MCPcopy
hub / github.com/modelcontextprotocol/python-sdk

github.com/modelcontextprotocol/python-sdk @v2.0.0a3 sqlite

repository ↗ · DeepWiki ↗ · release v2.0.0a3 ↗
4,796 symbols 25,398 edges 396 files 3,086 documented · 64%
README

MCP Python SDK

Python implementation of the Model Context Protocol (MCP)

PyPI MIT licensed Python Version Documentation Protocol Specification

Important: this documents v2 of the SDK, which is in alpha. Pre-releases are published to PyPI as 2.0.0aN, and each alpha may contain breaking changes from the previous one.

v2 is a major rework of the SDK, both to support the 2026-07-28 MCP specification release and to fix long-standing architectural issues. See the migration guide for what's changed. We're targeting a beta on 2026-06-30 and a stable v2 on 2026-07-27, alongside the spec release. Before stable, we plan to add a significant set of backwards compatibility shims so the final upgrade is much smaller than today's diff.

v1.x is the only stable release line and remains recommended for production. It is in maintenance mode and continues to receive critical bug fixes and security patches. Installers never select a pre-release unless you opt in (for example pip install mcp==2.0.0aN), so existing installs are unaffected. If your package depends on mcp, add a <2 upper bound to your version constraint (for example mcp>=1.27,<2) before the stable release lands.

Try the alpha and tell us what breaks: #python-sdk-dev on the MCP Contributors Discord. For v1 documentation, see the v1.x README.

Table of Contents

Overview

The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This Python SDK implements the full MCP specification, making it easy to:

  • Build MCP clients that can connect to any MCP server
  • Create MCP servers that expose resources, prompts and tools
  • Use standard transports like stdio, SSE, and Streamable HTTP
  • Handle all MCP protocol messages and lifecycle events

Installation

Adding MCP to your python project

We recommend using uv to manage your Python projects.

If you haven't created a uv-managed project yet, create one:

bash uv init mcp-server-demo cd mcp-server-demo

Then add MCP to your project dependencies:

bash uv add "mcp[cli]==2.0.0a1"

Alternatively, for projects using pip for dependencies:

pip install "mcp[cli]==2.0.0a1"

While v2 is in pre-release, you must pin the version explicitly: unpinned installs resolve to the latest stable v1.x release, which these docs do not describe. Check the release history for the newest pre-release. The same applies to ad-hoc commands: use uv run --with "mcp==2.0.0a1" rather than uv run --with mcp.

Running the standalone MCP development tools

To run the mcp command with uv:

uv run mcp

Quickstart

Let's create a simple MCP server that exposes a calculator tool and some data:

"""MCPServer quickstart example.

Run from the repository root:
    uv run examples/snippets/servers/mcpserver_quickstart.py
"""

from mcp.server.mcpserver import MCPServer

# Create an MCP server
mcp = MCPServer("Demo")


# Add an addition tool
@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b


# Add a dynamic greeting resource
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """Get a personalized greeting"""
    return f"Hello, {name}!"


# Add a prompt
@mcp.prompt()
def greet_user(name: str, style: str = "friendly") -> str:
    """Generate a greeting prompt"""
    styles = {
        "friendly": "Please write a warm, friendly greeting",
        "formal": "Please write a formal, professional greeting",
        "casual": "Please write a casual, relaxed greeting",
    }

    return f"{styles.get(style, styles['friendly'])} for someone named {name}."


# Run with streamable HTTP transport
if __name__ == "__main__":
    mcp.run(transport="streamable-http", json_response=True)

Full example: examples/snippets/servers/mcpserver_quickstart.py

You can install this server in Claude Code and interact with it right away. First, run the server:

uv run --with "mcp==2.0.0a1" examples/snippets/servers/mcpserver_quickstart.py

Then add it to Claude Code:

claude mcp add --transport http my-server http://localhost:8000/mcp

Alternatively, you can test it with the MCP Inspector. Start the server as above, then in a separate terminal:

npx -y @modelcontextprotocol/inspector

In the inspector UI, connect to http://localhost:8000/mcp.

What is MCP?

The Model Context Protocol (MCP) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions.

MCP follows a client-server model, where LLM applications act as clients and connect to MCP servers to access capabilities such as data retrieval and tool execution in a consistent format.

