Skip to content

Commit 0d468b1

Browse files
committed
Add support for prompts
1 parent 2c51fc3 commit 0d468b1

File tree

5 files changed

+742
-26
lines changed

5 files changed

+742
-26
lines changed

README.md

Lines changed: 210 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ https://github.com/user-attachments/assets/aa779b1c-a443-48d7-b3eb-13f27a4333b3
66

77
## Overview
88

9-
This extension provides a simplified, trait-based approach to exposing Jupyter functionality through the MCP protocol. It can dynamically load and register tools from various Python packages, making them available to AI assistants and other MCP clients.
9+
This extension provides a simplified, trait-based approach to exposing Jupyter functionality through the MCP protocol. It can dynamically load and register tools and prompts from various Python packages, making them available to AI assistants and other MCP clients.
1010

1111
## Key Features
1212

1313
- **Simplified Architecture**: Direct function registration without complex abstractions
14-
- **Configurable Tool Loading**: Register tools via string specifications (`module:function`)
15-
- **Automatic Tool Discovery**: Python packages can expose tools via entrypoints
14+
- **Configurable Tool & Prompt Loading**: Register tools and prompts via string specifications (`module:function`)
15+
- **Automatic Discovery**: Python packages can expose tools and prompts via entrypoints
1616
- **Jupyter Integration**: Seamless integration with Jupyter Server extension system
1717
- **HTTP Transport**: FastMCP-based HTTP server with proper MCP protocol support
1818
- **Traitlets Configuration**: Full configuration support through Jupyter's traitlets system
@@ -42,15 +42,21 @@ c.MCPExtensionApp.mcp_tools = [
4242
"os:getcwd",
4343
"json:dumps",
4444
"time:time",
45-
46-
# Jupyter AI Tools - Notebook operations
45+
46+
# Jupyter AI Tools - Notebook operations
4747
"jupyter_ai_tools.toolkits.notebook:read_notebook",
4848
"jupyter_ai_tools.toolkits.notebook:edit_cell",
49-
49+
5050
# JupyterLab Commands Toolkit
5151
"jupyterlab_commands_toolkit.tools:list_all_commands",
5252
"jupyterlab_commands_toolkit.tools:execute_command",
5353
]
54+
55+
# Register prompts for code assistance
56+
c.MCPExtensionApp.mcp_prompts = [
57+
"my_package.prompts:code_review_prompt",
58+
"my_package.prompts:documentation_prompt",
59+
]
5460
```
5561

5662
### 2. Start Jupyter Server
@@ -121,9 +127,12 @@ await server.start_server()
121127
```
122128

123129
**Key Methods:**
124-
- `register_tool(func, name=None, description=None)` - Register a Python function
130+
- `register_tool(func, name=None, description=None)` - Register a Python function as a tool
125131
- `register_tools(tools)` - Register multiple functions (list or dict)
126132
- `list_tools()` - Get list of registered tools
133+
- `register_prompt(func, name=None, description=None)` - Register a Python function as a prompt
134+
- `register_prompts(prompts)` - Register multiple prompt functions (list or dict)
135+
- `list_prompts()` - Get list of registered prompts
127136
- `start_server(host=None)` - Start the HTTP MCP server
128137

129138
#### MCPExtensionApp (`jupyter_server_mcp.extension.MCPExtensionApp`)
@@ -134,7 +143,8 @@ Jupyter Server extension that manages the MCP server lifecycle:
134143
- `mcp_name` - Server name (default: "Jupyter MCP Server")
135144
- `mcp_port` - Server port (default: 3001)
136145
- `mcp_tools` - List of tools to register (format: "module:function")
137-
- `use_tool_discovery` - Enable automatic tool discovery via entrypoints (default: True)
146+
- `mcp_prompts` - List of prompts to register (format: "module:function")
147+
- `use_tool_discovery` - Enable automatic discovery via entrypoints (default: True)
138148

139149
### Tool Registration
140150

