Who this is for and what you will build
This guide is for developers who already write Python and want to expose their own tools and data to LLM applications through the Model Context Protocol (MCP). By the end you will have installed the official SDK, written a server with one tool and one resource, opened it in the MCP Inspector, run it over HTTP, and called it from a small client.
What the SDK is
MCP is a protocol for exposing data and functionality to LLM applications in a standard way. The MCP Python SDK is its Python implementation[1]. It lets you build two kinds of program. A server exposes tools, resources and prompts to any MCP host, and a client connects to any MCP server[1]. The SDK supports the stdio, Streamable HTTP and SSE transports[1].
Instead of handling the protocol layer yourself, you mostly write ordinary, type-hinted Python functions. The SDK takes care of request parsing, validation and protocol details[1]. That is why a first working server fits in about fifteen lines.
Requirements
- Python 3.11 or newer[1].
- The SDK is released under the MIT License[1].
- You can install it with
uvor withpip[1].
Install
Install the SDK with the cli extra, using uv add "mcp[cli]" or pip install "mcp[cli]"[1]. The extra adds the mcp command-line tool, which provides mcp dev, mcp run and mcp install. If you do not need the command-line tool, install plain mcp instead[1]. For one-off commands without a project, uv run --with "mcp[cli]" mcp ... works without creating one[1].
Write the first server
Create a file called server.py with the following code[1]:
from mcp.server import MCPServer
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"MCPServer("Demo") creates the server object[1]. The @mcp.tool() decorator registers add as a tool. Its type hints, a: int, b: int, serve as the schema, so you do not write JSON Schema by hand[1]. The @mcp.resource("greeting://{name}") decorator registers greeting as a resource under a URI template, where {name} is filled in by the caller[1]. In this example the developer does not write request parsing, validation code or protocol handling[1].
The two decorators follow the same pattern: the Python function holds the logic, and the decorator tells the server what kind of item it is. A tool is something a client asks the server to run with arguments. A resource is addressed by a URI and returns content[1]. The SDK also lets a server expose prompts, but this example does not use them[1].
Test it in the MCP Inspector
Open the server in the MCP Inspector with uv run mcp dev server.py[1]. Calling add with a=1 and b=2 returns 3[1].
Run it over HTTP
To serve the server over Streamable HTTP, run uv run mcp run server.py --transport streamable-http[1]. This is the transport the SDK's README describes for deployment[1]. Stdio is the other transport: a local server can run as a stdio subprocess, which the client starts for you[1].
Call it from a client
With the server running, write a client in a separate file:
import asyncio
from mcp import Client
async def main() -> None:
async with Client("http://localhost:8000/mcp") as client:
result = await client.call_tool("add", {"a": 1, "b": 2})
print(result.structured_content) # {'result': 3}
asyncio.run(main())A Client created with a URL uses Streamable HTTP[1]. The code's comment shows that the printed result.structured_content is {'result': 3}[1]. A Client can also launch a local server as a stdio subprocess, or take a custom transport[1].
Limits and common questions
Do I need the cli extra? Only for the mcp command-line tool. If you use the library without those commands, plain mcp is enough[1].
What is the port in the example? The client connects to http://localhost:8000/mcp[1]. Replace it with the address your server actually listens on.
- The code here comes from the SDK's README. The editorial team has not run it ourselves, so check the official documentation before relying on it[2].
- The example has one tool and one resource. A real service needs its own parameters, return values and error handling.
- Start the server first, and keep it running at the address in the client's URL. The client example only works while the server listens at
http://localhost:8000/mcp[1]. - The SDK requires Python 3.11 or newer[1].
Next steps
The official documentation has a Get started guide, a "What's new in v2" page, an API reference and a migration guide[2]. Work through Get started first, then use the API reference to look up the decorators and classes you need[2].
Adapted from the README and official documentation of the MCP Python SDK[1][2], released under the MIT License.
Sources
- 1MCP Python SDK (README)MCP Python SDK (MIT)
- 2MCP Python SDK documentationMCP Python SDK (MIT)
Cite this page: Writing an MCP server with the official Python SDK. TellWorld, https://www.tellworld.net/practice/practice-mcp-python-sdk. Updated 2026-11-14