# https://github.com/modelcontextprotocol/python-sdk 项目说明书

生成时间：2026-05-15 12:58:02 UTC

## 目录

- [Getting Started with MCP Python SDK](#getting-started)
- [Project Structure](#project-structure)
- [FastMCP Server Development](#fastmcp-server)
- [Low-Level Server Development](#low-level-server)
- [Server Lifecycle and Context Management](#server-lifecycle)
- [Resources](#resources)
- [Tools and Structured Output](#tools-structured-output)
- [Prompts and Templates](#prompts)
- [Context and Session Management](#context-session)
- [Transports Overview](#transports)

<a id='getting-started'></a>

## Getting Started with MCP Python SDK

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Project Structure](#project-structure)

<details>
<summary>Related Source Files</summary>

The following source files were used to generate this documentation:

- [pyproject.toml](https://github.com/modelcontextprotocol/python-sdk/blob/main/pyproject.toml)
- [CONTRIBUTING.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/CONTRIBUTING.md)
- [examples/snippets/servers/fastmcp_quickstart.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/fastmcp_quickstart.py)
- [examples/servers/simple-prompt/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-prompt/server.py)
- [examples/servers/simple-pagination/mcp_simple_pagination/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-pagination/mcp_simple_pagination/server.py)
- [examples/clients/simple-auth-client/README.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-auth-client/README.md)
- [examples/mcpserver/icons_demo.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/mcpserver/icons_demo.py)
- [src/mcp/server/mcpserver/resources/base.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/base.py)
- [src/mcp/server/mcpserver/resources/types.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/types.py)
</details>

# Getting Started with MCP Python SDK

## Overview

The Model Context Protocol (MCP) Python SDK provides a comprehensive framework for building servers and clients that implement the MCP specification. MCP enables AI models to interact with external tools, resources, and prompts through a standardized protocol.

This guide walks you through setting up your development environment, understanding core concepts, and building your first MCP server.

## Prerequisites

Before getting started, ensure you have the following installed:

| Requirement | Version | Description |
|-------------|---------|-------------|
| Python | 3.10+ | The Python interpreter |
| uv | Latest | Package manager (required, not pip) |
| Git | Any | For cloning repositories |

资料来源：[CONTRIBUTING.md:3]()

## Installation

### Installing uv

If you don't have `uv` installed, follow the official installation guide:

```bash
# On Unix/macOS
curl -LsSf https://astral.sh/uv/install.sh | sh

# Or via pip
pip install uv
```

### Setting Up the Project

1. **Fork and clone the repository:**

```bash
git clone https://github.com/YOUR-USERNAME/python-sdk.git
cd python-sdk
```

2. **Install dependencies with all extras and dev tools:**

```bash
uv sync --frozen --all-extras --dev
```

The `--frozen` flag ensures `uv.lock` is respected, preventing unintended dependency changes.

3. **Set up pre-commit hooks:**

```bash
uv tool install pre-commit --with pre-commit-uv --force-reinstall
pre-commit install
```

资料来源：[CONTRIBUTING.md:5-16]()

## Core Concepts

Understanding MCP requires familiarity with three fundamental building blocks:

### Server Architecture

MCP servers expose capabilities through three primary interfaces:

```mermaid
graph TD
    A[MCP Server] --> B[Tools]
    A --> C[Resources]
    A --> D[Prompts]
    
    B --> B1[Executable Functions]
    C --> C1[Readable Data]
    D --> D1[Templated Messages]
```

| Component | Purpose | Usage |
|-----------|---------|-------|
| **Tools** | Executable functions that AI can call | `add_tool()` decorator |
| **Resources** | Read-only data accessible to AI | `add_resource()` method |
| **Prompts** | Pre-defined message templates | `add_prompt()` method |

资料来源：[src/mcp/server/mcpserver/server.py:1-50]()

### Tools

Tools are async functions that AI models can invoke. They support:

- **Icons**: Visual indicators for tool representation
- **Annotations**: Metadata about tool behavior (destructive, idempotent, etc.)
- **Typed parameters**: Automatic validation via Pydantic

```python
from mcp.server import Server
from mcp.types import Icon

app = Server("my-server")

@app.tool(
    title="Get Weather",
    description="Get current weather for a location",
    icons=[
        Icon(src="data:image/png;base64,...", mime_type="image/png", sizes=["16x16", "32x32"])
    ]
)
async def get_weather(location: str, units: str = "celsius") -> str:
    """Fetch weather data for the given location."""
    return f"Weather in {location}: 22°C"
```

资料来源：[examples/mcpserver/icons_demo.py:1-30]()

### Resources

Resources provide read-only data access. They follow a URI-based naming convention:

```mermaid
classDiagram
    class Resource {
        +str uri
        +str name
        +str mime_type
        +read() str | bytes
    }
    
    class FileResource {
        +Path path
        +bool is_binary
    }
    
    class FunctionResource {
        +Callable fn
    }
    
    Resource <|-- FileResource
    Resource <|-- FunctionResource
```

| Resource Type | Description | Use Case |
|---------------|-------------|-----------|
| `FileResource` | Reads from filesystem | Static data files |
| `FunctionResource` | Calls a function | Dynamic data generation |

资料来源：[src/mcp/server/mcpserver/resources/types.py:1-80]()
资料来源：[src/mcp/server/mcpserver/resources/base.py:1-40]()

### Prompts

Prompts are pre-defined message templates that can accept arguments:

```python
from mcp import types

prompts = [
    types.Prompt(
        name="simple",
        description="A simple prompt with context and topic",
        arguments=[
            types.PromptArgument(
                name="context",
                description="Additional context to consider",
                required=False,
            ),
            types.PromptArgument(
                name="topic",
                description="Specific topic to focus on",
                required=True,
            ),
        ],
    )
]
```

## Quick Start Guide

### Creating Your First Server

The fastest way to create an MCP server is using the `@mcp.tool()` decorator:

```python
# server.py
from mcp.server import Server

app = Server("my-first-server")

@app.tool(name="greet", description="Greet someone by name")
async def greet(name: str) -> str:
    return f"Hello, {name}!"

if __name__ == "__main__":
    app.run()
```

资料来源：[examples/snippets/servers/fastmcp_quickstart.py:1-15]()

### Running the Server

MCP supports multiple transport mechanisms:

| Transport | Use Case | Command |
|-----------|----------|---------|
| **stdio** | CLI tools, local integration | Default |
| **streamable-http** | Web applications, remote access | `--transport streamable-http` |

```python
import click

@click.command()
@click.option("--port", default=8000, help="Port for HTTP transport")
@click.option(
    "--transport",
    type=click.Choice(["stdio", "streamable-http"]),
    default="stdio",
)
def main(port: int, transport: str) -> int:
    app = Server("my-server")
    
    if transport == "streamable-http":
        import uvicorn
        uvicorn.run(app.streamable_http_app(), host="127.0.0.1", port=port)
    else:
        from mcp.server.stdio import stdio_server
        async def run():
            async with stdio_server() as streams:
                await app.run(streams[0], streams[1], app.create_initialization_options())
        anyio.run(run)
    return 0
```

资料来源：[examples/servers/simple-prompt/server.py:50-75]()

## Server Implementation Patterns

### Handling Tools

```python
from mcp.server import Server
from mcp.types import CallToolResult, TextContent

app = Server("my-server")

async def handle_call_tool(
    name: str, 
    arguments: dict[str, Any] | None
) -> CallToolResult:
    if name == "my_tool":
        result = await my_tool_function(**(arguments or {}))
        return CallToolResult(content=[TextContent(type="text", text=result)])
    raise ValueError(f"Unknown tool: {name}")
```

### Handling Resources

```python
async def handle_list_resources() -> list[types.Resource]:
    return [
        types.Resource(
            uri="file:///data/config.json",
            name="config",
            description="Application configuration",
            mimeType="application/json",
        )
    ]

async def handle_read_resource(uri: AnyUrl) -> Iterable[ReadResourceContents]:
    # Load and return resource content
    content = load_resource(uri)
    return [ReadResourceContents(content=content, mime_type="text/plain")]
```

### Handling Prompts

```python
async def handle_list_prompts() -> list[types.Prompt]:
    return [
        types.Prompt(
            name="summarize",
            description="Summarize a document",
            arguments=[
                types.PromptArgument(
                    name="text",
                    description="Text to summarize",
                    required=True,
                )
            ],
        )
    ]

async def handle_get_prompt(
    name: str, 
    arguments: dict[str, Any] | None
) -> types.GetPromptResult:
    if name != "summarize":
        raise ValueError(f"Unknown prompt: {name}")
    
    return types.GetPromptResult(
        messages=[{"role": "user", "content": {"type": "text", "text": f"Summarize: {arguments['text']}"}}],
        description="Document summarization prompt",
    )
```

## Advanced Features

### Resource Templates

Resource templates allow dynamic resource generation based on URI patterns:

```python
from mcp.server import Server

app = Server("github-server")

@app.list_resource_templates()
async def list_templates() -> list[types.ResourceTemplate]:
    return [
        types.ResourceTemplate(
            uri_template="github://repos/{owner}/{repo}",
            name="repository",
            description="Access a GitHub repository",
            arguments=[
                types.PromptArgument(name="owner", required=True),
                types.PromptArgument(name="repo", required=True),
            ],
        )
    ]
```

### Tool Annotations

Annotations provide metadata about tool behavior:

```python
from mcp.types import Annotations

@app.tool(
    annotations=Annotations(
        destructive=AnnotationState.UNSPECIFIED,
        idempotent=AnnotationState.TRUE,
        side_effects=AnnotationState.FALSE,
    )
)
async def safe_operation(data: str) -> str:
    return data.upper()
```

## Client Configuration

MCP clients need to know how to connect to servers. Configuration varies by client:

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `MCP_SERVER_PORT` | Server port for HTTP transport | `8000` |
| `MCP_TRANSPORT_TYPE` | Transport: `streamable-http` or `sse` | `streamable-http` |
| `MCP_CLIENT_METADATA_URL` | Optional client metadata URL | None |

### Claude Desktop Integration

To install a server in Claude Desktop:

```bash
mcp install examples/servers/my-server/server.py \
    --name "My Server" \
    --with-editable ./ \
    --env-var API_KEY=secret123
```

The server will be available in Claude Desktop's MCP configuration.

## Development Workflow

### Code Quality Standards

| Check | Command | Purpose |
|-------|---------|---------|
| Format | `uv run --frozen ruff format .` | Code formatting |
| Lint | `uv run --frozen ruff check . --fix` | Style and errors |
| Type Check | `uv run --frozen pyright` | Type validation |
| Tests | `uv run --frozen pytest` | Test suite |

### Running Tests

```bash
# All tests
uv run pytest

# Specific Python version
uv run --frozen --python 3.10 pytest

# With coverage
uv run pytest --cov=mcp --cov-report=term-missing
```

### Pre-commit Hooks

Pre-commit runs all quality checks automatically:

```bash
# Install hooks
pre-commit install

# Run on all files
pre-commit run --all-files

# Run specific hook
pre-commit run ruff --all-files
```

资料来源：[CONTRIBUTING.md:30-45]()

## Exception Handling Best Practices

Follow these guidelines for robust error handling:

| Scenario | Exception Type | Example |
|----------|---------------|---------|
| File operations | `OSError`, `PermissionError` | `except (OSError, PermissionError):` |
| JSON parsing | `json.JSONDecodeError` | `except json.JSONDecodeError:` |
| Network | `ConnectionError`, `TimeoutError` | `except (ConnectionError, TimeoutError):` |
| Unknown resources | `ResourceError` | Custom MCP exception |

Always use `logger.exception()` when catching exceptions:

```python
try:
    resource = await resource_manager.get_resource(uri)
except Exception as exc:
    logger.exception(f"Error getting resource {uri}")
    raise ResourceError(f"Error reading resource {uri}") from exc
```

资料来源：[CONTRIBUTING.md:55-65]()

## Next Steps

After completing this guide, explore:

1. **Example Servers**: Browse `examples/servers/` for complete implementations
   - `simple-prompt/` - Prompt handling
   - `simple-pagination/` - Pagination patterns
   - `simple-task-interactive/` - Interactive tasks with elicitation

2. **API Reference**: Check `src/mcp/` for the full SDK implementation

3. **Specification**: Review the MCP protocol specification for protocol details

4. **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines and coding standards

## Quick Reference

### Minimal Server Template

```python
from mcp.server import Server
from mcp import types

app = Server("my-server")

@app.list_tools()
async def list_tools() -> list[types.Tool]:
    return [types.Tool(name="hello", description="Say hello", inputSchema={})]

@app.call_tool()
async def call_tool(name: str, arguments: dict[str, Any]) -> list[types.Content]:
    if name == "hello":
        return [types.TextContent(type="text", text="Hello!")]
    raise ValueError(f"Unknown tool: {name}")

if __name__ == "__main__":
    app.run()
```

### Installation Checklist

- [ ] Python 3.10+ installed
- [ ] uv installed
- [ ] Repository cloned
- [ ] Dependencies installed (`uv sync --frozen --all-extras --dev`)
- [ ] Pre-commit hooks configured
- [ ] First server implemented
- [ ] Code formatted and linted

---

<a id='project-structure'></a>

## Project Structure

### 相关页面

相关主题：[Getting Started with MCP Python SDK](#getting-started), [FastMCP Server Development](#fastmcp-server)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/__init__.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/__init__.py)
- [src/mcp/server/__init__.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/__init__.py)
- [src/mcp/server/mcpserver/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/server.py)
- [src/mcp/server/mcpserver/resources/base.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/base.py)
- [src/mcp/server/mcpserver/resources/types.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/types.py)
- [src/mcp/server/auth/routes.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/auth/routes.py)
- [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)
- [examples/servers/simple-prompt/mcp_simple_prompt/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-prompt/server.py)
</details>

# Project Structure

The Model Context Protocol (MCP) Python SDK is organized as a comprehensive toolkit for building both MCP clients and servers. The project structure reflects the protocol's architecture, separating concerns between client-side, server-side, and shared components.

## Repository Layout

The repository follows a standard Python package layout with additional documentation and examples:

| Directory | Purpose |
|-----------|---------|
| `src/mcp/` | Main SDK source code |
| `examples/` | Working examples of servers and clients |
| `docs/` | Project documentation |
| `tests/` | Test suite |

## Source Code Organization

### Core Package (`src/mcp/`)

The main package contains several subpackages that separate the SDK into logical layers:

```mermaid
graph TD
    A[src/mcp/] --> B[client/]
    A --> C[server/]
    A --> D[shared/]
    A --> E[types/]
    C --> F[mcpserver/]
    C --> G[auth/]
    F --> H[resources/]
```

### Client Package (`src/mcp/client/`)

The client package provides functionality for connecting to MCP servers. Clients handle the protocol-level communication, including transport management and request/response handling.

### Server Package (`src/mcp/server/`)

The server package is the core of the SDK, containing:

| Subpackage | Description |
|------------|-------------|
| `mcpserver/` | High-level MCPServer implementation with resource, prompt, and tool management |
| `auth/` | OAuth 2.0 authentication and authorization routes |
| `stdio/` | STDIO transport for local server communication |
| `streamable_http/` | HTTP transport for remote server communication |

### Shared Package (`src/mcp/shared/`)

Shared utilities used by both clients and servers, including common data structures and helper functions.

### Types Package (`src/mcp/types/`)

Type definitions for MCP protocol entities such as resources, prompts, tools, and annotations.

## MCPServer Architecture

The `MCPServer` class is the primary entry point for building MCP servers. It wraps a low-level `Server` and provides high-level abstractions for registering resources, prompts, and tools.

```mermaid
graph TD
    A[MCPServer] --> B[ResourceManager]
    A --> C[PromptManager]
    A --> D[ToolHandler]
    B --> E[FunctionResource]
    B --> F[FileResource]
    B --> G[ResourceTemplate]
```

### Resource Management

Resources are managed through the `ResourceManager` class, which handles both static resources and dynamic resource templates. The base class `Resource` defines the common interface:

- `uri`: Unique identifier for the resource
- `name`: Optional name for the resource
- `title`: Human-readable title
- `description`: Description of the resource
- `mime_type`: MIME type of the content (default: `text/plain`)
- `icons`: Optional list of icons
- `annotations`: Optional annotations
- `meta`: Optional metadata dictionary

资料来源：[src/mcp/server/mcpserver/resources/base.py:1-50]()

### Resource Types

| Type | Purpose | Use Case |
|------|---------|----------|
| `FunctionResource` | Dynamic content via callable | API responses, computed data |
| `FileResource` | Static file content | Configuration files, documents |
| `ResourceTemplate` | Parameterized URIs | REST-like endpoints |

Function resources are created from functions using the `from_function()` classmethod:

```python
@staticmethod
def from_function(
    fn: Callable[..., Any],
    uri: str,
    name: str | None = None,
    title: str | None = None,
    description: str | None = None,
    mime_type: str | None = None,
    icons: list[Icon] | None = None,
    annotations: Annotations | None = None,
    meta: dict[str, Any] | None = None,
) -> FunctionResource
```

资料来源：[src/mcp/server/mcpserver/resources/types.py:1-80]()

### Tool Registration

Tools are registered using the `add_tool()` decorator or method. The server handles the routing of tool calls through the `_handle_call_tool` callback:

```python
def add_tool(
    self,
    fn: Callable[..., Any],
    name: str | None = None,
    title: str | None = None,
    description: str | None = None,
    annotations: Annotations | None = None,
) -> Callable[[_CallableT], _CallableT]
```

资料来源：[src/mcp/server/mcpserver/server.py:1-200]()

### Prompt Management

Prompts are registered using the `prompt()` decorator and managed by the `PromptManager`. The `get_prompt()` method renders prompts with arguments:

```python
async def get_prompt(
    self, 
    name: str, 
    arguments: dict[str, Any] | None = None,
    context: Context[LifespanResultT, Any] | None = None
) -> GetPromptResult
```

资料来源：[src/mcp/server/mcpserver/server.py:200-300]()

## Authentication Architecture

The auth package implements OAuth 2.0 support for MCP servers. Key components include:

| Component | Purpose |
|-----------|---------|
| `TokenVerifier` | Validates bearer tokens |
| `AuthServerProvider` | Provides auth server configuration |
| `ProtectedResource` | Decorator for protected endpoints |

Metadata endpoints follow RFC 9728 compliance, constructing URLs by inserting `/.well-known/oauth-protected-resource` between the host and resource path.

资料来源：[src/mcp/server/auth/routes.py:1-100]()

## Transport Layer

MCP servers support multiple transport mechanisms:

| Transport | Description |
|-----------|-------------|
| `stdio` | Standard input/output for local processes |
| `streamable-http` | HTTP-based streaming for remote access |

The server creates different application instances based on the transport:

```python
if transport == "streamable-http":
    uvicorn.run(app.streamable_http_app(), host="127.0.0.1", port=port)
else:
    async with stdio_server() as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())
```

资料来源：[examples/servers/simple-prompt/mcp_simple_prompt/server.py:1-80]()

## Examples Structure

The `examples/` directory contains working implementations:

```
examples/
├── servers/
│   ├── simple-prompt/
│   ├── simple-task-interactive/
│   └── ...
└── clients/
    ├── simple-chatbot/
    ├── simple-task-client/
    └── ...
```

### Server Examples

Server examples demonstrate:
- Tool registration patterns
- Resource and prompt management
- Interactive tasks with elicitation
- Authentication integration

### Client Examples

Client examples demonstrate:
- Connecting via different transports
- Calling tools and resources
- Polling for task results
- OAuth authentication flows

## Key Files Reference

| File | Role |
|------|------|
| `src/mcp/__init__.py` | Public API surface, exports `__all__` |
| `src/mcp/server/mcpserver/server.py` | Main MCPServer class |
| `src/mcp/server/mcpserver/resources/base.py` | Base Resource class |
| `src/mcp/server/mcpserver/resources/types.py` | FunctionResource, FileResource implementations |

## Development Guidelines

The project enforces strict code quality standards:

- **Type hints** required for all public APIs
- **Docstrings** required for public APIs with `Raises:` sections for documented exceptions
- **Exception handling**: Use `logger.exception()` instead of `logger.error()` when catching exceptions
- **Testing**: Use `pytest` with `anyio` for async testing

资料来源：[AGENTS.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/AGENTS.md)

## Summary

The MCP Python SDK is structured around a clean separation between:

1. **Protocol types** (`types/`) - Definitions of MCP entities
2. **Server implementation** (`server/`) - Building MCP servers with resources, prompts, and tools
3. **Client implementation** (`client/`) - Connecting to and interacting with servers
4. **Shared utilities** (`shared/`) - Common functionality

The architecture supports multiple transports and authentication mechanisms while maintaining a consistent interface through the `MCPServer` class.

---

<a id='fastmcp-server'></a>

## FastMCP Server Development

### 相关页面

相关主题：[Low-Level Server Development](#low-level-server), [Server Lifecycle and Context Management](#server-lifecycle), [Resources](#resources), [Tools and Structured Output](#tools-structured-output), [Prompts and Templates](#prompts)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/mcpserver/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/server.py)
- [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)
- [examples/servers/simple-pagination/mcp_simple_pagination/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-pagination/mcp_simple_pagination/server.py)
- [AGENTS.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/AGENTS.md)
- [CONTRIBUTING.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/CONTRIBUTING.md)
- [examples/clients/simple-task-client/README.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/clients/simple-task-client/README.md)
- [examples/servers/simple-task-interactive/README.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-task-interactive/README.md)
</details>

# FastMCP Server Development

FastMCP is a streamlined framework for building Model Context Protocol (MCP) servers in Python. It provides a simplified API over the lower-level `Server` class, making it easier to expose tools, resources, prompts, and other MCP capabilities to LLM clients.

## Architecture Overview

FastMCP follows a modular architecture where different components handle distinct aspects of the MCP protocol. The framework is built around a central server instance that orchestrates tool execution, resource management, and prompt handling.

The MCP server architecture consists of several key layers working together to provide a complete protocol implementation. At the lowest level, the `Server` class handles protocol-level concerns including message parsing, state management, and transport abstraction. Above this, FastMCP provides a more developer-friendly interface for registering handlers and exposing capabilities.

```mermaid
graph TD
    A[Client] --> B[Transport Layer<br/>stdio or HTTP]
    B --> C[FastMCP Server]
    C --> D[Tools Handler]
    C --> E[Resources Handler]
    C --> F[Prompts Handler]
    D --> G[Business Logic]
    E --> H[Resource Storage]
    F --> I[Prompt Templates]
```

## Core Components

### Server Initialization

FastMCP servers are initialized with a name and optional configuration parameters. The server instance serves as the central registry for all tools, resources, and prompts that will be exposed to clients.

The following table outlines the key configuration options available when creating a FastMCP server:

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `name` | `str` | Required | Unique identifier for the server |
| `title` | `str \| None` | `None` | Human-readable title |
| `description` | `str \| None` | `None` | Server description |
| `instructions` | `str \| None` | `None` | Usage instructions for clients |
| `version` | `str` | `"1.0.0"` | Server version string |
| `lifespan` | `Lifespan \| None` | `None` | Lifecycle context manager |

资料来源：[src/mcp/server/mcpserver/server.py:80-120]()

### Tool Registration

Tools are the primary mechanism for servers to expose executable functionality to clients. FastMCP provides the `add_tool` method for registering callable functions with automatic schema generation.

```python
@mcp.add_tool()
def get_time() -> dict:
    """Get the current server time."""
    return {"current_time": "2024-01-15T10:30:00", "timezone": "UTC"}
```

Tools can be registered with custom names, titles, and descriptions to control how they appear to clients. The decorator-based approach automatically extracts docstrings and type hints to generate the tool's JSON schema.

### Resource Management

Resources provide a way to expose data that clients can read. FastMCP supports both static resources and dynamic templates that can be resolved at read time.

| Resource Type | Description | Registration Method |
|---------------|-------------|---------------------|
| Static | Fixed data stored in memory | `add_resource()` |
| Template | Dynamic URI with parameters | `add_resource_template()` |
| Dynamic | Resolved on read via callback | `add_resource()` with handler |

资料来源：[src/mcp/server/mcpserver/server.py:40-60]()

### Prompt Templates

Prompts allow servers to expose reusable prompt templates that clients can invoke with arguments. This enables servers to provide standardized interactions for common tasks.

## Transport Configuration

FastMCP supports multiple transport mechanisms for client-server communication. The choice of transport affects how clients connect and interact with the server.

### Stdio Transport

The stdio transport uses standard input and output streams for message passing. This is the default transport and works well for local integrations.

```python
from mcp.server.stdio import stdio_server

async def arun():
    async with stdio_server() as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())

anyio.run(arun)
```

资料来源：[examples/servers/simple-pagination/mcp_simple_pagination/server.py:80-90]()

### Streamable HTTP Transport

For networked deployments, the streamable HTTP transport provides persistent connections over HTTP. This enables longer-running operations and streaming responses.

| Environment Variable | Description | Default |
|---------------------|-------------|---------|
| `MCP_SERVER_PORT` | Port number | `8000` |
| `MCP_TRANSPORT_TYPE` | Transport type | `streamable-http` |
| `MCP_CLIENT_METADATA_URL` | Client metadata URL | `None` |

资料来源：[examples/clients/simple-auth-client/README.md:50-60]()

## Task Execution Model

FastMCP supports an experimental task execution model that allows tools to be called as asynchronous tasks. This enables longer-running operations with progress tracking and intermediate status updates.

The task lifecycle follows a specific state progression:

```mermaid
stateDiagram-v2
    [*] --> Created: task created
    Created --> Working: execution started
    Working --> Working: progress update
    Working --> Completed: success
    Working --> Failed: error
    Completed --> [*]
    Failed --> [*]
```

Tasks are initiated using the experimental `call_tool_as_task` method, which returns immediately with a task reference. Clients then poll for status updates using `get_task_result`.

资料来源：[examples/clients/simple-task-client/README.md:25-35]()

## Interactive Task Features

FastMCP supports two advanced interaction patterns for tasks that require external input during execution.

### Elicitation

Elicitation allows a task to pause and request user confirmation before continuing. The server uses `task.elicit()` to send a prompt to the client, which responds with the user's input.

```python
async def confirm_delete(filename: str, task=None):
    if task:
        result = await task.elicit(
            message="Confirm deletion",
            params=[...]
        )
        if result.action == "accept":
            # proceed with deletion
            pass
```

资料来源：[examples/servers/simple-task-interactive/README.md:15-25]()

### Sampling

Sampling enables tasks to request LLM completions during execution. The server sends a prompt and sampling parameters to the client, which returns the generated text.

```python
async def write_haiku(topic: str, task=None):
    if task:
        response = await task.create_message(
            messages=[...],
            model_preferences={...}
        )
        return response.content
```

## Dependency Management

FastMCP uses `uv` for package management in all development and deployment scenarios. The project maintains strict dependency floors and uses frozen lock files for reproducible environments.

| Command | Purpose |
|---------|---------|
| `uv add <package>` | Install a new dependency |
| `uv lock --upgrade-package <package>` | Upgrade a dependency |
| `uv sync --frozen --all-extras --dev` | Install all dependencies |

资料来源：[CONTRIBUTING.md:10-20]()

## Code Quality Standards

FastMCP enforces specific quality standards for all contributions:

- **Type hints**: Required for all public APIs
- **Docstrings**: Required for public functions and classes
- **Linting**: `ruff check . --fix`
- **Formatting**: `ruff format .`
- **Type checking**: `pyright`

The project uses `strict-no-cover` to ensure test coverage for all non-trivial code paths. New code should include appropriate test coverage before submission.

资料来源：[AGENTS.md:30-50]()

## Exception Handling Patterns

FastMCP defines specific exception handling patterns that all server implementations should follow:

| Pattern | Usage |
|---------|-------|
| `logger.exception()` | Always use when catching exceptions |
| Specific catches | `OSError` for file ops, `JSONDecodeError` for JSON |
| Forbidden | `except Exception:` in library code |

资料来源：[AGENTS.md:25-30]()

## Testing Guidelines

Tests for FastMCP components should follow these principles:

- Use `anyio` for async testing, not raw `asyncio`
- Write plain top-level `test_*` functions, not `Test` prefixed classes
- Tests should be fast and deterministic
- Prefer in-memory execution over subprocess spawning

```bash
uv run --frozen pytest
```

资料来源：[AGENTS.md:55-65]()

## Complete Server Example

The following example demonstrates a minimal FastMCP server with tools, resources, and prompts:

```python
import anyio
import click
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("example-server")

@mcp.add_tool()
def get_time() -> dict:
    """Get the current server time."""
    return {"current_time": "2024-01-15T10:30:00", "timezone": "UTC"}

@mcp.add_resource("file://example/{name}")
def get_file(name: str) -> str:
    return f"Content of {name}"

@mcp.add_prompt()
def review_code(code: str, language: str) -> str:
    return f"Review this {language} code:\n\n{code}"

@click.command()
@click.option("--port", default=8000)
@click.option("--transport", default="stdio")
def main(port: int, transport: str) -> int:
    if transport == "streamable-http":
        import uvicorn
        uvicorn.run(mcp.streamable_http_app(), host="127.0.0.1", port=port)
    else:
        anyio.run(mcp.run)
    return 0
```

## Next Steps

For continued learning about FastMCP development:

1. Explore the [example servers](https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/servers) directory for complete implementations
2. Review the [migration guide](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/migration.md) for breaking changes between versions
3. Consult the [MCP specification](https://modelcontextprotocol.io/specification) for protocol-level details

---

<a id='low-level-server'></a>

## Low-Level Server Development

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Server Lifecycle and Context Management](#server-lifecycle), [Transports Overview](#transports)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/lowlevel/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/lowlevel/server.py)
- [src/mcp/server/lowlevel/__init__.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/lowlevel/__init__.py)
- [src/mcp/server/session.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/session.py)
- [examples/snippets/servers/lowlevel/basic.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lowlevel/basic.py)
- [examples/snippets/servers/lowlevel/lifespan.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/lowlevel/lifespan.py)
- [docs/low-level-server.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/low-level-server.md)
</details>

# Low-Level Server Development

The Model Context Protocol (MCP) Python SDK provides a low-level server API that gives developers fine-grained control over protocol handling, session management, and request/response processing. This approach differs from the high-level `MCPServer` abstraction by exposing the underlying protocol mechanics directly, enabling custom transport implementations, advanced middleware, and specialized integration scenarios.

## Overview

The low-level server layer is the foundational component of the MCP SDK's server architecture. It operates at the protocol level, handling JSON-RPC message processing, session lifecycle, and notification dispatching without imposing opinions on transport mechanisms or application structure.

### Key Characteristics

| Characteristic | Description |
|----------------|-------------|
| Protocol Focus | Handles MCP JSON-RPC protocol directly |
| Transport Agnostic | Works with stdio, HTTP/SSE, and custom transports |
| Session Management | Manages individual client connections independently |
| Callback-Based | Uses handler callbacks for protocol operations |
| Type Safe | Full type hints for all public interfaces |

The low-level server is used internally by the higher-level `MCPServer` class, which adds convenience abstractions, automatic middleware, and resource/prompt management. Direct use of the low-level API is appropriate when:

- Building custom MCP server implementations
- Implementing specialized transport adapters
- Requiring direct control over protocol behavior
- Developing protocol-level tools or testing utilities

## Architecture

### Component Hierarchy

```mermaid
graph TD
    A[Low-Level Server] --> B[Session Manager]
    A --> C[Request Handler]
    A --> D[Notification Dispatcher]
    B --> E[Client Session]
    B --> F[Client Session]
    E --> G[Protocol State]
    F --> H[Protocol State]
    C --> I[List Tools Handler]
    C --> J[Call Tool Handler]
    C --> K[List Resources Handler]
    C --> L[Read Resource Handler]
```

### Server Class Structure

The `Server` class in `src/mcp/server/lowlevel/server.py` serves as the central coordinator for all protocol operations. It accepts callback handlers for each protocol method and manages the registration of server capabilities.

```python
class Server:
    def __init__(
        self,
        name: str,
        title: str | None = None,
        description: str | None = None,
        instructions: str | None = None,
        version: str | None = None,
        on_list_tools: Callable | None = None,
        on_call_tool: Callable | None = None,
        on_list_resources: Callable | None = None,
        on_read_resource: Callable | None = None,
        on_list_resource_templates: Callable | None = None,
        on_list_prompts: Callable | None = None,
        on_get_prompt: Callable | None = None,
        on_list_resource_subscriptions: Callable | None = None,
        on_subscribe_resource: Callable | None = None,
        on_unsubscribe_resource: Callable | None = None,
        on_list_completions: Callable | None = None,
        on_initialize: Callable | None = None,
        on_set_logging_level: Callable | None = None,
        on_send_notification: Callable | None = None,
        lifespan: Callable | None = None,
    )
```

## Request Handlers

The low-level server uses callback-based handlers for each protocol method. These handlers receive structured request parameters and return typed responses.

### Tool Handlers

Tools are executable functions exposed by the server to clients. The low-level API provides two handlers:

| Handler | Purpose | Handler Signature |
|---------|---------|-------------------|
| `on_list_tools` | Return available tools and their schemas | `async def(...) -> list[types.Tool]` |
| `on_call_tool` | Execute a tool with given arguments | `async def(...) -> CallToolResult` |

### Resource Handlers

Resources provide read-only data access through URIs:

| Handler | Purpose | Handler Signature |
|---------|---------|-------------------|
| `on_list_resources` | List available resources | `async def(...) -> list[types.Resource]` |
| `on_list_resource_templates` | List resource templates with variable placeholders | `async def(...) -> list[types.ResourceTemplate]` |
| `on_read_resource` | Read resource content by URI | `async def(...) -> Iterable[ReadResourceContents]` |
| `on_subscribe_resource` | Subscribe to resource change notifications | `async def(...) -> None` |
| `on_unsubscribe_resource` | Unsubscribe from resource notifications | `async def(...) -> None` |

### Prompt Handlers

Prompts are templated message configurations:

| Handler | Purpose | Handler Signature |
|---------|---------|-------------------|
| `on_list_prompts` | List available prompt templates | `async def(...) -> list[types.Prompt]` |
| `on_get_prompt` | Render a prompt with given arguments | `async def(...) -> types.GetPromptResult` |

### Completion Handler

Auto-completion support for resource template variables:

```python
on_list_completions: Callable[[ServerRequestContext, types.CompleteRequestParams], Awaitable[types.CompleteResult]]
```

### Lifecycle Handlers

| Handler | Purpose | Handler Signature |
|---------|---------|-------------------|
| `on_initialize` | Handle client initialization | `async def(...) -> InitializeResult` |
| `on_set_logging_level` | Handle logging level changes | `async def(...) -> None` |

## Session Management

The session layer (`src/mcp/server/session.py`) manages individual client connections. Each session maintains protocol state, request/response tracking, and notification channels.

### Session Lifecycle

```mermaid
stateDiagram-v2
    [*] --> Initializing: Client connects
    Initializing --> Running: Initialize response sent
    Running --> Running: Request/Response cycle
    Running --> Closed: Client disconnects
    Closed --> [*]: Cleanup complete
```

### Session Responsibilities

- **Protocol State**: Maintains initialization state and capability negotiation
- **Request Tracking**: Correlates requests with responses using JSON-RPC IDs
- **Notification Queue**: Buffers notifications for delivery
- **Resource Subscriptions**: Tracks active resource subscriptions per client

## Lifespan Management

Lifespan handlers manage server startup and shutdown phases, enabling resource acquisition and cleanup.

### Lifespan Callback Pattern

```python
from contextlib import asynccontextmanager
from mcp.server.lowlevel.server import Server

@asynccontextmanager
async def lifespan(server: Server):
    # Startup: acquire resources
    db = await connect_to_database()
    cache = await create_cache()
    
    # Make resources available to handlers
    server.request_context.append(db)
    
    yield
    
    # Shutdown: release resources
    await db.close()
    await cache.close()
```

### Lifespan Phases

| Phase | Purpose | Operations |
|-------|---------|------------|
| Startup | Initialize resources before serving | DB connections, caches, clients |
| Running | Server accepts connections | Normal operation |
| Shutdown | Clean up acquired resources | Close connections, flush buffers |

资料来源：[examples/snippets/servers/lowlevel/lifespan.py]()

## Basic Implementation Pattern

A minimal low-level server implementation follows this pattern:

```python
from mcp.server.lowlevel.server import Server
from mcp.types import Tool, CallToolResult

async def handle_list_tools() -> list[Tool]:
    return [
        Tool(
            name="hello",
            description="Say hello to someone",
            inputSchema={
                "type": "object",
                "properties": {
                    "name": {"type": "string"}
                }
            }
        )
    ]

async def handle_call_tool(
    name: str, arguments: dict | None
) -> CallToolResult:
    if name == "hello":
        return CallToolResult(
            content=[types.TextContent(type="text", text=f"Hello, {arguments.get('name', 'World')}!")]
        )
    raise ValueError(f"Unknown tool: {name}")

server = Server(
    name="hello-server",
    on_list_tools=handle_list_tools,
    on_call_tool=handle_call_tool,
)
```

资料来源：[examples/snippets/servers/lowlevel/basic.py]()

## Integration with Transports

The low-level server is transport-agnostic. Different transport implementations connect to the server:

### Stdio Transport

For command-line integration and local processes:

```python
from mcp.server.stdio import stdio_server

async def run():
    async with stdio_server() as streams:
        await server.run(
            streams[0],
            streams[1],
            server.create_initialization_options()
        )
```

资料来源：[examples/servers/simple-prompt/mcp_simple_prompt/server.py]()

### Streamable HTTP Transport

For networked deployments with SSE notifications:

```python
import uvicorn

app = server.streamable_http_app()
uvicorn.run(app, host="127.0.0.1", port=8000)
```

### Custom Transport Integration

Implement custom transports by calling server methods directly:

```python
# Custom transport reads from WebSocket
async def custom_transport_handler(websocket):
    read_stream = websocket_async_reader(websocket)
    write_stream = websocket_async_writer(websocket)
    
    await server.run(
        read_stream,
        write_stream,
        server.create_initialization_options()
    )
```

## Server Initialization Options

The `create_initialization_options()` method generates the protocol initialization payload:

```python
def create_initialization_options(
    self,
    capabilities: ServerCapabilities | None = None,
    protocol_version: str | None = None,
) -> InitializationOptions
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `capabilities` | `ServerCapabilities` | Explicit capability declaration |
| `protocol_version` | `str` | Override default protocol version |

Capabilities are automatically constructed based on registered handlers, but can be explicitly overridden.

## Error Handling

The low-level server expects handlers to raise appropriate exceptions for error conditions:

| Exception | Usage |
|-----------|-------|
| `ValueError` | Invalid tool/resource names or unknown operations |
| `ResourceError` | Resource not found or unreadable |
| `PromptError` | Invalid prompt name or arguments |
| `ToolError` | Tool execution failures |

Handlers should use `logger.exception()` for logging errors rather than `logger.error()` when catching exceptions, ensuring stack traces are captured for debugging.

资料来源：[AGENTS.md]()

## Testing Low-Level Servers

The SDK uses `pytest` with `anyio` for async testing. Test patterns for low-level servers:

```python
import pytest
from mcp.server.lowlevel.server import Server
from mcp.testing import create_test_session

async def test_tool_discovery():
    server = Server(name="test", on_list_tools=list_tools_handler)
    
    async with create_test_session(server) as session:
        tools = await session.list_tools()
        assert len(tools) == 1
        assert tools[0].name == "test_tool"
```

资料来源：[CONTRIBUTING.md]()

## High-Level vs Low-Level API

| Aspect | High-Level `MCPServer` | Low-Level `Server` |
|--------|------------------------|-------------------|
| Resource Management | Built-in `ResourceManager` | Manual implementation |
| Prompt Management | Built-in `PromptManager` | Manual implementation |
| Middleware | Automatic | Manual |
| Complexity | Higher abstraction | Direct control |
| Flexibility | Convention-based | Protocol-based |

The `MCPServer` class internally delegates to the low-level `Server`, adding convenience features. For most use cases, `MCPServer` provides sufficient functionality with less boilerplate.

资料来源：[src/mcp/server/mcpserver/server.py]()

## Best Practices

1. **Always use `logger.exception()`** when logging caught exceptions
2. **Catch specific exceptions** rather than broad `except Exception:`
3. **Use type hints** on all handler functions and public APIs
4. **Include docstrings** for handler functions with `Raises:` sections
5. **Test handlers in isolation** using mock sessions
6. **Validate handler arguments** before processing
7. **Clean up resources** in lifespan shutdown phases

## Public API Surface

The public API is defined in `src/mcp/server/lowlevel/__init__.py` via `__all__`. Only symbols listed there should be imported:

```python
from mcp.server.lowlevel import (
    Server,
    ServerRequestContext,
    InitializationOptions,
)
```

Adding symbols to `__all__` is a deliberate API decision, not a convenience re-export.

资料来源：[AGENTS.md]()

---

<a id='server-lifecycle'></a>

## Server Lifecycle and Context Management

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Low-Level Server Development](#low-level-server), [Context and Session Management](#context-session)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/mcpserver/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/server.py)
- [src/mcp/server/mcpserver/resources/types.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/types.py)
- [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)
- [examples/servers/simple-prompt/mcp_simple_prompt/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-prompt/mcp_simple_prompt/server.py)
- [examples/servers/simple-pagination/mcp_simple_pagination/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-pagination/mcp_simple_pagination/server.py)
- [AGENTS.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/AGENTS.md)
</details>

# Server Lifecycle and Context Management

The Model Context Protocol (MCP) Python SDK implements a sophisticated lifecycle and context management system that enables servers to handle initialization, request processing, resource access, and graceful shutdown. This documentation covers the architecture, components, and best practices for implementing servers that properly manage their lifecycle and context propagation.

## Overview

The MCP server architecture is built around three core concepts:

1. **Lifecycle Management**: Managing server startup, request handling, and graceful shutdown through lifespan handlers
2. **Context Objects**: Request-scoped objects that carry server references, arguments, and metadata through handler chains
3. **Resource Managers**: Components that handle resource registration, retrieval, and templating with contextual awareness

These components work together to provide a consistent, testable, and maintainable server implementation. The `MCPServer` class serves as the central coordinator, integrating the low-level `Server` with resource managers, prompt managers, and lifespan handling.

## Architecture

### Component Hierarchy

```mermaid
graph TD
    A[MCP Server Application] --> B[MCPServer]
    B --> C[LowLevel Server]
    C --> D[Lifespan Manager]
    B --> E[Resource Manager]
    B --> F[Prompt Manager]
    B --> G[Context Factory]
    
    H[Client Request] --> C
    C --> I[Request Handlers]
    I --> G
    G --> E
    G --> F
```

### Lifecycle Flow

```mermaid
sequenceDiagram
    participant Client
    participant MCPServer
    participant LifespanManager
    participant ResourceManager
    participant PromptManager
    
    Note over MCPServer: Startup Phase
    MCPServer->>LifespanManager: Initialize lifespan context
    LifespanManager->>UserLifespan: startup callback
    UserLifespan-->>LifespanManager: lifespan_state
    
    Note over MCPServer: Ready State
    Client->>MCPServer: list_tools request
    MCPServer->>ResourceManager: Get registered tools
    ResourceManager-->>MCPServer: Tool list
    
    Client->>MCPServer: read_resource request
    MCPServer->>LifespanManager: Get context
    LifespanManager-->>MCPServer: context with lifespan_state
    MCPServer->>ResourceManager: Get resource with context
    ResourceManager-->>MCPServer: Resource content
    
    Note over MCPServer: Shutdown Phase
    MCPServer->>LifespanManager: Shutdown signal
    LifespanManager->>UserLifespan: shutdown callback
```

## Lifecycle Management

### Lifespan Wrapper

The `lifespan_wrapper` function wraps user-defined lifespan callbacks and integrates them with the server's low-level implementation:

```python
lifespan=(lifespan_wrapper(self, self.settings.lifespan) if self.settings.lifespan else default_lifespan)
```

资料来源：[src/mcp/server/mcpserver/server.py:100-101]()

The lifespan wrapper serves two primary purposes:

1. **Initialization**: Creates the lifespan context that will be available throughout the server's lifetime
2. **Integration**: Bridges user-defined startup/shutdown callbacks with the low-level server's lifespan protocol

### Default Lifespan

When no custom lifespan is provided, the `default_lifespan` ensures the server still follows proper lifecycle protocols. This is particularly useful for simple servers that don't require initialization or cleanup logic.

### Lifespan Context State

The lifespan context (`LifespanResultT`) carries server-wide state that handlers can access. This state is created during startup and remains available until shutdown:

```python
async def read_resource(
    self, uri: AnyUrl | str, context: Context[LifespanResultT, Any] | None = None
) -> Iterable[ReadResourceContents]:
    """Read a resource by URI."""
    if context is None:
        context = Context(mcp_server=self)
```

资料来源：[src/mcp/server/mcpserver/server.py:47-51]()

The context parameter is optional but recommended for accessing lifespan state within resource handlers.

### Example: Custom Lifespan Implementation

```python
from contextlib import asynccontextmanager
from mcp.server import MCPServer

@asynccontextmanager
async def my_lifespan(server: MCPServer):
    # Startup: Initialize connections, load data
    db_connection = await connect_to_database()
    server.context["db"] = db_connection
    
    yield  # Server runs here
    
    # Shutdown: Clean up resources
    await db_connection.close()

app = MCPServer(
    name="my-server",
    lifespan=my_lifespan
)
```

## Context Management

### Context Object Structure

The `Context` object is a generic container that provides access to server state and request metadata:

| Parameter | Type | Description |
|-----------|------|-------------|
| `mcp_server` | `MCPServer` | Reference to the server instance |
| `arguments` | `dict[str, Any]` | Request arguments (for template-based operations) |
| `meta` | `dict[str, Any]` | Request metadata |

The context is parameterized with two type variables:

```python
Context[LifespanResultT, Any]
```

Where `LifespanResultT` is the type of the lifespan state, and `Any` represents additional request-scoped data.

### Context in Resource Operations

When reading resources, the context carries critical information that resource handlers can use:

```python
async def read_resource(
    self, uri: AnyUrl | str, context: Context[LifespanResultT, Any] | None = None
) -> Iterable[ReadResourceContents]:
    if context is None:
        context = Context(mcp_server=self)
    try:
        resource = await self._resource_manager.get_resource(uri, context)
```

资料来源：[src/mcp/server/mcpserver/server.py:47-56]()

The resource manager passes this context to resource handlers, enabling:

- **Dynamic content**: Resources can read lifespan state (e.g., database connections) to generate content
- **Template resolution**: URI templates can use context arguments to resolve placeholders
- **Metadata propagation**: Request metadata flows through to resource handlers

### Context in Completion Resolution

The context object also supports completion callbacks, where it carries the arguments from the current request:

```python
if context and context.arguments and context.arguments.get("owner") == "modelcontextprotocol":
    repos = ["python-sdk", "typescript-sdk", "specification"]
    return Completion(values=repos, has_more=False)
```

资料来源：[examples/snippets/servers/completion.py:8-13]()

## Resource Management

### Resource Manager Initialization

The `ResourceManager` handles all resource-related operations:

```python
self._resource_manager = ResourceManager(
    resources=resources, 
    warn_on_duplicate_resources=self.settings.warn_on_duplicate_resources
)
```

资料来源：[src/mcp/server/mcpserver/server.py:85-87]()

| Option | Type | Description |
|--------|------|-------------|
| `resources` | `list[Resource]` | Initial resource set |
| `warn_on_duplicate_resources` | `bool` | Log warning on duplicate URI registration |

### Resource Types

The SDK provides several resource types for different use cases:

| Resource Type | Description | Use Case |
|--------------|-------------|----------|
| `FunctionResource` | Dynamic content from callable | API responses, computed data |
| `FileResource` | Static file content | Configuration files, documents |
| `ResourceTemplate` | Parameterized URI pattern | Dynamic resource resolution |

### FunctionResource with Context

The `FunctionResource` class accepts a callable that receives context for dynamic content generation:

```python
@classmethod
def from_function(
    cls,
    fn: Callable[..., Any],
    uri: str | None = None,
    name: str | None = None,
    title: str | None = None,
    description: str | None = None,
    mime_type: str | None = None,
    icons: ResourceIcons | None = None,
    annotations: Annotations | None = None,
    meta: dict[str, Any] | None = None,
) -> FunctionResource:
    """Create a FunctionResource from a function."""
    func_name = name or fn.__name__
    if func_name == "<lambda>":  # pragma: no cover
        raise ValueError("You must provide a name for lambda functions")

    # ensure the arguments are properly cast
    fn = validate_call(fn)

    return cls(
        uri=uri,
        name=func_name,
        title=title,
        description=description or fn.__doc__ or "",
        mime_type=mime_type or "text/plain",
        fn=fn,
        icons=icons,
        annotations=annotations,
        meta=meta,
    )
```

资料来源：[src/mcp/server/mcpserver/resources/types.py:101-130]()

The function is validated using `validate_call` to ensure proper argument handling and type safety.

### FileResource with Binary Support

The `FileResource` handles file-based resources with explicit binary support:

```python
class FileResource(Resource):
    """A resource that reads from a file.

    Set is_binary=True to read the file as binary data instead of text.
    """

    path: Path = Field(description="Path to the file")
    is_binary: bool = Field(
        default=False,
        description="Whether to read the file as binary data",
    )
    mime_type: str = Field(
        default="text/plain",
        description="MIME type of the resource content",
    )

    @pydantic.field_validator("path")
    @classmethod
    def validate_absolute_path(cls, path: Path) -> Path:
        """Ensure path is absolute."""
        if not path.is_absolute():
            raise ValueError("Path must be absolute")
        return path
```

资料来源：[src/mcp/server/mcpserver/resources/types.py:133-154]()

Key validation rules:

- **Absolute paths required**: All file paths must be absolute to prevent path traversal issues
- **MIME type inference**: Can be manually specified or derived from file extension
- **Binary mode**: Set `is_binary=True` for non-text content

## Request Handling Architecture

### Handler Chain

```mermaid
graph LR
    A[Incoming Request] --> B[MCPServer Entry]
    B --> C[List Tools Handler]
    B --> D[Call Tool Handler]
    B --> E[List Resources Handler]
    B --> F[Read Resource Handler]
    B --> G[List Prompts Handler]
    B --> H[Get Prompt Handler]
    
    C --> I[Resource Manager]
    E --> I
    F --> I
    I --> J[Context Injection]
    J --> K[Resource Handler]
```

### Error Handling in Resource Reading

The server implements defensive error handling to prevent information leakage:

```python
try:
    resource = await self._resource_manager.get_resource(uri, context)
except ValueError as exc:
    raise ResourceError(f"Unknown resource: {uri}") from exc

try:
    content = await resource.read()
    return [ReadResourceContents(content=content, mime_type=resource.mime_type, meta=resource.meta)]
except Exception as exc:
    logger.exception(f"Error getting resource {uri}")
    # If an exception happens when reading the resource, we should not leak the exception to the client.
    raise ResourceError(f"Error reading resource {uri}") from exc
```

资料来源：[src/mcp/server/mcpserver/server.py:53-67]()

Key principles:

1. **Specific exception catching**: `ValueError` is caught for unknown resources
2. **Generic exception wrapping**: Unexpected errors are wrapped to prevent leaking implementation details
3. **Logging with context**: `logger.exception()` is used to preserve stack traces for debugging

## Prompt and Tool Integration

### Prompt Manager

The `PromptManager` handles prompt registration with duplicate detection:

```python
self._prompt_manager = PromptManager(warn_on_duplicate_prompts=self.settings.warn_on_duplicate_prompts)
```

资料来源：[src/mcp/server/mcpserver/server.py:88-89]()

### Handler Registration

All handlers are registered with the low-level server during initialization:

```python
self._lowlevel_server = Server(
    name=name or "mcp-server",
    title=title,
    description=description,
    instructions=instructions,
    website_url=website_url,
    icons=icons,
    version=version,
    on_list_tools=self._handle_list_tools,
    on_call_tool=self._handle_call_tool,
    on_list_resources=self._handle_list_resources,
    on_read_resource=self._handle_read_resource,
    on_list_resource_templates=self._handle_list_resource_templates,
    on_list_prompts=self._handle_list_prompts,
    on_get_prompt=self._handle_get_prompt,
    lifespan=(lifespan_wrapper(self, self.settings.lifespan) if self.settings.lifespan else default_lifespan),
)
```

资料来源：[src/mcp/server/mcpserver/server.py:90-109]()

## Transport Integration

### Streamable HTTP Transport

Servers can expose HTTP endpoints for remote clients:

```python
@click.command()
@click.option("--port", default=8000, help="Port to listen on for HTTP")
@click.option(
    "--transport",
    type=click.Choice(["stdio", "streamable-http"]),
    default="stdio",
    help="Transport type",
)
def main(port: int, transport: str) -> int:
    app = Server("mcp-simple-prompt", ...)
    
    if transport == "streamable-http":
        import uvicorn
        uvicorn.run(app.streamable_http_app(), host="127.0.0.1", port=port)
```

资料来源：[examples/servers/simple-prompt/mcp_simple_prompt/server.py:42-56]()

The `streamable_http_app()` method creates an ASGI application that handles the MCP protocol over HTTP, maintaining lifecycle and context across requests.

## Best Practices

### Lifecycle Management

| Practice | Rationale |
|----------|-----------|
| Use `logger.exception()` for caught exceptions | Preserves stack traces for debugging |
| Avoid `except Exception:` at top level | Catch specific exceptions for proper handling |
| Initialize resources in startup | Ensures availability before handling requests |
| Clean up in shutdown | Prevents resource leaks |

### Context Usage

| Practice | Rationale |
|----------|-----------|
| Pass context to resource handlers | Enables dynamic content generation |
| Access lifespan state through context | Provides access to initialized resources |
| Use type hints for context parameters | Improves IDE support and type checking |

### Resource Handling

| Practice | Rationale |
|----------|-----------|
| Use absolute paths for FileResource | Prevents path traversal vulnerabilities |
| Specify MIME types explicitly | Ensures correct client interpretation |
| Handle errors with ResourceError | Provides clear error messages without leaking details |

## Testing Considerations

According to the development guidelines, tests should be:

- **Fast and deterministic**: Prefer in-memory async execution
- **Use anyio for async testing**: Not asyncio directly
- **Avoid Test-prefixed classes**: Write plain `test_*` functions
- **Reach for threads only when necessary**: Subprocesses as last resort

资料来源：[AGENTS.md:75-82]()

The context-aware design enables easy testing by allowing mock contexts to be injected:

```python
async def test_resource_with_context():
    # Create a mock context with test lifespan state
    context = Context(
        mcp_server=test_server,
        arguments={"owner": "test-owner"}
    )
    
    # Resource handler can access context.arguments
    result = await server.read_resource("github://repos/{owner}/{repo}", context)
```

## Summary

The MCP Python SDK's server lifecycle and context management system provides:

1. **Structured lifecycle handling**: Startup, request processing, and shutdown phases with proper resource management
2. **Context propagation**: Request-scoped objects carrying server references and arguments through handler chains
3. **Resource abstraction**: Flexible resource types supporting static files and dynamic content
4. **Error isolation**: Protection against information leakage while maintaining debuggability
5. **Transport flexibility**: Support for both stdio and streamable HTTP transports

This architecture enables developers to build robust MCP servers that maintain clean separation of concerns, proper resource lifecycle management, and consistent request handling patterns.

---

<a id='resources'></a>

## Resources

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Prompts and Templates](#prompts), [Tools and Structured Output](#tools-structured-output)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/mcpserver/resources/base.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/base.py)
- [src/mcp/server/mcpserver/resources/types.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/resources/types.py)
- [src/mcp/server/fastmcp/resources/base.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/resources/base.py)
- [src/mcp/server/fastmcp/resources/resource_manager.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/resources/resource_manager.py)
- [examples/snippets/servers/basic_resource.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_resource.py)
- [examples/snippets/servers/completion.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/completion.py)
</details>

# Resources

Resources are a core concept in the Model Context Protocol (MCP) that allow servers to expose data and content to clients. Unlike tools (which perform actions) or prompts (which are templates for LLM interactions), resources provide a way to share information that can be read by clients.

## Overview

In MCP, resources serve as **data containers** that can be:

- Read on demand by clients
- Organized with metadata (title, description, MIME type)
- Annotated with additional context
- Dynamically generated (via functions) or static (from files)

Resources follow a request-response pattern where clients query for available resources and then read their contents when needed.

资料来源：[examples/snippets/servers/basic_resource.py:1-50]()

## Architecture

```mermaid
graph TD
    A[Client] -->|list_resources / list_resource_templates| B[MCPServer]
    A -->|read_resource| B
    B -->|delegates| C[ResourceManager]
    C -->|manages| D[Resource instances]
    C -->|manages| E[ResourceTemplate instances]
    D -->|read| F[FunctionResource]
    D -->|read| G[FileResource]
    F -->|dynamic content| H[Callable Function]
    G -->|static content| I[File System]
```

## Resource Types

### Base Resource

All resources inherit from the abstract `Resource` base class defined in `base.py`:

| Field | Type | Description |
|-------|------|-------------|
| `uri` | `str` | **Required.** Unique identifier for the resource |
| `name` | `str \| None` | Display name (defaults to URI if not provided) |
| `title` | `str \| None` | Human-readable title |
| `description` | `str \| None` | Description of the resource content |
| `mime_type` | `str` | MIME type (default: `text/plain`) |
| `icons` | `list[Icon] \| None` | Optional icon specifications |
| `annotations` | `Annotations \| None` | Optional metadata annotations |
| `meta` | `dict[str, Any] \| None` | Optional custom metadata |

资料来源：[src/mcp/server/mcpserver/resources/base.py:17-31]()

### FunctionResource

A resource that generates content dynamically by calling a function:

```python
class FunctionResource(Resource):
    fn: Callable[[], str | bytes]
```

The function is invoked each time a client reads the resource, allowing for dynamic content generation. The function should return either:
- `str` for text content
- `bytes` for binary content

资料来源：[src/mcp/server/mcpserver/resources/types.py:1-50]()

### FileResource

A resource that reads content from the file system:

```python
class FileResource(Resource):
    path: Path
    is_binary: bool = False
    mime_type: str = "text/plain"
```

Key validation rules:
- Path **must** be absolute (raises `ValueError` otherwise)
- Binary mode is automatically detected based on MIME type when not explicitly set

资料来源：[src/mcp/server/mcpserver/resources/types.py:80-100]()

## Resource Templates

Resource templates allow servers to expose parameterized resources. Clients can list templates and provide arguments to instantiate specific resource URIs.

### Template Structure

```mermaid
classDiagram
    class ResourceTemplate {
        +uri_template: str
        +name: str
        +title: str | None
        +description: str | None
        +mime_type: str
        +annotations: Annotations | None
        +_meta: dict
    }
```

Templates use URI templates with placeholders that clients fill in when making requests.

资料来源：[src/mcp/server/fastmcp/resources/templates.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/resources/templates.py)

## Resource Manager

The `ResourceManager` handles registration, storage, and retrieval of resources and templates:

| Method | Description |
|--------|-------------|
| `list_resources()` | Returns all registered resources |
| `list_templates()` | Returns all registered resource templates |
| `get_resource(uri)` | Retrieves a resource by URI |
| `get_resource_by_name(name)` | Retrieves a resource by name |

The manager supports duplicate resource detection controlled by the `warn_on_duplicate_resources` setting.

资料来源：[src/mcp/server/fastmcp/resources/resource_manager.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/resources/resource_manager.py)

## Server Integration

The `MCPServer` class integrates resources through the resource manager:

```mermaid
sequenceDiagram
    participant Client
    participant MCPServer
    participant ResourceManager
    participant Resource
    
    Client->>MCPServer: list_resources()
    MCPServer->>ResourceManager: list_resources()
    ResourceManager-->>MCPServer: List[Resource]
    MCPServer-->>Client: MCPResource list
    
    Client->>MCPServer: read_resource(uri)
    MCPServer->>ResourceManager: get_resource(uri)
    ResourceManager->>Resource: read()
    Resource-->>ResourceManager: content
    ResourceManager-->>MCPServer: ReadResourceContents
    MCPServer-->>Client: Resource content
```

The server implements these async methods:
- `list_resources()` → `list[MCPResource]`
- `list_resource_templates()` → `list[MCPResourceTemplate]`
- `read_resource(uri)` → `Iterable[ReadResourceContents]`

资料来源：[src/mcp/server/mcpserver/server.py:50-80]()

## Usage Examples

### Basic Resource Registration

```python
from mcp.server import Server
from mcp.server.resource_manager import ResourceManager
from mcp.server.resources import FunctionResource

# Create resource manager
resource_manager = ResourceManager()

# Register a function-based resource
resource_manager.add(
    FunctionResource(
        uri="example://current-time",
        name="current_time",
        title="Current Time",
        description="Returns the current server time",
        fn=lambda: datetime.now().isoformat()
    )
)

# Create server with resources
server = Server("my-server", resources=[resource_manager])
```

资料来源：[examples/snippets/servers/basic_resource.py]()

### Resource with Completion Support

Resources can be paired with completion providers for intelligent suggestions:

```python
async def handle_completion(
    context: ServerRequestContext,
    ref: ResourceTemplateReference,
    argument: str
) -> Completion | None:
    if ref.uri == "github://repos/{owner}/{repo}":
        if argument.name == "repo":
            if context.arguments.get("owner") == "modelcontextprotocol":
                return Completion(
                    values=["python-sdk", "typescript-sdk", "specification"],
                    has_more=False
                )
    return None
```

资料来源：[examples/snippets/servers/completion.py:10-20]()

## Error Handling

The server handles resource-related errors gracefully:

| Error Condition | Server Response |
|-----------------|-----------------|
| Unknown resource URI | `ResourceError("Unknown resource: {uri}")` |
| Error reading resource | `ResourceError("Error reading resource: {uri}")` |

Internal exceptions are **never leaked** to clients for security reasons. The server logs the actual exception via `logger.exception()` and returns a sanitized error message.

资料来源：[src/mcp/server/mcpserver/server.py:65-75]()

## Best Practices

1. **Use descriptive URIs**: Follow a consistent naming scheme like `scheme://path/to/resource`
2. **Provide titles and descriptions**: Help clients understand resource purpose
3. **Set correct MIME types**: Enable proper content handling by clients
4. **Use function resources for dynamic content**: File resources for static data
5. **Validate inputs**: Ensure resource functions handle edge cases gracefully
6. **Avoid exposing sensitive data**: Resources are visible to all connected clients

---

<a id='tools-structured-output'></a>

## Tools and Structured Output

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Context and Session Management](#context-session)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/fastmcp/tools/base.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/tools/base.py)
- [src/mcp/server/fastmcp/tools/tool_manager.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/tools/tool_manager.py)
- [src/mcp/server/validation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/validation.py)
- [examples/snippets/servers/structured_output.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/structured_output.py)
- [examples/snippets/servers/direct_call_tool_result.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/direct_call_tool_result.py)
</details>

# Tools and Structured Output

## Overview

The Model Context Protocol (MCP) Python SDK provides a comprehensive system for defining and managing **tools** — callable functions that LLM clients can invoke to perform actions or retrieve data. Alongside tools, the SDK supports **structured output** through resources and well-defined result types, enabling type-safe, predictable communication between servers and clients.

Tools serve as the primary mechanism for servers to expose executable functionality to clients. Each tool has a name, optional title and description, input parameters, and a return type. The SDK enforces validation on tool names and provides mechanisms for handling errors gracefully.

资料来源：[src/mcp/server/mcpserver/server.py:add_tool]() (lines covering the add_tool method signature)

## Tool Registration Architecture

### Registration Flow

Tools are registered with an `MCPServer` instance using the `add_tool()` method. The registration process validates inputs, stores metadata, and prepares handlers for incoming tool calls.

```mermaid
graph TD
    A[Developer defines function] --> B[Call server.add_tool fn, name, title, description]
    B --> C{Validation}
    C -->|Name valid| D[Store in ToolManager]
    C -->|Invalid name| E[Raise ValueError]
    D --> F[Register with LowLevel Server]
    F --> G[Handle list_tools callback]
    
    H[Client requests tools] --> I[_handle_list_tools]
    I --> J[Return tool manifests]
    
    K[Client calls tool] --> L[_handle_call_tool]
    L --> M[Execute function]
    M --> N[Return CallToolResult]
```

### Adding Tools to Server

Tools are added via the server's `add_tool()` method, which accepts the following parameters:

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `fn` | `Callable[..., Any]` | Yes | The function to expose as a tool |
| `name` | `str \| None` | No | Override the function's name |
| `title` | `str \| None` | No | Human-readable title |
| `description` | `str \| None` | No | Detailed description of functionality |
| `annotations` | Various | No | Metadata annotations |

资料来源：[src/mcp/server/mcpserver/server.py:add_tool]() (method signature)

## Tool Name Validation

The SDK enforces strict rules for tool names to ensure compatibility across clients and servers. Validation is performed according to the SEP-986 specification.

### Validation Rules

| Rule | Requirement | Result on Violation |
|------|-------------|---------------------|
| Non-empty | Name must not be empty | `is_valid=False` |
| Length | Maximum 128 characters | `is_valid=False` |
| Pattern | Must match `TOOL_NAME_REGEX` | `is_valid=False` |
| Spaces | Warning only (not failure) | Warning appended |
| Commas | Warning only (not failure) | Warning appended |
| Leading/trailing dashes | Warning only (not failure) | Warning appended |
| Leading/trailing dots | Warning only (not failure) | Warning appended |

### Validation Function

The `validate_tool_name()` function returns a `ToolNameValidationResult` containing:

- `is_valid: bool` — Whether the name passes all mandatory checks
- `warnings: list[str]` — Non-fatal issues that may cause parsing problems

```python
def validate_tool_name(name: str) -> ToolNameValidationResult:
    warnings: list[str] = []
    
    if not name:
        return ToolNameValidationResult(is_valid=False, warnings=["Tool name cannot be empty"])
    
    if len(name) > 128:
        return ToolNameValidationResult(
            is_valid=False,
            warnings=[f"Tool name exceeds maximum length of 128 characters"]
        )
    
    if " " in name:
        warnings.append("Tool name contains spaces, which may cause parsing issues")
    
    # ... additional validation
```

资料来源：[src/mcp/shared/tool_name_validation.py:validate_tool_name]()

## Tool Manager

The `ToolManager` class handles storage, retrieval, and lifecycle management of registered tools.

### Core Responsibilities

| Responsibility | Description |
|----------------|-------------|
| Storage | Maintains internal registry of tool functions |
| Duplicate Detection | Warns when tools with same name are registered |
| Listing | Provides all registered tools on demand |
| Execution | Routes tool calls to registered functions |

### Manager Configuration

| Setting | Type | Default | Purpose |
|---------|------|---------|---------|
| `warn_on_duplicate_tools` | `bool` | `True` | Log warnings for duplicate registrations |

## Structured Output

The SDK provides mechanisms for returning structured data from tools and resources.

### CallToolResult

The standard result type for tool calls, containing:

```python
class CallToolResult(BaseModel):
    content: list[TextContent | ImageContent | EmbeddedResource]
    is_error: bool | None = None
```

### Content Types

| Type | Description |
|------|-------------|
| `TextContent` | Plain text output with MIME type |
| `ImageContent` | Binary image data with base64 encoding |
| `EmbeddedResource` | References to other resources |

### Structured Output Example

```python
@mcp.tool()
def get_user_info(user_id: str) -> CallToolResult:
    user = fetch_user(user_id)
    return CallToolResult(
        content=[
            TextContent(
                type="text",
                text=f"User: {user.name}\nEmail: {user.email}"
            )
        ]
    )
```

资料来源：[examples/snippets/servers/structured_output.py]()

## Error Handling

### Resource Errors

When reading resources fails, the server catches exceptions and converts them to `ResourceError`:

```python
async def read_resource(self, uri: AnyUrl | str, context: Context | None = None):
    try:
        resource = await self._resource_manager.get_resource(uri, context)
    except ValueError as exc:
        raise ResourceError(f"Unknown resource: {uri}") from exc
    
    try:
        content = await resource.read()
        return [ReadResourceContents(content=content, mime_type=resource.mime_type)]
    except Exception as exc:
        logger.exception(f"Error getting resource {uri}")
        raise ResourceError(f"Error reading resource {uri}") from exc
```

### Error Logging Guidelines

| Pattern | Usage |
|---------|-------|
| `logger.exception()` | Always use when catching exceptions (includes traceback) |
| `logger.error()` | Never use in exception handlers |
| Message format | `logger.exception("Failed")` not `logger.exception(f"Failed: {e}")` |

资料来源：[src/mcp/server/mcpserver/server.py:read_resource]() and [AGENTS.md:Exception Handling]()

## Resource Types

Resources provide structured data access alongside tools.

### FunctionResource

A resource backed by a callable function:

```python
@FunctionResource.from_function(
    uri="file://config/{env}",
    name="config_loader",
    title="Configuration Loader",
    description="Load configuration for specified environment",
    mime_type="application/json",
)
def load_config(env: str) -> dict:
    return {"environment": env, "debug": True}
```

### FileResource

A resource that reads directly from the filesystem:

```python
class FileResource(Resource):
    path: Path  # Must be absolute
    is_binary: bool = False
    mime_type: str = "text/plain"
```

| Field | Validation | Description |
|-------|------------|-------------|
| `path` | Must be absolute | Path to the file |
| `is_binary` | Auto-derived from MIME type | Whether to read as binary |
| `mime_type` | Default: `text/plain` | Content MIME type |

资料来源：[src/mcp/server/mcpserver/resources/types.py:FunctionResource]() and [src/mcp/server/mcpserver/resources/types.py:FileResource]()

## Direct Tool Result Handling

For advanced use cases, tools can return results directly without wrapping in `CallToolResult`:

```python
@mcp.tool()
def direct_result_tool(arg: str) -> str:
    """Return a string directly as tool output."""
    return f"Processed: {arg}"
```

The SDK automatically wraps primitive returns in appropriate content types.

资料来源：[examples/snippets/servers/direct_call_tool_result.py]()

## Tool Calling Workflow

```mermaid
sequenceDiagram
    participant Client
    participant MCPServer
    participant ToolManager
    participant ToolFunction
    
    Client->>MCPServer: list_tools()
    MCPServer->>ToolManager: list_tools()
    ToolManager-->>MCPServer: [Tool manifests]
    MCPServer-->>Client: Tool list
    
    Client->>MCPServer: call_tool(name, arguments)
    MCPServer->>ToolManager: get_tool(name)
    ToolManager->>ToolFunction: execute(arguments)
    ToolFunction-->>ToolManager: result
    ToolManager-->>MCPServer: CallToolResult
    MCPServer-->>Client: Result
```

## Best Practices

1. **Use descriptive names**: Tool names should clearly indicate their purpose
2. **Add docstrings**: All public tool functions should have documentation
3. **Handle errors gracefully**: Catch specific exceptions rather than using bare `except`
4. **Return structured data**: Prefer structured output over plain text when appropriate
5. **Validate inputs**: Use Pydantic models or similar for input validation
6. **Log appropriately**: Use `logger.exception()` in exception handlers

资料来源：[AGENTS.md:Code Quality]() and [AGENTS.md:Exception Handling]()

---

<a id='prompts'></a>

## Prompts and Templates

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Resources](#resources)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/mcpserver/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/server.py)
- [src/mcp/server/fastmcp/prompts/base.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/prompts/base.py)
- [src/mcp/server/fastmcp/prompts/manager.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/prompts/manager.py)
- [examples/snippets/servers/basic_prompt.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_prompt.py)
- [examples/servers/simple-prompt/mcp_simple_prompt/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-prompt/mcp_simple_prompt/server.py)
- [examples/servers/everything-server/mcp_everything_server/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/everything-server/mcp_everything_server/server.py)
</details>

# Prompts and Templates

## Overview

Prompts and Templates in the Model Context Protocol (MCP) SDK enable servers to expose reusable prompt configurations that clients can retrieve and use with dynamic arguments. This feature allows MCP servers to define structured, parameterized prompts that can include text content, embedded resources, and complex message structures.

The prompts system provides a declarative way to define prompt templates server-side, which clients can then consume through the MCP protocol's `get_prompt` and `list_prompts` operations.

## Architecture

### Core Components

```mermaid
graph TD
    A[Client] -->|list_prompts / get_prompt| B[MCPServer]
    B --> C[PromptManager]
    C --> D[Prompt Registry]
    D --> E[Prompt Instances]
    C --> F[PromptManager.get_prompt]
    F --> G[Prompt.render]
    G --> H[GetPromptResult]
    H --> A
    
    style A fill:#e1f5fe
    style B fill:#fff3e0
    style C fill:#e8f5e9
```

### Data Flow

```mermaid
sequenceDiagram
    participant Client
    participant MCPServer
    participant PromptManager
    participant Prompt
    participant Context

    Client->>MCPServer: list_prompts()
    MCPServer->>PromptManager: list_prompts()
    PromptManager-->>MCPServer: List[MCPPrompt]
    MCPServer-->>Client: Prompt metadata (name, description, arguments)

    Client->>MCPServer: get_prompt(name, arguments)
    MCPServer->>PromptManager: get_prompt(name)
    PromptManager->>Prompt: Find by name
    Prompt-->>PromptManager: Prompt instance
    PromptManager->>Prompt: render(arguments, context)
    Prompt-->>PromptManager: Rendered messages
    PromptManager-->>MCPServer: GetPromptResult
    MCPServer-->>Client: GetPromptResult with messages
```

## Prompt Registration

### Using the `@prompt()` Decorator

The primary way to register prompts is through the `@prompt()` decorator on the `MCPServer` instance.

```python
from mcp.server.mcpserver import MCPServer, Server
from mcp.types import UserMessage, TextContent

server = MCPServer(name="my-server")

@server.prompt()
def greeting() -> list[UserMessage]:
    """A simple greeting prompt."""
    return [
        UserMessage(
            role="user",
            content=TextContent(type="text", text="Hello! How can I assist you today?")
        )
    ]
```

资料来源：[src/mcp/server/mcpserver/server.py:1-300]()

### Prompt with Arguments

Prompts can accept arguments that are passed when the client requests the prompt:

```python
@server.prompt()
def personalized_greeting(name: str, context: str | None = None) -> list[UserMessage]:
    """A personalized greeting with optional context."""
    base_message = f"Hello, {name}!"
    if context:
        base_message += f"\n\nContext: {context}"
    
    return [
        UserMessage(
            role="user",
            content=TextContent(type="text", text=base_message)
        )
    ]
```

资料来源：[examples/servers/simple-prompt/mcp_simple_prompt/server.py:1-100]()

### Programmatic Registration

Alternatively, prompts can be added programmatically using the `add_prompt()` method:

```python
from mcp.types import Prompt, PromptArgument

prompt = Prompt(
    name="custom-prompt",
    description="A programmatically registered prompt",
    arguments=[
        PromptArgument(
            name="topic",
            description="The topic to discuss",
            required=True
        )
    ],
    # The handler is set via on_get_prompt callback
)
server.add_prompt(prompt)
```

## Prompt Manager

The `PromptManager` handles the internal storage and retrieval of prompts:

```python
class PromptManager:
    def __init__(self, warn_on_duplicate_prompts: bool = True) -> None:
        self._prompts: dict[str, Prompt] = {}
        self._warn_on_duplicate_prompts = warn_on_duplicate_prompts

    def add_prompt(self, prompt: Prompt) -> None:
        """Add a prompt to the manager."""
        ...

    def get_prompt(self, name: str) -> Prompt | None:
        """Get a prompt by name."""
        ...

    def list_prompts(self) -> list[Prompt]:
        """List all registered prompts."""
        ...
```

资料来源：[src/mcp/server/fastmcp/prompts/manager.py:1-100]()

### Manager Configuration

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `warn_on_duplicate_prompts` | `bool` | `True` | Whether to warn when adding a prompt with an existing name |

## Prompt Data Model

### MCPPrompt Structure

```python
@dataclass
class MCPPrompt:
    name: str                          # Unique identifier for the prompt
    description: str                  # Human-readable description
    arguments: list[MCPPromptArgument] # Parameter definitions
    icons: list[Icon] | None          # Optional icons
    annotations: Annotations | None    # Optional annotations
```

### MCPPromptArgument Structure

```python
@dataclass
class MCPPromptArgument:
    name: str         # Parameter name
    description: str # Human-readable description
    required: bool   # Whether the argument is mandatory
```

资料来源：[src/mcp/server/mcpserver/server.py:1-100]()

## Working with Resources in Prompts

Prompts can embed resources directly into the returned messages:

```python
from mcp.types import (
    UserMessage,
    TextContent,
    EmbeddedResource,
    TextResourceContents,
)

@server.prompt()
def prompt_with_resource(resource_uri: str) -> list[UserMessage]:
    """A prompt that includes an embedded resource."""
    return [
        UserMessage(
            role="user",
            content=EmbeddedResource(
                type="resource",
                resource=TextResourceContents(
                    uri=resource_uri,
                    mime_type="text/plain",
                    text="Embedded resource content for testing.",
                ),
            ),
        ),
        UserMessage(
            role="user",
            content=TextContent(
                type="text",
                text="Please process the embedded resource above."
            )
        ),
    ]
```

资料来源：[examples/servers/everything-server/mcp_everything_server/server.py:1-200]()

## Image Content in Prompts

Prompts can include image content using `ImageContent`:

```python
from mcp.types import UserMessage, ImageContent

TEST_IMAGE_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="

@server.prompt()
def prompt_with_image() -> list[UserMessage]:
    """A prompt that includes image content."""
    return [
        UserMessage(
            role="user",
            content=ImageContent(
                type="image",
                data=TEST_IMAGE_BASE64,
                mime_type="image/png"
            )
        ),
        UserMessage(
            role="user",
            content=TextContent(type="text", text="Please analyze the image above.")
        ),
    ]
```

资料来源：[examples/servers/everything-server/mcp_everything_server/server.py:1-200]()

## Server-Side Prompt Handlers

### Manual Handler Implementation

For more control, you can implement prompt handlers manually using the low-level `Server` class:

```python
import types
from mcp.server import Server, ServerRequestContext

async def handle_list_prompts(
    ctx: ServerRequestContext, 
    params: types.ListPromptsRequestParams
) -> types.ListPromptsResult:
    """List all available prompts."""
    return types.ListPromptsResult(
        prompts=[
            types.Prompt(
                name="simple",
                description="A simple prompt with optional arguments",
                arguments=[
                    types.PromptArgument(
                        name="context",
                        description="Additional context to consider",
                        required=False,
                    ),
                    types.PromptArgument(
                        name="topic",
                        description="Specific topic to focus on",
                        required=False,
                    ),
                ],
            )
        ]
    )

async def handle_get_prompt(
    ctx: ServerRequestContext, 
    params: types.GetPromptRequestParams
) -> types.GetPromptResult:
    """Get a specific prompt with arguments."""
    if params.name != "simple":
        raise ValueError(f"Unknown prompt: {params.name}")

    arguments = params.arguments or {}

    return types.GetPromptResult(
        messages=create_messages(
            context=arguments.get("context"),
            topic=arguments.get("topic")
        ),
        description="A simple prompt with optional context and topic arguments",
    )

# Create server with handlers
app = Server(
    "mcp-simple-prompt",
    on_list_prompts=handle_list_prompts,
    on_get_prompt=handle_get_prompt,
)
```

资料来源：[examples/servers/simple-prompt/mcp_simple_prompt/server.py:1-100]()

## API Reference

### MCPServer Methods

| Method | Parameters | Return Type | Description |
|--------|------------|-------------|-------------|
| `prompt()` | `name`, `title`, `description`, `icons` | `Callable[[F], F]` | Decorator to register a prompt function |
| `add_prompt()` | `prompt: Prompt` | `None` | Add a Prompt instance directly |
| `list_prompts()` | - | `list[MCPPrompt]` | List all registered prompts |
| `get_prompt()` | `name`, `arguments`, `context` | `GetPromptResult` | Get and render a prompt |

### GetPromptResult

```python
@dataclass
class GetPromptResult:
    description: str                    # Prompt description
    messages: list[BaseMessage | dict]  # Rendered message content
```

## Context Integration

Prompts can access server context for dynamic rendering:

```python
async def get_prompt(
    self, 
    name: str, 
    arguments: dict[str, Any] | None = None, 
    context: Context[LifespanResultT, Any] | None = None
) -> GetPromptResult:
    """Get a prompt by name with arguments."""
    if context is None:
        context = Context(mcp_server=self)
    
    try:
        prompt = self._prompt_manager.get_prompt(name)
        if not prompt:
            raise ValueError(f"Unknown prompt: {name}")

        messages = await prompt.render(arguments, context)

        return GetPromptResult(
            description=prompt.description,
            messages=pydantic_core.to_jsonable_python(messages),
        )
    except Exception as e:
        logger.exception(f"Error getting prompt {name}")
        raise ValueError(str(e)) from e
```

资料来源：[src/mcp/server/mcpserver/server.py:1-100]()

## Error Handling

The prompt system handles errors gracefully:

```mermaid
graph TD
    A[get_prompt request] --> B{Prompt found?}
    B -->|No| C[ValueError: Unknown prompt]
    B -->|Yes| D[Render prompt]
    D --> E{Render successful?}
    E -->|No| F[Log exception]
    E -->|Yes| G[Return GetPromptResult]
    F --> H[ResourceError to client]
    
    style C fill:#ffcdd2
    style H fill:#ffcdd2
    style G fill:#c8e6c9
```

Errors during prompt retrieval are logged and converted to user-friendly `ValueError` or `ResourceError` exceptions.

## Best Practices

1. **Provide clear argument descriptions**: Document each parameter's purpose in the `PromptArgument.description` field.

2. **Mark required arguments appropriately**: Set `required=True` for mandatory parameters to help clients validate input.

3. **Use consistent naming**: Follow snake_case for prompt and argument names for consistency with Python conventions.

4. **Handle missing arguments gracefully**: When arguments are optional, provide sensible defaults in your render logic.

5. **Include embedded resources carefully**: Only include resources that are relevant to the prompt's purpose to minimize payload size.

## Summary

The Prompts and Templates system in MCP provides a flexible mechanism for servers to expose reusable, parameterized prompt configurations. Through the `@prompt()` decorator, programmatic `add_prompt()` method, or manual handler implementation, developers can define prompts that support:

- Static text content
- Dynamic arguments
- Embedded resources
- Image and multimedia content
- Context-aware rendering

This abstraction enables clean separation between prompt definition and execution, making it easy to maintain and version prompt templates within the MCP server codebase.

---

<a id='context-session'></a>

## Context and Session Management

### 相关页面

相关主题：[FastMCP Server Development](#fastmcp-server), [Server Lifecycle and Context Management](#server-lifecycle)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/fastmcp/__init__.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/fastmcp/__init__.py)
- [src/mcp/server/session.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/session.py)
- [src/mcp/shared/session.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/shared/session.py)
- [examples/snippets/servers/tool_progress.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/tool_progress.py)
- [examples/snippets/servers/elicitation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/elicitation.py)
</details>

# Context and Session Management

## Overview

Context and Session Management form the foundational communication layer in the MCP Python SDK. The SDK provides a layered architecture where sessions encapsulate client-server communication and contexts propagate request-scoped information through the handler chain. Sessions handle the underlying transport and protocol mechanics, while contexts provide a convenient interface for servers to access request metadata, respond to clients, and coordinate complex workflows like task elicitation and sampling.

## Architecture Overview

```mermaid
graph TB
    subgraph "Client Layer"
        Client[MCP Client]
    end
    
    subgraph "Server Layer"
        MCPServer[MCPServer]
        FastMCP[FastMCP]
    end
    
    subgraph "Session Layer"
        ServerSession[ServerSession<br/>src/mcp/server/session.py]
        SharedSession[SharedSession<br/>src/mcp/shared/session.py]
    end
    
    subgraph "Context Layer"
        Context[Context<br/>Request Context]
        TaskContext[TaskContext<br/>Task Execution Context]
    end
    
    Client <-->|Transport| ServerSession
    MCPServer --> ServerSession
    FastMCP --> ServerSession
    ServerSession --> SharedSession
    SharedSession --> Context
    Context --> TaskContext
```

## Session Management

### Session Types

The SDK implements two primary session classes that work together to provide the complete MCP communication interface.

| Session Type | Location | Purpose |
|-------------|----------|---------|
| `ServerSession` | `src/mcp/server/session.py` | Server-side session managing protocol handlers and request routing |
| `SharedSession` | `src/mcp/shared/session.py` | Shared session state for cross-request data and message handling |

### ServerSession

The `ServerSession` class is the primary interface servers use to interact with clients. It manages the protocol lifecycle, handles request/response routing, and provides methods for sending notifications and responses.

**Key Responsibilities:**

- Route incoming requests to appropriate handlers
- Send responses and notifications back to clients
- Manage request/response correlations via request IDs
- Handle protocol-level operations like initialization

**Core Methods:**

```python
class ServerSession:
    """Server-side session for MCP protocol communication."""
    
    async def send_response(self, request_id: RequestId, response: Any) -> None:
        """Send a response to a specific request."""
        
    async def send_notification(self, method: str, params: Any) -> None:
        """Send a notification without expecting a response."""
        
    async def request(self, method: str, params: Any) -> Any:
        """Send a request to the client and wait for response."""
```

### SharedSession

The `SharedSession` provides the underlying message queue and state management that both client and server sessions rely upon. It implements the request/resolver pattern for correlating messages.

```mermaid
sequenceDiagram
    participant Server as ServerSession
    participant Shared as SharedSession
    participant Queue as MessageQueue
    participant Resolver as Resolver
    
    Server->>Shared: _build_request(messages, params)
    Shared->>Queue: enqueue(request)
    Shared->>Resolver: Create resolver for request_id
    Queue-->>Shared: Acknowledged
    Shared-->>Server: Queued message
    
    Note over Server,Resolver: Waiting for response...
    
    Resolver->>Server: response_data
```

### Session Initialization

Sessions are initialized during the server's lifespan and injected into the request context chain:

```python
# src/mcp/server/mcpserver/server.py
async def read_resource(
    self, uri: AnyUrl | str, context: Context[LifespanResultT, Any] | None = None
) -> Iterable[ReadResourceContents]:
    """Read a resource by URI."""
    if context is None:
        context = Context(mcp_server=self)
    # ...
```

## Context Management

### Context Class

The `Context` class provides request-scoped access to server functionality. It wraps a session and server reference, exposing typed methods for common operations.

```python
class Context(Generic[LifespanResultT, SessionT]):
    """Request context providing access to server and session functionality."""
    
    def __init__(
        self,
        mcp_server: McpServer[LifespanResultT] | None = None,
        session: SessionT | None = None,
        request_id: RequestId | None = None,
        session_id: str | None = None,
    ):
        self._mcp_server = mcp_server
        self._session = session
        self._request_id = request_id
        self._session_id = session_id
```

### Context Request Flow

```mermaid
graph LR
    A[Incoming Request] --> B[ServerSession]
    B --> C[Create Context]
    C --> D[Handler with Context]
    D --> E[Business Logic]
    E --> F[ctx.session.send_response]
    F --> G[Client Response]
```

### Context Methods

The `Context` class exposes several key methods for server handlers:

| Method | Purpose | Return Type |
|--------|---------|-------------|
| `request` | Send a request to the client | `Awaitable[Any]` |
| `session` | Access the underlying session | `SessionT` |
| `mcp_server` | Access the MCP server instance | `McpServer` |

**Example Usage in Handlers:**

```python
# src/mcp/server/mcpserver/server.py
async def read_resource(
    self, uri: AnyUrl | str, context: Context[LifespanResultT, Any] | None = None
) -> Iterable[ReadResourceContents]:
    """Read a resource by URI."""
    if context is None:
        context = Context(mcp_server=self)
    try:
        resource = await self._resource_manager.get_resource(uri, context)
    except ValueError as exc:
        raise ResourceError(f"Unknown resource: {uri}") from exc
```

## Task Context

The `TaskContext` class (in `src/mcp/server/experimental/task_context.py`) extends the base context for task-based operations, enabling complex workflows like elicitation and sampling.

```mermaid
graph TD
    TC[TaskContext] --> C[Context]
    TC --> QM[Queue Management]
    TC --> EP[Elicitation Provider]
    TC --> SP[Sampling Provider]
    
    EP --> ER[ElicitResult]
    SP --> CM[CreateMessageResult]
```

### TaskContext Creation

Tasks are created with an associated context that manages the lifecycle:

```python
# src/mcp/server/experimental/task_context.py
async def create_task_with_context(
    self,
    messages: list[types.BaseMessage],
    task_metadata: TaskMetadata | None = None,
    ttl: int | None = None,
) -> tuple[TaskContext, CreateTaskResult]:
```

### Task Request Building

Task contexts build requests with special task metadata for task-augmented sampling:

```python
# src/mcp/server/experimental/task_context.py
# Build request WITH task field for task-augmented sampling
request = self._session._build_create_message_request(
    messages=messages,
    max_tokens=max_tokens,
    system_prompt=system_prompt,
    include_context=include_context,
    temperature=temperature,
    stop_sequences=stop_sequences,
    metadata=metadata,
    model_preferences=model_preferences,
    tools=tools,
    tool_choice=tool_choice,
    related_task_id=self.task_id,
    task=TaskMetadata(ttl=ttl),
)
```

## Elicitation Pattern

Elicitation allows servers to request input from users through the client. This pattern is essential for interactive workflows requiring human confirmation or input.

### Elicitation Flow

```mermaid
sequenceDiagram
    participant Server
    participant Session
    participant Client
    participant User
    
    Server->>Session: task.elicit(params)
    Session->>Client: elicitation request
    Client->>User: Prompt for input
    User-->>Client: User response
    Client->>Session: ElicitResult
    Session-->>Server: Elicitation response
```

### Elicitation Implementation

The elicitation callback pattern enables servers to request user input:

```python
# examples/snippets/servers/elicitation.py
async def elicitation_callback(context, params) -> ElicitResult:
    """Handle elicitation requests from the server."""
    # params contains the elicitation request details
    # Return user decision
    return ElicitResult(action="accept", content={"confirm": True})
```

### Elicitation in Interactive Tasks

The interactive task example demonstrates the complete elicitation flow:

```python
# examples/servers/simple-task-interactive/server.py
async def handle_confirm_delete(ctx: ServerRequestContext, params):
    # Request user confirmation via elicitation
    result = await ctx.request(
        "SamplingMessage",
        {
            "method": "elicitation",
            "params": {
                "message": {
                    "role": "user",
                    "content": {
                        "type": "text",
                        "text": f"Confirm delete of '{params.arguments['file_name']}'?"
                    }
                }
            }
        }
    )
```

## Sampling Pattern

Sampling enables servers to request LLM completions from the client. This is useful for servers that need AI capabilities but delegate the actual model execution to the client.

### Sampling Flow

```mermaid
sequenceDiagram
    participant Server
    participant Session
    participant Client
    participant LLM
    
    Server->>Session: task.create_message(messages)
    Session->>Client: sampling request
    Client->>LLM: Request completion
    LLM-->>Client: Completion
    Client->>Session: CreateMessageResult
    Session-->>Server: Sampling response
```

### Sampling Implementation

```python
# examples/snippets/servers/tool_progress.py
async def sampling_callback(context, params) -> CreateMessageResult:
    """Handle sampling requests from the server."""
    return CreateMessageResult(
        model="gpt-4",
        role="assistant",
        content=[types.TextContent(type="text", text="Generated response")]
    )
```

## Tool Progress Reporting

Sessions support progress reporting for long-running operations, allowing servers to send status updates during task execution.

```python
# examples/snippets/servers/tool_progress.py
async def handle_long_running_task(ctx: ServerRequestContext, params):
    """Handle a long-running task with progress updates."""
    
    # Initialize task
    task = await ctx.session.experimental.create_task(
        messages=[],
        task_metadata=TaskMetadata(name="long_running_task")
    )
    
    # Send progress updates
    for i in range(5):
        await task.send_progress(
            total=5,
            current=i + 1,
            message=f"Processing step {i + 1}..."
        )
```

### Progress Notification Flow

```mermaid
graph TD
    A[Start Task] --> B[Execute Step 1]
    B --> C[Send Progress]
    C --> D[Execute Step 2]
    D --> E[Send Progress]
    E --> F[Complete Task]
```

## Session Request Correlation

The SDK uses a resolver pattern to correlate requests and responses across the transport layer.

```mermaid
graph LR
    A[Request ID] --> B[Resolver Map]
    B --> C[Pending Request]
    C --> D[Response Received]
    D --> E[Resolve Value]
    E --> F[Awaiter Notified]
```

### Request Lifecycle

```python
# src/mcp/shared/session.py
class Resolver(Generic[T]):
    """Resolver for correlating request/response pairs."""
    
    def __init__(self):
        self._value: T | None = None
        self._event = anyio.create_event()
    
    def resolve(self, value: T) -> None:
        """Resolve the request with a value."""
        self._value = value
        self._event.set()
    
    async def wait(self) -> T:
        """Wait for and return the resolved value."""
        await self._event.wait()
        return self._value
```

## Error Handling

Context and session operations should handle errors gracefully using the logging patterns specified in the SDK guidelines.

```python
# src/mcp/server/mcpserver/server.py
try:
    content = await resource.read()
    return [ReadResourceContents(content=content, mime_type=resource.mime_type, meta=resource.meta)]
except Exception as exc:
    logger.exception(f"Error getting resource {uri}")
    # If an exception happens when reading the resource, we should not leak the exception to the client.
    raise ResourceError(f"Error reading resource {uri}") from exc
```

## Best Practices

### Context Usage

1. **Always use `logger.exception()` instead of `logger.error()` when catching exceptions**
   - Never include the exception in the message manually

2. **Catch specific exceptions where possible**
   ```python
   except (OSError, PermissionError):
       # Handle file operation errors
   except json.JSONDecodeError:
       # Handle JSON parsing errors
   ```

3. **Never use bare `except Exception:`** - unless in top-level handlers

### Session Management

1. Sessions are created during the server lifespan and should not be instantiated directly
2. Use the context's session reference rather than storing session references
3. For task operations, use `session.experimental` methods

### Task Context

1. Always provide TTL for long-running tasks
2. Use polling with `poll_task()` for task status monitoring
3. Handle cancellation via `anyio.get_cancelled_exc_class()`

## Related Components

| Component | File | Purpose |
|-----------|------|---------|
| MCPServer | `src/mcp/server/mcpserver/server.py` | Main server class that creates and manages sessions |
| FastMCP | `src/mcp/server/fastmcp/__init__.py` | High-level API layer built on top of sessions |
| ServerSession | `src/mcp/server/session.py` | Protocol-level session implementation |
| SharedSession | `src/mcp/shared/session.py` | Shared state and message handling |
| TaskContext | `src/mcp/server/experimental/task_context.py` | Task-scoped context for complex workflows |

## Summary

The MCP SDK's Context and Session Management system provides a robust foundation for server-client communication. Sessions handle the transport and protocol mechanics, while contexts provide a developer-friendly interface for request-scoped operations. The task and elicitation patterns built on this foundation enable sophisticated interactive workflows where servers can request user input and LLM completions through a well-defined callback mechanism.

---

<a id='transports'></a>

## Transports Overview

### 相关页面

相关主题：[Low-Level Server Development](#low-level-server)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/mcp/server/mcpserver/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/server/mcpserver/server.py)
- [examples/servers/simple-pagination/mcp_simple_pagination/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-pagination/mcp_simple_pagination/server.py)
- [examples/servers/simple-prompt/mcp_simple_prompt/server.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-prompt/mcp_simple_prompt/server.py)
- [examples/snippets/clients/stdio_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/stdio_client.py)
- [examples/servers/simple-task-interactive/README.md](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/servers/simple-task-interactive/README.md)
- [src/mcp/cli/cli.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/src/mcp/cli/cli.py)
</details>

# Transports Overview

## Introduction

The Model Context Protocol (MCP) SDK supports multiple transport mechanisms for communication between clients and servers. Transports define how JSON-RPC messages are transmitted between the MCP client and server, providing abstraction over different communication paradigms.

The SDK provides two primary transport types:

| Transport Type | Use Case | Direction |
|---------------|----------|-----------|
| **stdio** | Local, CLI-based communication | Bidirectional |
| **streamable-http** | Remote, HTTP-based communication | Bidirectional with polling |

资料来源：[examples/servers/simple-pagination/mcp_simple_pagination/server.py:49-57]()

## Architecture

### Transport Layer Position

MCP follows a layered architecture where transports sit at the communication layer:

```mermaid
graph TD
    A[MCP Client] --> B[Transport Layer]
    C[MCP Server] --> D[Transport Layer]
    B <-->|stdio / HTTP| D
    
    E[Application Layer] --> B
    D --> F[Business Logic]
```

### Message Flow

All transports implement the same message protocol, enabling interoperability:

```mermaid
sequenceDiagram
    participant C as Client
    participant T as Transport
    participant S as Server
    
    C->>T: Initialize
    T->>S: JSON-RPC Request
    S->>T: JSON-RPC Response
    T->>C: Result
```

## Stdio Transport

### Overview

The stdio transport uses standard input and standard output streams for communication. This is ideal for local processes, command-line tools, and desktop application integrations.

资料来源：[examples/snippets/clients/stdio_client.py]()

### Server Implementation

```python
from mcp.server.stdio import stdio_server

async def arun():
    async with stdio_server() as streams:
        await app.run(streams[0], streams[1], app.create_initialization_options())

anyio.run(arun)
```

资料来源：[examples/servers/simple-pagination/mcp_simple_pagination/server.py:61-65]()

### Client Implementation

```python
from mcp.client.stdio import StdioServerParameters, stdio_client

async def run():
    params = StdioServerParameters(
        command="python",
        args=["server.py"],
        env={"key": "value"}
    )
    async with stdio_client(params) as client:
        # Use client...
```

资料来源：[examples/snippets/clients/stdio_client.py]()

### StdioServerParameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `command` | `str` | Yes | Executable command |
| `args` | `list[str]` | No | Command arguments |
| `env` | `dict[str, str]` | No | Environment variables |
| `cwd` | `str` | No | Working directory |

## Streamable HTTP Transport

### Overview

The streamable-http transport uses HTTP POST requests for sending messages and Server-Sent Events (SSE) or chunked transfer for receiving responses. This supports remote server deployments and web integrations.

资料来源：[examples/servers/simple-pagination/mcp_simple_pagination/server.py:54-56]()

### Server Implementation

```python
import uvicorn

if transport == "streamable-http":
    uvicorn.run(app.streamable_http_app(), host="127.0.0.1", port=port)
```

资料来源：[examples/servers/simple-pagination/mcp_simple_pagination/server.py:54-56]()

### Server Options

The `streamable_http_app()` method supports the following configuration:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `app` | `Server` | Required | MCP Server instance |
| `app_path` | `str` | `"/mcp"` | HTTP endpoint path |
| `cors_domains` | `list[str]` | `[]` | Allowed CORS origins |
| `max_request_size` | `int` | `16777216` | Max request body size |
| `write_timeout` | `float` | `30.0` | SSE write timeout |
| `heartbeat` | `float` | `None` | Heartbeat interval |

资料来源：[src/mcp/server/mcpserver/server.py]()

### HTTP Endpoint Configuration

```python
app = Server("mcp-simple-pagination", ...)
http_app = app.streamable_http_app(
    app_path="/custom-path",
    cors_domains=["https://example.com"],
    heartbeat=30.0
)
uvicorn.run(http_app, host="127.0.0.1", port=8000)
```

## Client Configuration

### Environment Variables

The SDK supports configuration via environment variables for HTTP transport:

| Variable | Default | Description |
|----------|---------|-------------|
| `MCP_SERVER_PORT` | `8000` | Port number |
| `MCP_TRANSPORT_TYPE` | `streamable-http` | Transport type |
| `MCP_CLIENT_METADATA_URL` | `None` | Optional CIMD URL |

资料来源：[examples/clients/simple-auth-client/README.md]()

### Transport Selection

```python
# stdio transport
transport = "stdio"
async with stdio_server() as streams:
    await app.run(streams[0], streams[1], app.create_initialization_options())

# HTTP transport
transport = "streamable-http"
uvicorn.run(app.streamable_http_app(), host="127.0.0.1", port=port)
```

资料来源：[examples/servers/simple-prompt/mcp_simple_prompt/server.py:52-65]()

## Stream Protocol

### Message Framing

Both transports use the MCP stream protocol for message encoding:

```mermaid
graph LR
    A[Application Data] --> B[JSON-RPC 2.0]
    B --> C[Content-Length Header]
    C --> D[Raw Bytes]
```

### Protocol Requirements

- Messages are JSON-RPC 2.0 compliant
- HTTP transport uses `Content-Length` header for framing
- Stdio transport uses line-delimited JSON with content length prefix

## Transport Selection Guide

| Scenario | Recommended Transport | Reason |
|----------|----------------------|--------|
| CLI tools | stdio | Simple, local process |
| Desktop apps | stdio | Secure, isolated |
| Web applications | streamable-http | HTTP-native |
| Microservices | streamable-http | Network-friendly |
| Testing | stdio | Fast, deterministic |

## CLI Integration

The MCP CLI tool supports installing servers with transport configuration:

```bash
mcp install server.py --name "my-server"
```

资料来源：[src/mcp/cli/cli.py]()

Environment variables specified during installation are preserved and can be used for transport configuration.

## Best Practices

1. **Security**: Use stdio for local, trusted connections; use HTTPS for streamable-http in production
2. **Error Handling**: Always wrap transport initialization in try-except blocks
3. **Timeouts**: Configure appropriate timeouts for HTTP transport
4. **Resource Cleanup**: Use async context managers to ensure proper resource disposal
5. **CORS**: Restrict `cors_domains` when deploying HTTP servers

## Example: Dual Transport Server

```python
import click
import uvicorn
from mcp.server.stdio import stdio_server
from mcp.server.mcpserver import MCPServer

app = MCPServer(name="dual-transport-server", ...)

@click.command()
@click.option("--transport", type=click.Choice(["stdio", "streamable-http"]), default="stdio")
@click.option("--port", default=8000)
def main(transport: str, port: int):
    if transport == "streamable-http":
        uvicorn.run(app.streamable_http_app(), host="0.0.0.0", port=port)
    else:
        async def run():
            async with stdio_server() as streams:
                await app.run(streams[0], streams[1], app.create_initialization_options())
        anyio.run(run)
```

This pattern allows a single server implementation to serve both transport types based on deployment requirements.

---

---

## Doramagic Pitfall Log

Project: modelcontextprotocol/python-sdk

Summary: Found 38 potential pitfall items; 8 are high/blocking. Highest priority: configuration - 来源证据：Duplicate `initialize` with changed parameters can overwrite `ServerSession.client_params`.

## 1. configuration · 来源证据：Duplicate `initialize` with changed parameters can overwrite `ServerSession.client_params`

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Duplicate `initialize` with changed parameters can overwrite `ServerSession.client_params`
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_fbd28a768e3d4de5b6350068d5f755e6 | https://github.com/modelcontextprotocol/python-sdk/issues/2605 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 2. configuration · 来源证据：Streamable HTTP server silently drops in-flight request when client reuses a JSON-RPC id

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Streamable HTTP server silently drops in-flight request when client reuses a JSON-RPC id
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_4ac932bd22b544cdb3fd360948cea40a | https://github.com/modelcontextprotocol/python-sdk/issues/2655 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 3. configuration · 来源证据：streamable_http_client: one concurrent request HTTPStatusError tears down sibling requests

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：streamable_http_client: one concurrent request HTTPStatusError tears down sibling requests
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_eea700d7503c4f4aa8ee4dcbd3db4591 | https://github.com/modelcontextprotocol/python-sdk/issues/2604 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 4. maintenance · 来源证据：FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax
- User impact: 可能阻塞安装或首次运行。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_a8726c44efdb4ae880d844a7d492b1e9 | https://github.com/modelcontextprotocol/python-sdk/issues/2591 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 5. security_permissions · 来源证据：Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O
- User impact: 可能影响授权、密钥配置或安全边界。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_8f0ce3f22c2e45b9af5ad37292daba8b | https://github.com/modelcontextprotocol/python-sdk/issues/1305 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 6. security_permissions · 来源证据：Progress notifications cause server to hang on stdio transport

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Progress notifications cause server to hang on stdio transport
- User impact: 可能阻塞安装或首次运行。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_ed924e0ca71b419381464d8c25d237ef | https://github.com/modelcontextprotocol/python-sdk/issues/1141 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 7. security_permissions · 来源证据：Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVersion` on `initialize`

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVersion` on `initialize`
- User impact: 可能影响授权、密钥配置或安全边界。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_84eac7ce86a345c38a09308517763962 | https://github.com/modelcontextprotocol/python-sdk/issues/2618 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 8. security_permissions · 来源证据：User-Agent header in sHTTP transport is not forwarded to auth flow

- Severity: high
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：User-Agent header in sHTTP transport is not forwarded to auth flow
- User impact: 可能影响授权、密钥配置或安全边界。
- Suggested check: 来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_824f98c734544a28b3bfd8e982425150 | https://github.com/modelcontextprotocol/python-sdk/issues/1664 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 9. installation · 失败模式：installation: Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-t...

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-task generator driving
- User impact: Developers may fail before the first successful local run: Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-task generator driving
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-task generator driving. Context: Observed when using windows
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_7ab763a43233ec1e7dcaebc3255017a6 | https://github.com/modelcontextprotocol/python-sdk/issues/2644 | Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-task generator driving

## 10. installation · 失败模式：installation: FastMCP.__init__ clobbers root logger with INFO RichHandler — hangs stdio servers under back-...

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: FastMCP.__init__ clobbers root logger with INFO RichHandler — hangs stdio servers under back-pressure
- User impact: Developers may fail before the first successful local run: FastMCP.__init__ clobbers root logger with INFO RichHandler — hangs stdio servers under back-pressure
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: FastMCP.__init__ clobbers root logger with INFO RichHandler — hangs stdio servers under back-pressure. Context: Observed when using node, python, macos
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_4529ab733a6558a19e9c3f318ce112c5 | https://github.com/modelcontextprotocol/python-sdk/issues/2527 | FastMCP.__init__ clobbers root logger with INFO RichHandler — hangs stdio servers under back-pressure

## 11. installation · 失败模式：installation: Types-only install option

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this installation risk before relying on the project: Types-only install option
- User impact: Developers may fail before the first successful local run: Types-only install option
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Types-only install option. Context: Observed during installation or first-run setup.
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_4b31523e85ae0860236ec672488b4035 | https://github.com/modelcontextprotocol/python-sdk/issues/2581 | Types-only install option

## 12. configuration · 失败模式：configuration: Add `invalid_target` to `AuthorizationErrorCode` (RFC 8707)

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Add `invalid_target` to `AuthorizationErrorCode` (RFC 8707)
- User impact: Developers may misconfigure credentials, environment, or host setup: Add `invalid_target` to `AuthorizationErrorCode` (RFC 8707)
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Add `invalid_target` to `AuthorizationErrorCode` (RFC 8707). Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_4c29698ade9229f6578bf641e5ca4aec | https://github.com/modelcontextprotocol/python-sdk/issues/2641 | Add `invalid_target` to `AuthorizationErrorCode` (RFC 8707), failure_mode_cluster:github_issue | fmev_81c61c3640860f857e3b46c6f8531177 | https://github.com/modelcontextprotocol/python-sdk/issues/2641 | Add `invalid_target` to `AuthorizationErrorCode` (RFC 8707)

## 13. configuration · 失败模式：configuration: Add dereference helper for tool inputSchema with nested Pydantic models

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Add dereference helper for tool inputSchema with nested Pydantic models
- User impact: Developers may misconfigure credentials, environment, or host setup: Add dereference helper for tool inputSchema with nested Pydantic models
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Add dereference helper for tool inputSchema with nested Pydantic models. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_b2ce8b41d7d1313880fbc1d46aab3d74 | https://github.com/modelcontextprotocol/python-sdk/issues/2586 | Add dereference helper for tool inputSchema with nested Pydantic models

## 14. configuration · 失败模式：configuration: Claude Code client sends tools/call without initialize handshake — SSE transport rejects with...

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Claude Code client sends tools/call without initialize handshake — SSE transport rejects with -32602
- User impact: Developers may misconfigure credentials, environment, or host setup: Claude Code client sends tools/call without initialize handshake — SSE transport rejects with -32602
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Claude Code client sends tools/call without initialize handshake — SSE transport rejects with -32602. Context: Observed when using python, linux
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_884755d92c4ee7ff54d4b4708f39069f | https://github.com/modelcontextprotocol/python-sdk/issues/2579 | Claude Code client sends tools/call without initialize handshake — SSE transport rejects with -32602

## 15. configuration · 失败模式：configuration: Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O
- User impact: Developers may misconfigure credentials, environment, or host setup: Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O. Context: Source discussion did not expose a precise runtime context.
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_c27e12906c0f7d454244f8102a06ef49 | https://github.com/modelcontextprotocol/python-sdk/issues/1305 | Feature Proposal: Secure Tool/Resource/Prompt Decorators with Auth + Encrypted I/O

## 16. configuration · 失败模式：configuration: MCP client does not retry authenticated request after successful OAuth token exchange

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: MCP client does not retry authenticated request after successful OAuth token exchange
- User impact: Developers may misconfigure credentials, environment, or host setup: MCP client does not retry authenticated request after successful OAuth token exchange
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: MCP client does not retry authenticated request after successful OAuth token exchange. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_de3aa46bd21d5cae2ad94a4a536299c9 | https://github.com/modelcontextprotocol/python-sdk/issues/2577 | MCP client does not retry authenticated request after successful OAuth token exchange

## 17. configuration · 失败模式：configuration: OAuth token refresh sends RFC 8707 resource parameter that Entra ID v2.0 rejects (AADSTS9010010)

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: OAuth token refresh sends RFC 8707 resource parameter that Entra ID v2.0 rejects (AADSTS9010010)
- User impact: Developers may misconfigure credentials, environment, or host setup: OAuth token refresh sends RFC 8707 resource parameter that Entra ID v2.0 rejects (AADSTS9010010)
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: OAuth token refresh sends RFC 8707 resource parameter that Entra ID v2.0 rejects (AADSTS9010010). Context: Observed when using python, docker
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_07b495ad5a45da97ecc1b984b9300cce | https://github.com/modelcontextprotocol/python-sdk/issues/2578 | OAuth token refresh sends RFC 8707 resource parameter that Entra ID v2.0 rejects (AADSTS9010010)

## 18. configuration · 失败模式：configuration: SSE transport: "Received request before initialization was complete" error with Claude Code c...

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: SSE transport: "Received request before initialization was complete" error with Claude Code client
- User impact: Developers may misconfigure credentials, environment, or host setup: SSE transport: "Received request before initialization was complete" error with Claude Code client
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: SSE transport: "Received request before initialization was complete" error with Claude Code client. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_31027dd837c7b2629b64e0af3be9fc95 | https://github.com/modelcontextprotocol/python-sdk/issues/1844 | SSE transport: "Received request before initialization was complete" error with Claude Code client

## 19. configuration · 失败模式：configuration: Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVer...

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVersion` on `initialize`
- User impact: Developers may misconfigure credentials, environment, or host setup: Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVersion` on `initialize`
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVersion` on `initialize`. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_0d875956519d754739d2f47b361a05c1 | https://github.com/modelcontextprotocol/python-sdk/issues/2618 | Streamable HTTP server accepts mismatched `MCP-Protocol-Version` header and body `protocolVersion` on `initialize`

## 20. configuration · 失败模式：configuration: Trying to connect to a MCP url got the follwing error any idea why ?

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this configuration risk before relying on the project: Trying to connect to a MCP url got the follwing error any idea why ?
- User impact: Developers may misconfigure credentials, environment, or host setup: Trying to connect to a MCP url got the follwing error any idea why ?
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Trying to connect to a MCP url got the follwing error any idea why ?. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_9523da384e29bdf69864713f37e5176a | https://github.com/modelcontextprotocol/python-sdk/issues/2517 | Trying to connect to a MCP url got the follwing error any idea why ?

## 21. configuration · 来源证据：Agents talking to MCP Server, SSL verification is failing. Has some been through this?

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Agents talking to MCP Server, SSL verification is failing. Has some been through this?
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_914631b4623b42b58a37f604428d3bc8 | https://github.com/modelcontextprotocol/python-sdk/issues/1628 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 22. configuration · 来源证据：Trying to connect to a MCP url got the follwing error any idea why ?

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：Trying to connect to a MCP url got the follwing error any idea why ?
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_a547a9416bda42e09bfdb76cb30cebd3 | https://github.com/modelcontextprotocol/python-sdk/issues/2517 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 23. configuration · 来源证据：how to return images from an mcp server

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个配置相关的待验证问题：how to return images from an mcp server
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_f045f1b17f2840588e0043d2c23b26be | https://github.com/modelcontextprotocol/python-sdk/issues/2557 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 24. capability · 能力判断依赖假设

- Severity: medium
- Evidence strength: source_linked
- Finding: README/documentation is current enough for a first validation pass.
- User impact: 假设不成立时，用户拿不到承诺的能力。
- Suggested check: 将假设转成下游验证清单。
- Guardrail action: 假设必须转成验证项；没有验证结果前不能写成事实。
- Evidence: capability.assumptions | github_repo:862584018 | https://github.com/modelcontextprotocol/python-sdk | README/documentation is current enough for a first validation pass.

## 25. runtime · 失败模式：runtime: Allow explicit `message_url` override in `mcp.client.sse.sse_client`

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this runtime risk before relying on the project: Allow explicit `message_url` override in `mcp.client.sse.sse_client`
- User impact: Developers may hit a documented source-backed failure mode: Allow explicit `message_url` override in `mcp.client.sse.sse_client`
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: Allow explicit `message_url` override in `mcp.client.sse.sse_client`. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_38851e8d85c6f19432856bbba26ef3e8 | https://github.com/modelcontextprotocol/python-sdk/issues/2255 | Allow explicit `message_url` override in `mcp.client.sse.sse_client`

## 26. runtime · 失败模式：runtime: FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this runtime risk before relying on the project: FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax
- User impact: Developers may hit a documented source-backed failure mode: FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_ba4b866b69ee970071b1debedd854e87 | https://github.com/modelcontextprotocol/python-sdk/issues/2591 | FastMCP crashes when tool return type uses Python 3.10+ `A | B | C` union syntax

## 27. runtime · 失败模式：runtime: RequestResponder.__exit__ leaks CancelledError on cancelled request, killing the stdio receiv...

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this runtime risk before relying on the project: RequestResponder.__exit__ leaks CancelledError on cancelled request, killing the stdio receive loop
- User impact: Developers may hit a documented source-backed failure mode: RequestResponder.__exit__ leaks CancelledError on cancelled request, killing the stdio receive loop
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: RequestResponder.__exit__ leaks CancelledError on cancelled request, killing the stdio receive loop. Context: Observed when using python, windows
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_4222d93626e7c215e5f89c3437d364ac | https://github.com/modelcontextprotocol/python-sdk/issues/2610 | RequestResponder.__exit__ leaks CancelledError on cancelled request, killing the stdio receive loop

## 28. runtime · 失败模式：runtime: streamable HTTP client parses zstd-compressed JSON response bytes as JSON

- Severity: medium
- Evidence strength: source_linked
- Finding: Developers should check this runtime risk before relying on the project: streamable HTTP client parses zstd-compressed JSON response bytes as JSON
- User impact: Developers may hit a documented source-backed failure mode: streamable HTTP client parses zstd-compressed JSON response bytes as JSON
- Suggested check: Before packaging this project, run the relevant install/config/quickstart check for: streamable HTTP client parses zstd-compressed JSON response bytes as JSON. Context: Observed when using python
- Guardrail action: State this as source-backed community evidence, not as Doramagic reproduction.
- Evidence: failure_mode_cluster:github_issue | fmev_6dab858cb2e7425fd52afd406c414889 | https://github.com/modelcontextprotocol/python-sdk/issues/2649 | streamable HTTP client parses zstd-compressed JSON response bytes as JSON, failure_mode_cluster:github_issue | fmev_78fb17ba8dc344c3013b7a2a4dd78b69 | https://github.com/modelcontextprotocol/python-sdk/issues/2649 | streamable HTTP client parses zstd-compressed JSON response bytes as JSON

## 29. maintenance · 来源证据：Allow explicit `message_url` override in `mcp.client.sse.sse_client`

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：Allow explicit `message_url` override in `mcp.client.sse.sse_client`
- User impact: 可能增加新用户试用和生产接入成本。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_64695bc088354f31aed514c1509a8466 | https://github.com/modelcontextprotocol/python-sdk/issues/2255 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 30. maintenance · 维护活跃度未知

- Severity: medium
- Evidence strength: source_linked
- Finding: 未记录 last_activity_observed。
- User impact: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Suggested check: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Guardrail action: 维护活跃度未知时，推荐强度不能标为高信任。
- Evidence: evidence.maintainer_signals | github_repo:862584018 | https://github.com/modelcontextprotocol/python-sdk | last_activity_observed missing

## 31. security_permissions · 下游验证发现风险项

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: 下游已经要求复核，不能在页面中弱化。
- Suggested check: 进入安全/权限治理复核队列。
- Guardrail action: 下游风险存在时必须保持 review/recommendation 降级。
- Evidence: downstream_validation.risk_items | github_repo:862584018 | https://github.com/modelcontextprotocol/python-sdk | no_demo; severity=medium

## 32. security_permissions · 存在评分风险

- Severity: medium
- Evidence strength: source_linked
- Finding: no_demo
- User impact: 风险会影响是否适合普通用户安装。
- Suggested check: 把风险写入边界卡，并确认是否需要人工复核。
- Guardrail action: 评分风险必须进入边界卡，不能只作为内部分数。
- Evidence: risks.scoring_risks | github_repo:862584018 | https://github.com/modelcontextprotocol/python-sdk | no_demo; severity=medium

## 33. security_permissions · 来源证据：Add dereference helper for tool inputSchema with nested Pydantic models

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Add dereference helper for tool inputSchema with nested Pydantic models
- User impact: 可能影响授权、密钥配置或安全边界。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_8593f035989b47d9be01d49846994bac | https://github.com/modelcontextprotocol/python-sdk/issues/2586 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 34. security_permissions · 来源证据：Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-task generator driving

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Bug: `anyio.Lock` in `oauth2.py` raises "current task is not holding this lock" under cross-task generator driving
- User impact: 可能影响授权、密钥配置或安全边界。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_1f87ab18f1bd41f08edfee9d554fff11 | https://github.com/modelcontextprotocol/python-sdk/issues/2644 | 来源讨论提到 windows 相关条件，需在安装/试用前复核。

## 35. security_permissions · 来源证据：Context bloat - the bottle neck of MCP

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Context bloat - the bottle neck of MCP
- User impact: 可能影响授权、密钥配置或安全边界。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_b3028447aa1549b0acb817312bd398b5 | https://github.com/modelcontextprotocol/python-sdk/issues/2619 | 来源类型 github_issue 暴露的待验证使用条件。

## 36. security_permissions · 来源证据：Server OAuth metadata hardcodes token_endpoint_auth_methods_supported, breaking public client flows

- Severity: medium
- Evidence strength: source_linked
- Finding: GitHub 社区证据显示该项目存在一个安全/权限相关的待验证问题：Server OAuth metadata hardcodes token_endpoint_auth_methods_supported, breaking public client flows
- User impact: 可能影响升级、迁移或版本选择。
- Suggested check: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Guardrail action: 不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- Evidence: community_evidence:github | cevd_4a64c4f8e4064f39adb8da663a976411 | https://github.com/modelcontextprotocol/python-sdk/issues/2260 | 来源讨论提到 python 相关条件，需在安装/试用前复核。

## 37. maintenance · issue/PR 响应质量未知

- Severity: low
- Evidence strength: source_linked
- Finding: issue_or_pr_quality=unknown。
- User impact: 用户无法判断遇到问题后是否有人维护。
- Suggested check: 抽样最近 issue/PR，判断是否长期无人处理。
- Guardrail action: issue/PR 响应未知时，必须提示维护风险。
- Evidence: evidence.maintainer_signals | github_repo:862584018 | https://github.com/modelcontextprotocol/python-sdk | issue_or_pr_quality=unknown

## 38. maintenance · 发布节奏不明确

- Severity: low
- Evidence strength: source_linked
- Finding: release_recency=unknown。
- User impact: 安装命令和文档可能落后于代码，用户踩坑概率升高。
- Suggested check: 确认最近 release/tag 和 README 安装命令是否一致。
- Guardrail action: 发布节奏未知或过期时，安装说明必须标注可能漂移。
- Evidence: evidence.maintainer_signals | github_repo:862584018 | https://github.com/modelcontextprotocol/python-sdk | release_recency=unknown

<!-- canonical_name: modelcontextprotocol/python-sdk; human_manual_source: deepwiki_human_wiki -->