@@ -185,6 +195,95 @@ Tools from entrypoints are discovered automatically when the extension starts. T
185195
c.MCPExtensionApp.use_tool_discovery = False
186196
```
187197

198+
### Prompt Registration
199+
200+
Prompts can be registered in two ways:
201+
202+
#### 1. Manual Configuration
203+
204+
Specify prompts directly in your Jupyter configuration using `module:function` format:
205+
206+
```python
207+
c.MCPExtensionApp.mcp_prompts = [
208+
"my_package.prompts:code_review_prompt",
209+
"my_package.prompts:documentation_prompt",
210+
]
211+
```
212+
213+
#### 2. Automatic Discovery via Entrypoints
214+
215+
Python packages can expose prompts automatically using the `jupyter_server_mcp.prompts` entrypoint group.
216+
217+
**In your package's `pyproject.toml`:**
218+
219+
```toml
220+
[project.entry-points."jupyter_server_mcp.prompts"]
221+
my_package_prompts = "my_package.prompts:PROMPTS"
222+
```
223+
224+
**In `my_package/prompts.py`:**
225+
226+
```python
227+
# Option 1: Define as a list
228+
PROMPTS = [
229+
"my_package.prompts:code_review_prompt",
230+
"my_package.prompts:documentation_prompt",
231+
"my_package.prompts:test_generation_prompt",
232+
]
233+
234+
# Option 2: Define as a function
235+
def get_prompts():
236+
return [
237+
"my_package.prompts:code_review_prompt",
238+
"my_package.prompts:documentation_prompt",
239+
]
240+
241+
# Example prompt functions
242+
def code_review_prompt(file_path: str, focus_area: str = "general") -> str:
243+
"""Generate a code review prompt for a specific file.
244+
245+
Args:
246+
file_path: Path to the file to review
247+
focus_area: Aspect to focus on (e.g., 'security', 'performance', 'general')
248+
249+
Returns:
250+
A formatted prompt for code review
251+
"""
252+
return f"""Please review the code in {file_path} with a focus on {focus_area}.
253+
254+
Provide feedback on:
255+
- Code quality and best practices
256+
- Potential bugs or issues
257+
- Performance considerations
258+
- Security concerns
259+
- Documentation and readability
260+
"""
261+
262+
def documentation_prompt(module_name: str, target_audience: str = "developers") -> str:
263+
"""Generate a documentation prompt for a module.
264+
265+
Args:
266+
module_name: Name of the module to document
267+
target_audience: Who will read this (e.g., 'developers', 'users', 'contributors')
268+
269+
Returns:
270+
A formatted prompt for documentation generation
271+
"""
272+
return f"""Create comprehensive documentation for the {module_name} module.
273+
274+
Target audience: {target_audience}
275+
276+
Include:
277+
- Overview and purpose
278+
- Key features and capabilities
279+
- Usage examples with code
280+
- API reference
281+
- Common patterns and best practices
282+
"""
283+
```
284+
285+
Prompts from entrypoints are discovered automatically when the extension starts, using the same `use_tool_discovery` setting as tools.
286+
188287
## Configuration Examples
189288

190289
### Minimal Setup
@@ -203,36 +302,50 @@ c.MCPExtensionApp.mcp_port = 8080
203302
c.MCPExtensionApp.mcp_tools = [
204303
# File system operations (jupyter-ai-tools)
205304
"jupyter_ai_tools.toolkits.file_system:read",
206-
"jupyter_ai_tools.toolkits.file_system:write",
305+
"jupyter_ai_tools.toolkits.file_system:write",
207306
"jupyter_ai_tools.toolkits.file_system:edit",
208307
"jupyter_ai_tools.toolkits.file_system:ls",
209308
"jupyter_ai_tools.toolkits.file_system:glob",
210-
309+
211310
# Notebook operations (jupyter-ai-tools)
212311
"jupyter_ai_tools.toolkits.notebook:read_notebook",
213312
"jupyter_ai_tools.toolkits.notebook:edit_cell",
214-
"jupyter_ai_tools.toolkits.notebook:add_cell",
313+
"jupyter_ai_tools.toolkits.notebook:add_cell",
215314
"jupyter_ai_tools.toolkits.notebook:delete_cell",
216315
"jupyter_ai_tools.toolkits.notebook:create_notebook",
217-
316+
218317
# Git operations (jupyter-ai-tools)
219318
"jupyter_ai_tools.toolkits.git:git_status",
220319
"jupyter_ai_tools.toolkits.git:git_add",
221320
"jupyter_ai_tools.toolkits.git:git_commit",
222321
"jupyter_ai_tools.toolkits.git:git_push",
223-
322+
224323
# JupyterLab operations (jupyterlab-commands-toolkit)
225324
"jupyterlab_commands_toolkit.tools:clear_all_outputs_in_notebook",
226325
"jupyterlab_commands_toolkit.tools:open_document",
227326
"jupyterlab_commands_toolkit.tools:open_markdown_file_in_preview_mode",
228327
"jupyterlab_commands_toolkit.tools:show_diff_of_current_notebook",
229-
230-
# Utility functions
328+
329+
# Utility functions
231330
"os:getcwd",
232331
"json:dumps",
233332
"time:time",
234333
"platform:system",
235334
]
335+
336+
c.MCPExtensionApp.mcp_prompts = [
337+
# Code analysis prompts
338+
"my_package.prompts:code_review_prompt",
339+
"my_package.prompts:refactoring_suggestions_prompt",
340+
341+
# Documentation prompts
342+
"my_package.prompts:documentation_prompt",
343+
"my_package.prompts:api_documentation_prompt",
344+
345+
# Testing prompts
346+
"my_package.prompts:test_generation_prompt",
347+
"my_package.prompts:test_coverage_analysis_prompt",
348+
]
236349
```
237350

