# 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 ## 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, ) ``` ## 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