{"kind":"AgentDefinition","metadata":{"namespace":"community","name":"python-mcp-server","version":"0.1.0"},"spec":{"agents_md":"---\ndescription: 'Instructions for building Model Context Protocol (MCP) servers using the Python SDK'\napplyTo: '**/*.py, **/pyproject.toml, **/requirements.txt'\n---\n\n# Python MCP Server Development\n\n## Instructions\n\n- Use **uv** for project management: `uv init mcp-server-demo` and `uv add \"mcp[cli]\"`\n- Import FastMCP from `mcp.server.fastmcp`: `from mcp.server.fastmcp import FastMCP`\n- Use `@mcp.tool()`, `@mcp.resource()`, and `@mcp.prompt()` decorators for registration\n- Type hints are mandatory - they're used for schema generation and validation\n- Use Pydantic models, TypedDicts, or dataclasses for structured output\n- Tools automatically return structured output when return types are compatible\n- For stdio transport, use `mcp.run()` or `mcp.run(transport=\"stdio\")`\n- For HTTP servers, use `mcp.run(transport=\"streamable-http\")` or mount to Starlette/FastAPI\n- Use `Context` parameter in tools/resources to access MCP capabilities: `ctx: Context`\n- Send logs with `await ctx.debug()`, `await ctx.info()`, `await ctx.warning()`, `await ctx.error()`\n- Report progress with `await ctx.report_progress(progress, total, message)`\n- Request user input with `await ctx.elicit(message, schema)`\n- Use LLM sampling with `await ctx.session.create_message(messages, max_tokens)`\n- Configure icons with `Icon(src=\"path\", mimeType=\"image/png\")` for server, tools, resources, prompts\n- Use `Image` class for automatic image handling: `return Image(data=bytes, format=\"png\")`\n- Define resource templates with URI patterns: `@mcp.resource(\"greeting://{name}\")`\n- Implement completion support by accepting partial values and returning suggestions\n- Use lifespan context managers for startup/shutdown with shared resources\n- Access lifespan context in tools via `ctx.request_context.lifespan_context`\n- For stateless HTTP servers, set `stateless_http=True` in FastMCP initialization\n- Enable JSON responses for modern clients: `json_response=True`\n- Test servers with: `uv run mcp dev server.py` (Inspector) or `uv run mcp install server.py` (Claude Desktop)\n- Mount multiple servers in Starlette with different paths: `Mount(\"/path\", mcp.streamable_http_app())`\n- Configure CORS for browser clients: expose `Mcp-Session-Id` header\n- Use low-level Server class for maximum control when FastMCP isn't sufficient\n\n## Best Practices\n\n- Always use type hints - they drive schema generation and validation\n- Return Pydantic models or TypedDicts for structured tool outputs\n- Keep tool functions focused on single responsibilities\n- Provide clear docstrings - they become tool descriptions\n- Use descriptive parameter names with type hints\n- Validate inputs using Pydantic Field descriptions\n- Implement proper error handling with try-except blocks\n- Use async functions for I/O-bound operations\n- Clean up resources in lifespan context managers\n- Log to stderr to avoid interfering with stdio transport (when using stdio)\n- Use environment variables for configuration\n- Test tools independently before LLM integration\n- Consider security when exposing file system or network access\n- Use structured output for machine-readable data\n- Provide both content and structured data for backward compatibility\n\n## Common Patterns\n\n### Basic Server Setup (stdio)\n```python\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"My Server\")\n\n@mcp.tool()\ndef calculate(a: int, b: int, op: str) -\u003e int:\n    \"\"\"Perform calculation\"\"\"\n    if op == \"add\":\n        return a + b\n    return a - b\n\nif __name__ == \"__main__\":\n    mcp.run()  # stdio by default\n```\n\n### HTTP Server\n```python\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"My HTTP Server\")\n\n@mcp.tool()\ndef hello(name: str = \"World\") -\u003e str:\n    \"\"\"Greet someone\"\"\"\n    return f\"Hello, {name}!\"\n\nif __name__ == \"__main__\":\n    mcp.run(transport=\"streamable-http\")\n```\n\n### Tool with Structured Output\n```python\nfrom pydantic import BaseModel, Field\n\nclass WeatherData(BaseModel):\n    temperature: float = Field(description=\"Temperature in Celsius\")\n    condition: str\n    humidity: float\n\n@mcp.tool()\ndef get_weather(city: str) -\u003e WeatherData:\n    \"\"\"Get weather for a city\"\"\"\n    return WeatherData(\n        temperature=22.5,\n        condition=\"sunny\",\n        humidity=65.0\n    )\n```\n\n### Dynamic Resource\n```python\n@mcp.resource(\"users://{user_id}\")\ndef get_user(user_id: str) -\u003e str:\n    \"\"\"Get user profile data\"\"\"\n    return f\"User {user_id} profile data\"\n```\n\n### Tool with Context\n```python\nfrom mcp.server.fastmcp import Context\nfrom mcp.server.session import ServerSession\n\n@mcp.tool()\nasync def process_data(\n    data: str, \n    ctx: Context[ServerSession, None]\n) -\u003e str:\n    \"\"\"Process data with logging\"\"\"\n    await ctx.info(f\"Processing: {data}\")\n    await ctx.report_progress(0.5, 1.0, \"Halfway done\")\n    return f\"Processed: {data}\"\n```\n\n### Tool with Sampling\n```python\nfrom mcp.server.fastmcp import Context\nfrom mcp.server.session import ServerSession\nfrom mcp.types import SamplingMessage, TextContent\n\n@mcp.tool()\nasync def summarize(\n    text: str,\n    ctx: Context[ServerSession, None]\n) -\u003e str:\n    \"\"\"Summarize text using LLM\"\"\"\n    result = await ctx.session.create_message(\n        messages=[SamplingMessage(\n            role=\"user\",\n            content=TextContent(type=\"text\", text=f\"Summarize: {text}\")\n        )],\n        max_tokens=100\n    )\n    return result.content.text if result.content.type == \"text\" else \"\"\n```\n\n### Lifespan Management\n```python\nfrom contextlib import asynccontextmanager\nfrom dataclasses import dataclass\nfrom mcp.server.fastmcp import FastMCP, Context\n\n@dataclass\nclass AppContext:\n    db: Database\n\n@asynccontextmanager\nasync def app_lifespan(server: FastMCP):\n    db = await Database.connect()\n    try:\n        yield AppContext(db=db)\n    finally:\n        await db.disconnect()\n\nmcp = FastMCP(\"My App\", lifespan=app_lifespan)\n\n@mcp.tool()\ndef query(sql: str, ctx: Context) -\u003e str:\n    \"\"\"Query database\"\"\"\n    db = ctx.request_context.lifespan_context.db\n    return db.execute(sql)\n```\n\n### Prompt with Messages\n```python\nfrom mcp.server.fastmcp.prompts import base\n\n@mcp.prompt(title=\"Code Review\")\ndef review_code(code: str) -\u003e list[base.Message]:\n    \"\"\"Create code review prompt\"\"\"\n    return [\n        base.UserMessage(\"Review this code:\"),\n        base.UserMessage(code),\n        base.AssistantMessage(\"I'll review the code for you.\")\n    ]\n```\n\n### Error Handling\n```python\n@mcp.tool()\nasync def risky_operation(input: str) -\u003e str:\n    \"\"\"Operation that might fail\"\"\"\n    try:\n        result = await perform_operation(input)\n        return f\"Success: {result}\"\n    except Exception as e:\n        return f\"Error: {str(e)}\"\n```\n","description":"Instructions for building Model Context Protocol (MCP) servers using the Python SDK","import":{"commit_sha":"541b7819d8c3545c6df122491af4fa1eae415779","imported_at":"2026-05-18T20:05:35Z","license_text":"MIT License\n\nCopyright GitHub, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.","owner":"github","repo":"github/awesome-copilot","source_url":"https://github.com/github/awesome-copilot/blob/541b7819d8c3545c6df122491af4fa1eae415779/instructions/python-mcp-server.instructions.md"},"manifest":{}},"content_hash":[99,174,107,61,227,71,195,12,86,115,51,210,191,79,116,214,115,149,113,101,59,8,239,24,211,224,72,1,219,173,98,61],"trust_level":"unsigned","yanked":false}