238351
### Running Tests
@@ -258,17 +371,94 @@ jupyter_server_mcp/
258371
│ └── extension.py # Jupyter Server extension
259372
├── tests/
260373
│ ├── test_mcp_server.py # MCPServer tests
261-
│ └── test_extension.py # Extension tests
262-
├── demo/
263-
│ ├── jupyter_config.py # Example configuration
264-
│ └── *.py # Debug/diagnostic scripts
374+
│ └── test_extension.py # Extension tests
265375
└── pyproject.toml # Package configuration
266376
```
267377

378+
## Example: Creating a Package with Prompts
379+
380+
Here's how to create a package that exposes prompts via entrypoints:
381+
382+
**my_package/prompts.py:**
383+
```python
384+
"""Example prompt functions for code assistance."""
385+
386+
def code_review_prompt(file_path: str, focus_area: str = "general") -> str:
387+
"""Generate a code review prompt for a specific file.
388+
389+
Args:
390+
file_path: Path to the file to review
391+
focus_area: Aspect to focus on (e.g., 'security', 'performance', 'general')
392+
393+
Returns:
394+
A formatted prompt for code review
395+
"""
396+
return f"""Please review the code in {file_path} with a focus on {focus_area}.
397+
398+
Provide feedback on:
399+
- Code quality and best practices
400+
- Potential bugs or issues
401+
- Performance considerations
402+
- Security concerns
403+
- Documentation and readability
404+
"""
405+
406+
def documentation_prompt(module_name: str, target_audience: str = "developers") -> str:
407+
"""Generate a documentation prompt for a module."""
408+
return f"""Create comprehensive documentation for the {module_name} module.
409+
410+
Target audience: {target_audience}
411+
412+
Include:
413+
- Overview and purpose
414+
- Key features and capabilities
415+
- Usage examples with code
416+
- API reference
417+
- Common patterns and best practices
418+
"""
419+
420+
def test_generation_prompt(function_name: str, function_code: str) -> str:
421+
"""Generate a prompt for creating unit tests."""
422+
return f"""Generate comprehensive unit tests for the following function:
423+
424+
Function name: {function_name}
425+
426+
Code:
427+
```python
428+
{function_code}
429+
```
430+
431+
Please create:
432+
- Test cases for normal operation
433+
- Edge cases and boundary conditions
434+
- Error handling tests
435+
- Mocking examples if needed
436+
"""
437+
438+
# Define prompts list for entrypoint discovery
439+
PROMPTS = [
440+
"my_package.prompts:code_review_prompt",
441+
"my_package.prompts:documentation_prompt",
442+
"my_package.prompts:test_generation_prompt",
443+
]
444+
```
445+
446+
**pyproject.toml:**
447+
```toml
448+
[project]
449+
name = "my-package"
450+
version = "0.1.0"
451+
452+
[project.entry-points."jupyter_server_mcp.prompts"]
453+
my_package_prompts = "my_package.prompts:PROMPTS"
454+
```
455+
456+
After installing your package, the prompts will be automatically discovered and registered when the Jupyter Server MCP extension starts.
457+
268458
## Contributing
269459

270460
1. Fork the repository
271461
2. Create a feature branch
272-
3. Add tests for new functionality
462+
3. Add tests for new functionality
273463
4. Ensure all tests pass: `pytest tests/`
274464
5. Submit a pull request

0 commit comments

Comments
 (0)