import anyio import click import mcp.types as types from mcp.server.lowlevel import Server from mcp.server.lowlevel.helper_types import ReadResourceContents from starlette.requests import Request SAMPLE_RESOURCES = { "greeting": { "content": "Hello! This is a sample text resource.", "title": "Welcome Message", }, "help": { "content": "This server provides a few sample text resources for testing.", "title": "Help Documentation", }, "about": { "content": "This is the simple-resource MCP server implementation.", "title": "About This Server", }, } @click.command() @click.option("--port", default=8000, help="Port to listen on for SSE") @click.option( "--transport", type=click.Choice(["stdio", "sse"]), default="stdio", help="Transport type", ) def main(port: int, transport: str) -> int: app = Server("mcp-simple-resource") @app.list_resources() async def list_resources() -> list[types.Resource]: return [ types.Resource( uri=f"file:///{name}.txt", name=name, title=SAMPLE_RESOURCES[name]["title"], description=f"A sample text resource named {name}", mime_type="text/plain", ) for name in SAMPLE_RESOURCES.keys() ] @app.read_resource() async def read_resource(uri: str): from urllib.parse import urlparse parsed = urlparse(uri) if not parsed.path: raise ValueError(f"Invalid resource path: {uri}") name = parsed.path.replace(".txt", "").lstrip("/") if name not in SAMPLE_RESOURCES: raise ValueError(f"Unknown resource: {uri}") return [ReadResourceContents(content=SAMPLE_RESOURCES[name]["content"], mime_type="text/plain")] if transport == "sse": from mcp.server.sse import SseServerTransport from starlette.applications import Starlette from starlette.responses import Response from starlette.routing import Mount, Route sse = SseServerTransport("/messages/") async def handle_sse(request: Request): async with sse.connect_sse(request.scope, request.receive, request._send) as streams: # type: ignore[reportPrivateUsage] await app.run(streams[0], streams[1], app.create_initialization_options()) return Response() starlette_app = Starlette( debug=True, routes=[ Route("/sse", endpoint=handle_sse, methods=["GET"]), Mount("/messages/", app=sse.handle_post_message), ], ) import uvicorn uvicorn.run(starlette_app, host="127.0.0.1", port=port) else: from mcp.server.stdio import stdio_server async def arun(): async with stdio_server() as streams: await app.run(streams[0], streams[1], app.create_initialization_options()) anyio.run(arun) return 0