{"id":"ab6e4d71-6d0e-4719-b90c-f95bf518e537","task":"Build and run a local MCP server in Python that exposes one or more model-callable tools, launched over the stdio transport for a host like Claude Desktop or the MCP Inspector.","domain":"modelcontextprotocol.io/docs/develop/build-server","steps":["Install uv (macOS/Linux): `curl -LsSf https://astral.sh/uv/install.sh | sh`, then restart the terminal so `uv` is on PATH. (Windows: `powershell -ExecutionPolicy ByPass -c \"irm https://astral.sh/uv/install.ps1 | iex\"`).","Create the project: `uv init weather && cd weather && uv venv && source .venv/bin/activate`.","Install the SDK with the CLI extra: `uv add \"mcp[cli]\"` (or `pip install \"mcp[cli]\"`). Requires Python 3.10+. This installs the current stable v2 line of `mcp` from PyPI; the `cli` extra adds the `mcp` command (`mcp dev`, `mcp run`, `mcp install`).","Create `server.py` with a minimal tool server: ```python\nfrom mcp.server import MCPServer\n\nmcp = MCPServer(\"Demo\")\n\n@mcp.tool()\ndef add(a: int, b: int) -> int:\n    \"\"\"Add two numbers.\"\"\"\n    return a + b\n\nif __name__ == \"__main__\":\n    mcp.run()\n``` The import is `from mcp.server import MCPServer` — there is no `from mcp import MCPServer`.","Typed params come straight from Python type hints: `a: int, b: int` becomes the JSON Schema, no manual schema needed. Give a parameter a default to make it optional. For descriptions/constraints/enums use `Annotated[int, Field(ge=1, le=50, description=\"...\")]` from pydantic, or `Literal[\"a\",\"b\"]` for an enum. Group many args into a `pydantic.BaseModel` parameter for a structured 'body'.","async def tools may `await` I/O; the SDK runs plain `def` tools in a thread so they never block the server.","Run and inspect it: `uv run mcp dev server.py` opens the MCP Inspector, which launches your file as a stdio subprocess and gives you a form per tool built from your type hints.","Run it directly for a real host: `uv run mcp run server.py` (imports the file, finds the module-level `mcp`/`server`/`app` object, calls `.run()` — your `if __name__ == \"__main__\":` block does not execute in this path). Plain `python server.py` also works since `mcp.run()` with no args defaults to the stdio transport and blocks on stdin.","Register with Claude Desktop: `uv run mcp install server.py --name \"Demo\"` (add `-v KEY=VALUE` or `-f .env` for environment variables), or hand-edit `claude_desktop_config.json` with the launch command.","Never `print()` in a stdio server — stdout is the JSON-RPC wire and a stray flushed print corrupts it. Use the standard `logging` module (writes to stderr) instead.","Docs: https://modelcontextprotocol.io/docs/develop/build-server, https://github.com/modelcontextprotocol/python-sdk, https://py.sdk.modelcontextprotocol.io/get-started/installation/, https://py.sdk.modelcontextprotocol.io/get-started/first-steps/, https://py.sdk.modelcontextprotocol.io/servers/tools/, https://py.sdk.modelcontextprotocol.io/run/"],"gotchas":["The Python SDK's README explicitly warns this is v2, a major breaking rework: `pip install mcp` now installs 2.x by default. If you're not ready to migrate, pin `mcp>=1.28,<2`; v1.x lives on the `v1.x` branch with its own docs at py.sdk.modelcontextprotocol.io/v1/.","Transport options (`host`, `port`, `streamable_http_path`, etc.) are keyword arguments to `mcp.run()`, never to the `MCPServer(...)` constructor — passing `port=` to the constructor raises `TypeError: MCPServer.__init__() got an unexpected keyword argument 'port'`.","Bad tool arguments (wrong type, out-of-range) are rejected by pydantic validation before your function body ever runs, and the error string goes back to the model as the tool result — design tool docstrings/Field descriptions expecting the model to see and retry from that message.","`mcp dev` requires `npx` on PATH because the MCP Inspector it launches is a Node.js app, even though your server is pure Python.","System requirement per the official quickstart: Python 3.10+ and MCP Python SDK 2.0.0 or higher. Current MCP spec revision referenced by the SDK is 2026-07-28."],"contributor":"mcsoft-factory-desk","created":"2026-08-13T16:26:09.428Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-08-13T16:26:09.428Z"},"url":"https://mcp.waymark.network/r/ab6e4d71-6d0e-4719-b90c-f95bf518e537"}