Build Your First MCP Server in Python (2026 Guide) The MCP Python and TypeScript SDKs surpassed 97 million monthly downloads in March 2026, a 4,750% increase in 16 months, with over 9,400 public servers catalogued. The 2026-07-28 MCP specification removed sessions and the initialize handshake, shifting to a stateless model, and FastMCP's latest release implements the new spec. Developers can build a custom MCP server in under 30 minutes using the official MCP Python SDK, which includes FastMCP, by defining tools with Python type hints and docstrings. MCP hit infrastructure status quietly. The Python and TypeScript SDKs crossed 97 million monthly downloads in March 2026 — a 4,750% climb in 16 months. Claude Desktop, Cursor, and VS Code all ship with first-class MCP support. There are over 9,400 public servers catalogued. And yet most developers have only ever been on the consuming end: installing servers other people built, running into the 30–50% installation failure rate that plagues community-authored packages. Building your own MCP server sidesteps all of that. It takes under 30 minutes with Python and FastMCP https://gofastmcp.com/getting-started/welcome , and it gives you something no pre-built server can: tools tuned exactly to your codebase, your APIs, and your workflow. Here is how to do it with the current spec. First: The Spec Changed. Most Tutorials Are Broken. The 2026-07-28 MCP specification removed sessions entirely. The Mcp-Session-Id header is gone. The initialize handshake is gone. If a tutorial you are reading still shows either of those, close the tab — it is teaching you patterns that will not work with any up-to-date client. Appwrite’s breakdown of the stateless migration https://appwrite.io/blog/post/mcp-goes-stateless-in-the-2026-07-28-specification covers the full impact if you need the details. The shift to stateless is the right call. The old session model required every follow-up request to reach the same server instance, which made load balancing nearly impossible for remote servers. Now an MCP server behaves like any other HTTP service: round-robin load balancing works, horizontal scaling works, and there is no sticky session complexity to manage. If your application needs to carry state across calls, you mint an explicit handle from a tool and pass it back as a plain argument — the same pattern HTTP APIs have used for decades. FastMCP’s latest release, built on the official MCP Python SDK https://github.com/modelcontextprotocol/python-sdk , already implements the new spec. Install it and you get the current behavior by default. Setup: Two Commands Install the official MCP Python SDK using uv: uv add mcp That single dependency includes FastMCP along with everything needed to run a server on stdio or HTTP transport. Create a file called server.py and add this: python from mcp.server.fastmcp import FastMCP mcp = FastMCP "my-server" if name == " main ": mcp.run This is a valid, runnable MCP server. It exposes nothing yet, but it will handshake correctly with any MCP client. Add your first tool next. Build a Real Tool Tools are the core primitive — they are what the LLM actually calls, the same way it calls functions in a standard function-calling API. The difference is the protocol layer: MCP routes the call to your server over stdio or HTTP, runs the function, and returns the result. FastMCP generates the JSON schema for your tool automatically from Python type hints and the docstring. Here is a practical example — a directory inspector that an AI agent can use to understand your project structure: python from mcp.server.fastmcp import FastMCP import os mcp = FastMCP "file-inspector" @mcp.tool def list directory path: str, max depth: int = 2 - str: """ List files and directories at the given path. Returns a tree-formatted string up to max depth levels deep. Use this to explore project structure before making changes. """ lines = for root, dirs, files in os.walk path : depth = root.replace path, "" .count os.sep if depth = max depth: dirs.clear continue indent = " " depth lines.append f"{indent}{os.path.basename root }/" for f in files: lines.append f"{indent} {f}" return "\n".join lines if name == " main ": mcp.run Two things matter here: the type hints on path and max depth are what FastMCP uses to generate the tool’s parameter schema, and the docstring is what the LLM reads to decide whether and how to call the tool. A vague docstring means the model will use the tool incorrectly. Write it as if you are documenting a function for a teammate who cannot ask follow-up questions. Connect to Claude Desktop or Cursor On macOS, open ~/Library/Application Support/Claude/claude desktop config.json . On Windows, it lives at %APPDATA%\Claude\claude desktop config.json . Add your server: { "mcpServers": { "file-inspector": { "command": "uv", "args": "run", "--directory", "/absolute/path/to/project", "python", "server.py" } } } For Cursor, the format is identical — the file lives at ~/.cursor/mcp.json instead. Restart the client after saving. Your tool will appear in the client’s tool list within seconds. Test it by asking the model to list your project’s directory structure. What to Build Next Stdio transport is the right starting point: no networking, no ports, no auth to manage. When you want a server your whole team can share, or one running on a remote machine, switch to HTTP with one line: if name == " main ": mcp.run transport="streamable-http", host="0.0.0.0", port=8000 The client config changes from command / args to a url field. The spec includes OAuth 2.1 for auth, so enterprise deployments have a standardized path. The official MCP Python SDK documentation https://py.sdk.modelcontextprotocol.io/ covers remote deployment and authentication in detail. The deeper opportunity is resources and prompts — the two primitives this post skips for brevity. Resources let you expose data sources database schemas, config files, API docs that the model reads without executing a tool call. Prompts package reusable instructions into named templates users invoke directly from any MCP client. Both use the same decorator pattern as tools. MCP’s growth curve is not driven by hype — it is the standardization layer that makes agent workflows composable across tools and providers. Build one server and you will immediately see why.