Move template to flat app pattern

This commit is contained in:
David Soria Parra 2024-11-24 21:02:02 +00:00
commit 35730e4a16
No known key found for this signature in database
2 changed files with 127 additions and 152 deletions

View file

@ -6,30 +6,12 @@ from mcp.server import NotificationOptions, Server
from pydantic import AnyUrl
import mcp.server.stdio
class McpServer(Server):
"""
Example MCP server demonstrating the three core primitives:
1. Resources - Simple key-value notes storage accessed via custom URIs
2. Prompts - Configurable summarization prompt for notes
3. Tools - Ability to add new notes programmatically
This server shows how to:
- Implement resource listing and reading with custom URI schemes
- Create parameterized prompts that can access server state
- Define tools with JSON schema validation
- Send notifications when server state changes
"""
def __init__(self):
super().__init__("{{server_name}}")
# Store notes as a simple key-value dict to demonstrate state management
self.notes: dict[str, str] = {}
notes: dict[str, str] = {}
# RESOURCE HANDLERS
# Resources allow clients to discover and read content from the server
@self.list_resources()
server = Server("{{server_name}}")
@server.list_resources()
async def handle_list_resources() -> list[types.Resource]:
"""
List available note resources.
@ -37,15 +19,15 @@ class McpServer(Server):
"""
return [
types.Resource(
uri=AnyUrl(f"note:///{name}"),
uri=AnyUrl(f"note://internal/{name}"),
name=f"Note: {name}",
description=f"A simple note named {name}",
mimeType="text/plain",
)
for name in self.notes
for name in notes
]
@self.read_resource()
@server.read_resource()
async def handle_read_resource(uri: AnyUrl) -> str:
"""
Read a specific note's content by its URI.
@ -57,12 +39,10 @@ class McpServer(Server):
name = uri.path
if name is not None:
name = name.lstrip("/")
return self.notes[name]
return notes[name]
raise ValueError(f"Note not found: {name}")
# PROMPT HANDLERS
# Prompts define templates that can be filled with server state
@self.list_prompts()
@server.list_prompts()
async def handle_list_prompts() -> list[types.Prompt]:
"""
List available prompts.
@ -82,7 +62,7 @@ class McpServer(Server):
)
]
@self.get_prompt()
@server.get_prompt()
async def handle_get_prompt(
name: str, arguments: dict[str, str] | None
) -> types.GetPromptResult:
@ -106,16 +86,14 @@ class McpServer(Server):
text=f"Here are the current notes to summarize:{detail_prompt}\n\n"
+ "\n".join(
f"- {name}: {content}"
for name, content in self.notes.items()
for name, content in notes.items()
),
),
)
],
)
# TOOL HANDLERS
# Tools allow clients to modify server state in controlled ways
@self.list_tools()
@server.list_tools()
async def handle_list_tools() -> list[types.Tool]:
"""
List available tools.
@ -136,7 +114,7 @@ class McpServer(Server):
)
]
@self.call_tool()
@server.call_tool()
async def handle_call_tool(
name: str, arguments: dict | None
) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
@ -157,10 +135,10 @@ class McpServer(Server):
raise ValueError("Missing name or content")
# Update server state
self.notes[note_name] = content
notes[note_name] = content
# Notify clients that resources have changed
await self.request_context.session.send_resource_list_changed()
await server.request_context.session.send_resource_list_changed()
return [
types.TextContent(
@ -169,10 +147,7 @@ class McpServer(Server):
)
]
async def main():
server = McpServer()
# Run the server using stdin/stdout streams
async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
await server.run(

2
uv.lock generated
View file

@ -24,7 +24,7 @@ wheels = [
[[package]]
name = "create-mcp-server"
version = "1.0.3.dev0"
version = "1.0.4.dev0"
source = { editable = "." }
dependencies = [
{ name = "click" },