diff --git a/src/create_mcp_server/template/README.md.jinja2 b/src/create_mcp_server/template/README.md.jinja2 index c35655d..54bba02 100644 --- a/src/create_mcp_server/template/README.md.jinja2 +++ b/src/create_mcp_server/template/README.md.jinja2 @@ -6,23 +6,15 @@ ### Resources -The server implements a simple note storage system with: -- Custom note:// URI scheme for accessing individual notes -- Each note resource has a name, description and text/plain mimetype +Implement the `handle_list_resources()` and `handle_read_resource()` methods to expose and read resources. ### Prompts -The server provides a single prompt: -- summarize-notes: Creates summaries of all stored notes - - Optional "style" argument to control detail level (brief/detailed) - - Generates prompt combining all current notes with style preference +Implement the `handle_list_prompts()` and `handle_get_prompt()` methods to expose and generate prompts. ### Tools -The server implements one tool: -- add-note: Adds a new note to the server - - Takes "name" and "content" as required string arguments - - Updates server state and notifies clients of resource changes +Implement the `handle_list_tools()` and `handle_call_tool()` methods to expose and execute tools. ## Configuration diff --git a/src/create_mcp_server/template/server.py.jinja2 b/src/create_mcp_server/template/server.py.jinja2 index bc39f5c..be85bfc 100644 --- a/src/create_mcp_server/template/server.py.jinja2 +++ b/src/create_mcp_server/template/server.py.jinja2 @@ -6,61 +6,31 @@ from mcp.server import NotificationOptions, Server from pydantic import AnyUrl import mcp.server.stdio -# Store notes as a simple key-value dict to demonstrate state management -notes: dict[str, str] = {} - server = Server("{{server_name}}") @server.list_resources() async def handle_list_resources() -> list[types.Resource]: """ - List available note resources. - Each note is exposed as a resource with a custom note:// URI scheme. + List available resources. + Implement this method to expose your server's resources. """ - return [ - types.Resource( - uri=AnyUrl(f"note://internal/{name}"), - name=f"Note: {name}", - description=f"A simple note named {name}", - mimeType="text/plain", - ) - for name in notes - ] + return [] @server.read_resource() async def handle_read_resource(uri: AnyUrl) -> str: """ - Read a specific note's content by its URI. - The note name is extracted from the URI host component. + Read a specific resource's content by its URI. + Implement this method to return the content of a resource. """ - if uri.scheme != "note": - raise ValueError(f"Unsupported URI scheme: {uri.scheme}") - - name = uri.path - if name is not None: - name = name.lstrip("/") - return notes[name] - raise ValueError(f"Note not found: {name}") + raise NotImplementedError("Resource reading not implemented") @server.list_prompts() async def handle_list_prompts() -> list[types.Prompt]: """ List available prompts. - Each prompt can have optional arguments to customize its behavior. + Implement this method to expose your server's prompts. """ - return [ - types.Prompt( - name="summarize-notes", - description="Creates a summary of all notes", - arguments=[ - types.PromptArgument( - name="style", - description="Style of the summary (brief/detailed)", - required=False, - ) - ], - ) - ] + return [] @server.get_prompt() async def handle_get_prompt( @@ -68,51 +38,17 @@ async def handle_get_prompt( ) -> types.GetPromptResult: """ Generate a prompt by combining arguments with server state. - The prompt includes all current notes and can be customized via arguments. + Implement this method to generate prompts based on the given name and arguments. """ - if name != "summarize-notes": - raise ValueError(f"Unknown prompt: {name}") - - style = (arguments or {}).get("style", "brief") - detail_prompt = " Give extensive details." if style == "detailed" else "" - - return types.GetPromptResult( - description="Summarize the current notes", - messages=[ - types.PromptMessage( - role="user", - content=types.TextContent( - type="text", - text=f"Here are the current notes to summarize:{detail_prompt}\n\n" - + "\n".join( - f"- {name}: {content}" - for name, content in notes.items() - ), - ), - ) - ], - ) + raise NotImplementedError("Prompt generation not implemented") @server.list_tools() async def handle_list_tools() -> list[types.Tool]: """ List available tools. - Each tool specifies its arguments using JSON Schema validation. + Implement this method to expose your server's tools. """ - return [ - types.Tool( - name="add-note", - description="Add a new note", - inputSchema={ - "type": "object", - "properties": { - "name": {"type": "string"}, - "content": {"type": "string"}, - }, - "required": ["name", "content"], - }, - ) - ] + return [] @server.call_tool() async def handle_call_tool( @@ -120,35 +56,11 @@ async def handle_call_tool( ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: """ Handle tool execution requests. - Tools can modify server state and notify clients of changes. + Implement this method to handle tool calls with the given name and arguments. """ - if name != "add-note": - raise ValueError(f"Unknown tool: {name}") - - if not arguments: - raise ValueError("Missing arguments") - - note_name = arguments.get("name") - content = arguments.get("content") - - if not note_name or not content: - raise ValueError("Missing name or content") - - # Update server state - notes[note_name] = content - - # Notify clients that resources have changed - await server.request_context.session.send_resource_list_changed() - - return [ - types.TextContent( - type="text", - text=f"Added note '{note_name}' with content: {content}", - ) - ] + raise NotImplementedError("Tool execution not implemented") async def main(): - # Run the server using stdin/stdout streams async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream,