Skip to content

Commit 0ff33a9

Browse files
authored
Merge branch 'main' into add_root_notification
2 parents f6784bd + 61399b3 commit 0ff33a9

File tree

18 files changed

+608
-56
lines changed

18 files changed

+608
-56
lines changed

CLAUDE.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ This document contains critical information about working with this codebase. Fo
4848
the problem it tries to solve, and how it is solved. Don't go into the specifics of the
4949
code unless it adds clarity.
5050

51-
- Always add `jerome3o-anthropic` and `jspahrsummers` as reviewer.
52-
5351
- NEVER ever mention a `co-authored-by` or similar aspects. In particular, never
5452
mention the tool used to create the commit message or PR.
5553

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
[![MIT licensed][mit-badge]][mit-url]
99
[![Python Version][python-badge]][python-url]
1010
[![Documentation][docs-badge]][docs-url]
11+
[![Protocol][protocol-badge]][protocol-url]
1112
[![Specification][spec-badge]][spec-url]
12-
[![GitHub Discussions][discussions-badge]][discussions-url]
1313

1414
</div>
1515

@@ -74,12 +74,12 @@
7474
[mit-url]: https://github.com/modelcontextprotocol/python-sdk/blob/main/LICENSE
7575
[python-badge]: https://img.shields.io/pypi/pyversions/mcp.svg
7676
[python-url]: https://www.python.org/downloads/
77-
[docs-badge]: https://img.shields.io/badge/docs-modelcontextprotocol.io-blue.svg
78-
[docs-url]: https://modelcontextprotocol.io
77+
[docs-badge]: https://img.shields.io/badge/docs-python--sdk-blue.svg
78+
[docs-url]: https://modelcontextprotocol.github.io/python-sdk/
79+
[protocol-badge]: https://img.shields.io/badge/protocol-modelcontextprotocol.io-blue.svg
80+
[protocol-url]: https://modelcontextprotocol.io
7981
[spec-badge]: https://img.shields.io/badge/spec-spec.modelcontextprotocol.io-blue.svg
8082
[spec-url]: https://spec.modelcontextprotocol.io
81-
[discussions-badge]: https://img.shields.io/github/discussions/modelcontextprotocol/python-sdk
82-
[discussions-url]: https://github.com/modelcontextprotocol/python-sdk/discussions
8383

8484
## Overview
8585

docs/authorization.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Authorization
2+
3+
!!! warning "Under Construction"
4+
5+
This page is currently being written. Check back soon for complete documentation.

docs/concepts.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Concepts
2+
3+
!!! warning "Under Construction"
4+
5+
This page is currently being written. Check back soon for complete documentation.
6+
7+
<!--
8+
- Server vs Client
9+
- Three primitives (tools, resources, prompts)
10+
- Transports (stdio, SSE, streamable HTTP)
11+
- Context and sessions
12+
- Lifecycle and state
13+
-->

docs/index.md

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,57 @@
1-
# MCP Server
1+
# MCP Python SDK
22

3-
This is the MCP Server implementation in Python.
3+
The **Model Context Protocol (MCP)** allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction.
44

5-
It only contains the [API Reference](api.md) for the time being.
5+
This Python SDK implements the full MCP specification, making it easy to:
6+
7+
- **Build MCP servers** that expose resources, prompts, and tools
8+
- **Create MCP clients** that can connect to any MCP server
9+
- **Use standard transports** like stdio, SSE, and Streamable HTTP
10+
11+
If you want to read more about the specification, please visit the [MCP documentation](https://modelcontextprotocol.io).
12+
13+
## Quick Example
14+
15+
Here's a simple MCP server that exposes a tool, resource, and prompt:
16+
17+
```python title="server.py"
18+
from mcp.server.fastmcp import FastMCP
19+
20+
mcp = FastMCP("Test Server")
21+
22+
23+
@mcp.tool()
24+
def add(a: int, b: int) -> int:
25+
"""Add two numbers"""
26+
return a + b
27+
28+
29+
@mcp.resource("greeting://{name}")
30+
def get_greeting(name: str) -> str:
31+
"""Get a personalized greeting"""
32+
return f"Hello, {name}!"
33+
34+
35+
@mcp.prompt()
36+
def greet_user(name: str, style: str = "friendly") -> str:
37+
"""Generate a greeting prompt"""
38+
return f"Write a {style} greeting for someone named {name}."
39+
```
40+
41+
Test it with the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
42+
43+
```bash
44+
uv run mcp dev server.py
45+
```
46+
47+
## Getting Started
48+
49+
<!-- TODO(Marcelo): automatically generate the follow references with a header on each of those files. -->
50+
1. **[Install](installation.md)** the MCP SDK
51+
2. **[Learn concepts](concepts.md)** - understand the three primitives and architecture
52+
3. **[Explore authorization](authorization.md)** - add security to your servers
53+
4. **[Use low-level APIs](low-level-server.md)** - for advanced customization
54+
55+
## API Reference
56+
57+
Full API documentation is available in the [API Reference](api.md).

docs/installation.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Installation
2+
3+
The Python SDK is available on PyPI as [`mcp`](https://pypi.org/project/mcp/) so installation is as simple as:
4+
5+
=== "pip"
6+
7+
```bash
8+
pip install mcp
9+
```
10+
=== "uv"
11+
12+
```bash
13+
uv add mcp
14+
```
15+
16+
The following dependencies are automatically installed:
17+
18+
- [`httpx`](https://pypi.org/project/httpx/): HTTP client to handle HTTP Streamable and SSE transports.
19+
- [`httpx-sse`](https://pypi.org/project/httpx-sse/): HTTP client to handle SSE transport.
20+
- [`pydantic`](https://pypi.org/project/pydantic/): Types, JSON schema generation, data validation, and [more](https://docs.pydantic.dev/latest/).
21+
- [`starlette`](https://pypi.org/project/starlette/): Web framework used to build the HTTP transport endpoints.
22+
- [`python-multipart`](https://pypi.org/project/python-multipart/): Handle HTTP body parsing.
23+
- [`sse-starlette`](https://pypi.org/project/sse-starlette/): Server-Sent Events for Starlette, used to build the SSE transport endpoint.
24+
- [`pydantic-settings`](https://pypi.org/project/pydantic-settings/): Settings management used in FastMCP.
25+
- [`uvicorn`](https://pypi.org/project/uvicorn/): ASGI server used to run the HTTP transport endpoints.
26+
- [`jsonschema`](https://pypi.org/project/jsonschema/): JSON schema validation.
27+
- [`pywin32`](https://pypi.org/project/pywin32/): Windows specific dependencies for the CLI tools.
28+
29+
This package has the following optional groups:
30+
31+
- `cli`: Installs `typer` and `python-dotenv` for the MCP CLI tools.

docs/low-level-server.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Low-Level Server
2+
3+
!!! warning "Under Construction"
4+
5+
This page is currently being written. Check back soon for complete documentation.

docs/testing.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Testing MCP Servers
2+
3+
If you call yourself a developer, you will want to test your MCP server.
4+
The Python SDK offers the `create_connected_server_and_client_session` function to create a session
5+
using an in-memory transport. I know, I know, the name is too long... We are working on improving it.
6+
7+
Anyway, let's assume you have a simple server with a single tool:
8+
9+
```python title="server.py"
10+
from mcp.server import FastMCP
11+
12+
app = FastMCP("Calculator")
13+
14+
@app.tool()
15+
def add(a: int, b: int) -> int:
16+
"""Add two numbers.""" # (1)!
17+
return a + b
18+
```
19+
20+
1. The docstring is automatically added as the description of the tool.
21+
22+
To run the below test, you'll need to install the following dependencies:
23+
24+
=== "pip"
25+
```bash
26+
pip install inline-snapshot pytest
27+
```
28+
29+
=== "uv"
30+
```bash
31+
uv add inline-snapshot pytest
32+
```
33+
34+
!!! info
35+
I think [`pytest`](https://docs.pytest.org/en/stable/) is a pretty standard testing framework,
36+
so I won't go into details here.
37+
38+
The [`inline-snapshot`](https://15r10nk.github.io/inline-snapshot/latest/) is a library that allows
39+
you to take snapshots of the output of your tests. Which makes it easier to create tests for your
40+
server - you don't need to use it, but we are spreading the word for best practices.
41+
42+
```python title="test_server.py"
43+
from collections.abc import AsyncGenerator
44+
45+
import pytest
46+
from inline_snapshot import snapshot
47+
from mcp.client.session import ClientSession
48+
from mcp.shared.memory import create_connected_server_and_client_session
49+
from mcp.types import CallToolResult, TextContent
50+
51+
from server import app
52+
53+
54+
@pytest.fixture
55+
def anyio_backend(): # (1)!
56+
return "asyncio"
57+
58+
59+
@pytest.fixture
60+
async def client_session() -> AsyncGenerator[ClientSession]:
61+
async with create_connected_server_and_client_session(app, raise_exceptions=True) as _session:
62+
yield _session
63+
64+
65+
@pytest.mark.anyio
66+
async def test_call_add_tool(client_session: ClientSession):
67+
result = await client_session.call_tool("add", {"a": 1, "b": 2})
68+
assert result == snapshot(
69+
CallToolResult(
70+
content=[TextContent(type="text", text="3")],
71+
structuredContent={"result": 3},
72+
)
73+
)
74+
```
75+
76+
1. If you are using `trio`, you should set `"trio"` as the `anyio_backend`. Check more information in the [anyio documentation](https://anyio.readthedocs.io/en/stable/testing.html#specifying-the-backends-to-run-on).
77+
78+
There you go! You can now extend your tests to cover more scenarios.

examples/servers/simple-auth/mcp_simple_auth/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class ResourceServerSettings(BaseSettings):
3232
# Server settings
3333
host: str = "localhost"
3434
port: int = 8001
35-
server_url: AnyHttpUrl = AnyHttpUrl("http://localhost:8001")
35+
server_url: AnyHttpUrl = AnyHttpUrl("http://localhost:8001/mcp")
3636

3737
# Authorization Server settings
3838
auth_server_url: AnyHttpUrl = AnyHttpUrl("http://localhost:9000")
@@ -137,7 +137,7 @@ def main(port: int, auth_server: str, transport: Literal["sse", "streamable-http
137137

138138
# Create settings
139139
host = "localhost"
140-
server_url = f"http://{host}:{port}"
140+
server_url = f"http://{host}:{port}/mcp"
141141
settings = ResourceServerSettings(
142142
host=host,
143143
port=port,

mkdocs.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ site_url: https://modelcontextprotocol.github.io/python-sdk
1111
# copyright: © Model Context Protocol 2025 to present
1212

1313
nav:
14-
- Home: index.md
14+
- Introduction: index.md
15+
- Installation: installation.md
16+
- Documentation:
17+
- Concepts: concepts.md
18+
- Low-Level Server: low-level-server.md
19+
- Authorization: authorization.md
20+
- Testing: testing.md
1521
- API Reference: api.md
1622

1723
theme:

0 commit comments

Comments
 (0)