231 lines
6.6 KiB
Markdown
231 lines
6.6 KiB
Markdown
# Migration Guide: v1 to v2
|
|
|
|
This guide covers the breaking changes introduced in v2 of the MCP Python SDK and how to update your code.
|
|
|
|
## Overview
|
|
|
|
Version 2 of the MCP Python SDK introduces several breaking changes to improve the API, align with the MCP specification, and provide better type safety.
|
|
|
|
## Breaking Changes
|
|
|
|
### `streamablehttp_client` removed
|
|
|
|
The deprecated `streamablehttp_client` function has been removed. Use `streamable_http_client` instead.
|
|
|
|
**Before (v1):**
|
|
|
|
```python
|
|
from mcp.client.streamable_http import streamablehttp_client
|
|
|
|
async with streamablehttp_client(
|
|
url="http://localhost:8000/mcp",
|
|
headers={"Authorization": "Bearer token"},
|
|
timeout=30,
|
|
sse_read_timeout=300,
|
|
auth=my_auth,
|
|
) as (read_stream, write_stream, get_session_id):
|
|
...
|
|
```
|
|
|
|
**After (v2):**
|
|
|
|
```python
|
|
import httpx
|
|
from mcp.client.streamable_http import streamable_http_client
|
|
|
|
# Configure headers, timeout, and auth on the httpx.AsyncClient
|
|
http_client = httpx.AsyncClient(
|
|
headers={"Authorization": "Bearer token"},
|
|
timeout=httpx.Timeout(30, read=300),
|
|
auth=my_auth,
|
|
)
|
|
|
|
async with http_client:
|
|
async with streamable_http_client(
|
|
url="http://localhost:8000/mcp",
|
|
http_client=http_client,
|
|
) as (read_stream, write_stream, get_session_id):
|
|
...
|
|
```
|
|
|
|
### `StreamableHTTPTransport` parameters removed
|
|
|
|
The `headers`, `timeout`, `sse_read_timeout`, and `auth` parameters have been removed from `StreamableHTTPTransport`. Configure these on the `httpx.AsyncClient` instead (see example above).
|
|
|
|
### Removed type aliases and classes
|
|
|
|
The following deprecated type aliases and classes have been removed from `mcp.types`:
|
|
|
|
| Removed | Replacement |
|
|
|---------|-------------|
|
|
| `Content` | `ContentBlock` |
|
|
| `ResourceReference` | `ResourceTemplateReference` |
|
|
|
|
**Before (v1):**
|
|
|
|
```python
|
|
from mcp.types import Content, ResourceReference
|
|
```
|
|
|
|
**After (v2):**
|
|
|
|
```python
|
|
from mcp.types import ContentBlock, ResourceTemplateReference
|
|
```
|
|
|
|
### `args` parameter removed from `ClientSessionGroup.call_tool()`
|
|
|
|
The deprecated `args` parameter has been removed from `ClientSessionGroup.call_tool()`. Use `arguments` instead.
|
|
|
|
**Before (v1):**
|
|
|
|
```python
|
|
result = await session_group.call_tool("my_tool", args={"key": "value"})
|
|
```
|
|
|
|
**After (v2):**
|
|
|
|
```python
|
|
result = await session_group.call_tool("my_tool", arguments={"key": "value"})
|
|
```
|
|
|
|
### `cursor` parameter removed from `ClientSession` list methods
|
|
|
|
The deprecated `cursor` parameter has been removed from the following `ClientSession` methods:
|
|
|
|
- `list_resources()`
|
|
- `list_resource_templates()`
|
|
- `list_prompts()`
|
|
- `list_tools()`
|
|
|
|
Use `params=PaginatedRequestParams(cursor=...)` instead.
|
|
|
|
**Before (v1):**
|
|
|
|
```python
|
|
result = await session.list_resources(cursor="next_page_token")
|
|
result = await session.list_tools(cursor="next_page_token")
|
|
```
|
|
|
|
**After (v2):**
|
|
|
|
```python
|
|
from mcp.types import PaginatedRequestParams
|
|
|
|
result = await session.list_resources(params=PaginatedRequestParams(cursor="next_page_token"))
|
|
result = await session.list_tools(params=PaginatedRequestParams(cursor="next_page_token"))
|
|
```
|
|
|
|
### Resource URI type changed from `AnyUrl` to `str`
|
|
|
|
The `uri` field on resource-related types now uses `str` instead of Pydantic's `AnyUrl`. This aligns with the [MCP specification schema](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.ts) which defines URIs as plain strings (`uri: string`) without strict URL validation. This change allows relative paths like `users/me` that were previously rejected.
|
|
|
|
**Before (v1):**
|
|
|
|
```python
|
|
from pydantic import AnyUrl
|
|
from mcp.types import Resource
|
|
|
|
# Required wrapping in AnyUrl
|
|
resource = Resource(name="test", uri=AnyUrl("users/me")) # Would fail validation
|
|
```
|
|
|
|
**After (v2):**
|
|
|
|
```python
|
|
from mcp.types import Resource
|
|
|
|
# Plain strings accepted
|
|
resource = Resource(name="test", uri="users/me") # Works
|
|
resource = Resource(name="test", uri="custom://scheme") # Works
|
|
resource = Resource(name="test", uri="https://example.com") # Works
|
|
```
|
|
|
|
If your code passes `AnyUrl` objects to URI fields, convert them to strings:
|
|
|
|
```python
|
|
# If you have an AnyUrl from elsewhere
|
|
uri = str(my_any_url) # Convert to string
|
|
```
|
|
|
|
Affected types:
|
|
|
|
- `Resource.uri`
|
|
- `ReadResourceRequestParams.uri`
|
|
- `ResourceContents.uri` (and subclasses `TextResourceContents`, `BlobResourceContents`)
|
|
- `SubscribeRequestParams.uri`
|
|
- `UnsubscribeRequestParams.uri`
|
|
- `ResourceUpdatedNotificationParams.uri`
|
|
|
|
The `ClientSession.read_resource()`, `subscribe_resource()`, and `unsubscribe_resource()` methods now accept both `str` and `AnyUrl` for backwards compatibility.
|
|
|
|
## Deprecations
|
|
|
|
<!-- Add deprecations below -->
|
|
|
|
## New Features
|
|
|
|
### Low-level StreamableHTTP server APIs
|
|
|
|
New exports from `mcp.server` for building custom StreamableHTTP servers without FastMCP:
|
|
|
|
- `StreamableHTTPSessionManager` - Manages MCP sessions for StreamableHTTP transport
|
|
- `create_streamable_http_app()` - Creates a configured Starlette app from a session manager
|
|
|
|
```python
|
|
from mcp.server import Server, StreamableHTTPSessionManager, create_streamable_http_app
|
|
|
|
server = Server("my-server")
|
|
# ... configure handlers ...
|
|
|
|
session_manager = StreamableHTTPSessionManager(
|
|
app=server,
|
|
event_store=my_event_store, # Optional, for resumability
|
|
json_response=False,
|
|
stateless=False,
|
|
)
|
|
|
|
app = create_streamable_http_app(
|
|
session_manager,
|
|
endpoint_path="/mcp",
|
|
additional_routes=[...],
|
|
middleware=[...],
|
|
)
|
|
```
|
|
|
|
### Reusable auth components
|
|
|
|
New exports from `mcp.server.auth` for adding OAuth 2.0 authentication to custom servers:
|
|
|
|
- `AuthComponents` - Dataclass containing middleware, endpoint wrapper, and routes
|
|
- `build_auth_components()` - Builds auth components from configuration
|
|
|
|
```python
|
|
from mcp.server.auth import build_auth_components
|
|
|
|
auth = build_auth_components(
|
|
token_verifier=my_verifier,
|
|
issuer_url="https://auth.example.com",
|
|
required_scopes=["mcp:read"],
|
|
resource_server_url="https://api.example.com", # Optional
|
|
auth_server_provider=my_provider, # Optional, if acting as OAuth AS
|
|
)
|
|
|
|
app = create_streamable_http_app(
|
|
session_manager,
|
|
additional_routes=auth.routes,
|
|
middleware=auth.middleware,
|
|
endpoint_wrapper=auth.endpoint_wrapper,
|
|
)
|
|
```
|
|
|
|
<!-- Add new features below -->
|
|
|
|
## Need Help?
|
|
|
|
If you encounter issues during migration:
|
|
|
|
1. Check the [API Reference](api.md) for updated method signatures
|
|
2. Review the [examples](https://github.com/modelcontextprotocol/python-sdk/tree/main/examples) for updated usage patterns
|
|
3. Open an issue on [GitHub](https://github.com/modelcontextprotocol/python-sdk/issues) if you find a bug or need further assistance
|