MCP servers can:

  • Expose data through Resources (think of these sort of like GET endpoints; they are used to load information into the LLM's context)
  • Provide functionality through Tools (sort of like POST endpoints; they are used to execute code or otherwise produce a side effect)
  • Define interaction patterns through Prompts (reusable templates for LLM interactions)
  • And more!

Core Concepts

Server

The MCPServer server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:

"""Example showing lifespan support for startup/shutdown with strong typing."""

from collections.abc import AsyncIterator
from contextlib import asynccontextmanager
from dataclasses import dataclass

from mcp.server.mcpserver import Context, MCPServer


# Mock database class for example
class Database:
    """Mock database class for example."""

    @classmethod
    async def connect(cls) -> "Database":
        """Connect to database."""
        return cls()

    async def disconnect(self) -> None:
        """Disconnect from database."""
        pass

    def query(self) -> str:
        """Execute a query."""
        return "Query result"


@dataclass
class AppContext:
    """Application context with typed dependencies."""

    db: Database


@asynccontextmanager
async def app_lifespan(server: MCPServer) -> AsyncIterator[AppContext]:
    """Manage application lifecycle with type-safe context."""
    # Initialize on startup
    db = await Database.connect()
    try:
        yield AppContext(db=db)
    finally:
        # Cleanup on shutdown
        await db.disconnect()


# Pass lifespan to server
mcp = MCPServer("My App", lifespan=app_lifespan)


# Access type-safe lifespan context in tools
@mcp.tool()
def query_db(ctx: Context[AppContext]) -> str:
    """Tool that uses initialized resources."""
    db = ctx.request_context.lifespan_context.db
    return db.query()

Full example: examples/snippets/servers/lifespan_example.py

Resources

Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects:

from mcp.server.mcpserver import MCPServer

mcp = MCPServer(name="Resource Example")


@mcp.resource("file://documents/{name}")
def read_document(name: str) -> str:
    """Read a document by name."""
    # This would normally read from disk
    return f"Content of {name}"


@mcp.resource("config://settings")
def get_settings() -> str:
    """Get application settings."""
    return """{
  "theme": "dark",
  "language": "en",
  "debug": false
}"""

Full example: examples/snippets/servers/basic_resource.py

Tools

Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects:

from mcp.server.mcpserver import MCPServer

mcp = MCPServer(name="Tool Example")


@mcp.tool()
def sum(a: int, b: int) -> int:
    """Add two numbers together."""
    return a + b


@mcp.tool()
def get_weather(city: str, unit: str = "celsius") -> str:
    """Get weather for a city."""
    # This would normally call a weather API
    return f"Weather in {city}: 22degrees{unit[0].upper()}"

Full example: examples/snippets/servers/basic_tool.py

Tools can optionally receive a Context object by including a parameter with the Context type annotation. This context is automatically injected by the MCPServer framework and provides access to MCP capabilities:

```python from mcp.server.mcpserver import Context, MCPServer

mcp = MCPServer(name="Progress Example")

@mcp.tool() async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str: """Execute a task with progress updates.""" await ctx.info(f"Starting: {task_name}") # pyright: ignore[reportDeprecated]

for i in range(steps):
    progress = (i + 1) / steps
    await ctx.report_progress(
        progress=progress,
        total=1.0,
        message=f"Step {i + 1}/{steps}",
    )
    await ctx.debug(f"Completed step {i + 1}")

Core symbols most depended-on inside this repo

call_tool
called by 228
src/mcp/client/client.py
wait
called by 159
src/mcp/os/win32/utilities.py
list_tools
called by 101
src/mcp/client/client.py
debug
called by 90
src/mcp/server/mcpserver/context.py
start
called by 71
examples/clients/simple-chatbot/mcp_simple_chatbot/main.py
info
called by 70
src/mcp/server/mcpserver/context.py
run
called by 66
src/mcp/shared/dispatcher.py
streamable_http_client
called by 65
src/mcp/client/streamable_http.py

Shape

Function 2,575
Method 1,288
Class 897
Route 36

Languages

Python100%

Modules by API surface

src/mcp-types/mcp_types/v2025_11_25/__init__.py175 symbols
src/mcp-types/mcp_types/v2026_07_28/__init__.py172 symbols
src/mcp-types/mcp_types/_types.py157 symbols
tests/server/mcpserver/test_server.py149 symbols
tests/client/test_auth.py143 symbols
tests/shared/test_jsonrpc_dispatcher.py120 symbols
tests/server/test_runner.py116 symbols
tests/server/mcpserver/test_tool_manager.py116 symbols
tests/server/mcpserver/test_func_metadata.py106 symbols
tests/shared/test_streamable_http.py92 symbols
tests/client/test_session.py85 symbols
tests/client/test_stdio.py78 symbols

Dependencies from manifests, versioned

anyio4.5 · 1×
click8.2.0 · 1×
dunamai1.26.1 · 1×
hatchling1.29.0 · 1×
httpx0.27 · 1×
jinja23.1.6 · 1×
markupsafe3.0.3 · 1×
mcp1.0.0 · 1×
packaging26.1 · 1×
pathspec1.0.4 · 1×
pluggy1.6.0 · 1×
pydantic2.12.0 · 1×

Datastores touched

memory_dbDatabase · 1 repos
postgresDatabase · 1 repos

For agents

$ claude mcp add python-sdk \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact