Skip to content

Commit 765ae28

Browse files
Merge branch 'main' into expose_meta_in_tool_calling
2 parents 2b61abb + c733eec commit 765ae28

File tree

77 files changed

+4104
-1497
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+4104
-1497
lines changed

.github/CODEOWNERS

Lines changed: 0 additions & 23 deletions
This file was deleted.

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ ipython_config.py
8989
# pyenv
9090
# For a library or package, you might want to ignore these files since the code is
9191
# intended to run in multiple environments; otherwise, check them in:
92-
# .python-version
92+
.python-version
9393

9494
# pipenv
9595
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.

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: 155 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

@@ -57,6 +57,7 @@
5757
- [Advanced Usage](#advanced-usage)
5858
- [Low-Level Server](#low-level-server)
5959
- [Structured Output Support](#structured-output-support)
60+
- [Pagination (Advanced)](#pagination-advanced)
6061
- [Writing MCP Clients](#writing-mcp-clients)
6162
- [Client Display Utilities](#client-display-utilities)
6263
- [OAuth Authentication for Clients](#oauth-authentication-for-clients)
@@ -73,12 +74,12 @@
7374
[mit-url]: https://github.com/modelcontextprotocol/python-sdk/blob/main/LICENSE
7475
[python-badge]: https://img.shields.io/pypi/pyversions/mcp.svg
7576
[python-url]: https://www.python.org/downloads/
76-
[docs-badge]: https://img.shields.io/badge/docs-modelcontextprotocol.io-blue.svg
77-
[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
7881
[spec-badge]: https://img.shields.io/badge/spec-spec.modelcontextprotocol.io-blue.svg
7982
[spec-url]: https://spec.modelcontextprotocol.io
80-
[discussions-badge]: https://img.shields.io/github/discussions/modelcontextprotocol/python-sdk
81-
[discussions-url]: https://github.com/modelcontextprotocol/python-sdk/discussions
8283

8384
## Overview
8485

@@ -515,6 +516,41 @@ def debug_error(error: str) -> list[base.Message]:
515516
_Full example: [examples/snippets/servers/basic_prompt.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/basic_prompt.py)_
516517
<!-- /snippet-source -->
517518

519+
### Icons
520+
521+
MCP servers can provide icons for UI display. Icons can be added to the server implementation, tools, resources, and prompts:
522+
523+
```python
524+
from mcp.server.fastmcp import FastMCP, Icon
525+
526+
# Create an icon from a file path or URL
527+
icon = Icon(
528+
src="icon.png",
529+
mimeType="image/png",
530+
sizes="64x64"
531+
)
532+
533+
# Add icons to server
534+
mcp = FastMCP(
535+
"My Server",
536+
website_url="https://example.com",
537+
icons=[icon]
538+
)
539+
540+
# Add icons to tools, resources, and prompts
541+
@mcp.tool(icons=[icon])
542+
def my_tool():
543+
"""Tool with an icon."""
544+
return "result"
545+
546+
@mcp.resource("demo://resource", icons=[icon])
547+
def my_resource():
548+
"""Resource with an icon."""
549+
return "content"
550+
```
551+
552+
_Full example: [examples/fastmcp/icons_demo.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/fastmcp/icons_demo.py)_
553+
518554
### Images
519555

520556
FastMCP provides an `Image` class that automatically handles image data:
@@ -746,6 +782,8 @@ async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerS
746782
_Full example: [examples/snippets/servers/elicitation.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/elicitation.py)_
747783
<!-- /snippet-source -->
748784

785+
Elicitation schemas support default values for all field types. Default values are automatically included in the JSON schema sent to clients, allowing them to pre-populate forms.
786+
749787
The `elicit()` method returns an `ElicitationResult` with:
750788

751789
- `action`: "accept", "decline", or "cancel"
@@ -895,6 +933,8 @@ The FastMCP server instance accessible via `ctx.fastmcp` provides access to serv
895933

896934
- `ctx.fastmcp.name` - The server's name as defined during initialization
897935
- `ctx.fastmcp.instructions` - Server instructions/description provided to clients
936+
- `ctx.fastmcp.website_url` - Optional website URL for the server
937+
- `ctx.fastmcp.icons` - Optional list of icons for UI display
898938
- `ctx.fastmcp.settings` - Complete server configuration object containing:
899939
- `debug` - Debug mode flag
900940
- `log_level` - Current logging level
@@ -1737,6 +1777,116 @@ Tools can return data in three ways:
17371777

17381778
When an `outputSchema` is defined, the server automatically validates the structured output against the schema. This ensures type safety and helps catch errors early.
17391779

1780+
### Pagination (Advanced)
1781+
1782+
For servers that need to handle large datasets, the low-level server provides paginated versions of list operations. This is an optional optimization - most servers won't need pagination unless they're dealing with hundreds or thousands of items.
1783+
1784+
#### Server-side Implementation
1785+
1786+
<!-- snippet-source examples/snippets/servers/pagination_example.py -->
1787+
```python
1788+
"""
1789+
Example of implementing pagination with MCP server decorators.
1790+
"""
1791+
1792+
from pydantic import AnyUrl
1793+
1794+
import mcp.types as types
1795+
from mcp.server.lowlevel import Server
1796+
1797+
# Initialize the server
1798+
server = Server("paginated-server")
1799+
1800+
# Sample data to paginate
1801+
ITEMS = [f"Item {i}" for i in range(1, 101)] # 100 items
1802+
1803+
1804+
@server.list_resources()
1805+
async def list_resources_paginated(request: types.ListResourcesRequest) -> types.ListResourcesResult:
1806+
"""List resources with pagination support."""
1807+
page_size = 10
1808+
1809+
# Extract cursor from request params
1810+
cursor = request.params.cursor if request.params is not None else None
1811+
1812+
# Parse cursor to get offset
1813+
start = 0 if cursor is None else int(cursor)
1814+
end = start + page_size
1815+
1816+
# Get page of resources
1817+
page_items = [
1818+
types.Resource(uri=AnyUrl(f"resource://items/{item}"), name=item, description=f"Description for {item}")
1819+
for item in ITEMS[start:end]
1820+
]
1821+
1822+
# Determine next cursor
1823+
next_cursor = str(end) if end < len(ITEMS) else None
1824+
1825+
return types.ListResourcesResult(resources=page_items, nextCursor=next_cursor)
1826+
```
1827+
1828+
_Full example: [examples/snippets/servers/pagination_example.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/servers/pagination_example.py)_
1829+
<!-- /snippet-source -->
1830+
1831+
#### Client-side Consumption
1832+
1833+
<!-- snippet-source examples/snippets/clients/pagination_client.py -->
1834+
```python
1835+
"""
1836+
Example of consuming paginated MCP endpoints from a client.
1837+
"""
1838+
1839+
import asyncio
1840+
1841+
from mcp.client.session import ClientSession
1842+
from mcp.client.stdio import StdioServerParameters, stdio_client
1843+
from mcp.types import PaginatedRequestParams, Resource
1844+
1845+
1846+
async def list_all_resources() -> None:
1847+
"""Fetch all resources using pagination."""
1848+
async with stdio_client(StdioServerParameters(command="uv", args=["run", "mcp-simple-pagination"])) as (
1849+
read,
1850+
write,
1851+
):
1852+
async with ClientSession(read, write) as session:
1853+
await session.initialize()
1854+
1855+
all_resources: list[Resource] = []
1856+
cursor = None
1857+
1858+
while True:
1859+
# Fetch a page of resources
1860+
result = await session.list_resources(params=PaginatedRequestParams(cursor=cursor))
1861+
all_resources.extend(result.resources)
1862+
1863+
print(f"Fetched {len(result.resources)} resources")
1864+
1865+
# Check if there are more pages
1866+
if result.nextCursor:
1867+
cursor = result.nextCursor
1868+
else:
1869+
break
1870+
1871+
print(f"Total resources: {len(all_resources)}")
1872+
1873+
1874+
if __name__ == "__main__":
1875+
asyncio.run(list_all_resources())
1876+
```
1877+
1878+
_Full example: [examples/snippets/clients/pagination_client.py](https://github.com/modelcontextprotocol/python-sdk/blob/main/examples/snippets/clients/pagination_client.py)_
1879+
<!-- /snippet-source -->
1880+
1881+
#### Key Points
1882+
1883+
- **Cursors are opaque strings** - the server defines the format (numeric offsets, timestamps, etc.)
1884+
- **Return `nextCursor=None`** when there are no more pages
1885+
- **Backward compatible** - clients that don't support pagination will still work (they'll just get the first page)
1886+
- **Flexible page sizes** - Each endpoint can define its own page size based on data characteristics
1887+
1888+
See the [simple-pagination example](examples/servers/simple-pagination) for a complete implementation.
1889+
17401890
### Writing MCP Clients
17411891

17421892
The SDK provides a high-level client interface for connecting to MCP servers using various [transports](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports):

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.

0 commit comments

Comments
 (0)