Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 36 additions & 4 deletions docs/migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,25 @@ async with http_client:

The `headers`, `timeout`, `sse_read_timeout`, and `auth` parameters have been removed from `StreamableHTTPTransport`. Configure these on the `httpx.AsyncClient` instead (see example above).

### `Content` type alias removed
### Removed type aliases and classes

The deprecated `Content` type alias has been removed. Use `ContentBlock` directly instead.
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
from mcp.types import Content, ResourceReference
```

**After (v2):**

```python
from mcp.types import ContentBlock
from mcp.types import ContentBlock, ResourceTemplateReference
```

### `args` parameter removed from `ClientSessionGroup.call_tool()`
Expand All @@ -84,6 +89,33 @@ result = await session_group.call_tool("my_tool", args={"key": "value"})
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"))
```

## Deprecations

<!-- Add deprecations below -->
Expand Down
140 changes: 12 additions & 128 deletions src/mcp/client/session.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import logging
from typing import Any, Protocol, overload
from typing import Any, Protocol

import anyio.lowlevel
from anyio.streams.memory import MemoryObjectReceiveStream, MemoryObjectSendStream
from pydantic import AnyUrl, TypeAdapter
from typing_extensions import deprecated

import mcp.types as types
from mcp.client.experimental import ExperimentalClientFeatures
Expand Down Expand Up @@ -256,112 +255,48 @@ async def set_logging_level(self, level: types.LoggingLevel) -> types.EmptyResul
types.EmptyResult,
)

@overload
@deprecated("Use list_resources(params=PaginatedRequestParams(...)) instead")
async def list_resources(self, cursor: str | None) -> types.ListResourcesResult: ...

@overload
async def list_resources(self, *, params: types.PaginatedRequestParams | None) -> types.ListResourcesResult: ...

@overload
async def list_resources(self) -> types.ListResourcesResult: ...

async def list_resources(
self,
cursor: str | None = None,
*,
params: types.PaginatedRequestParams | None = None,
) -> types.ListResourcesResult:
async def list_resources(self, *, params: types.PaginatedRequestParams | None = None) -> types.ListResourcesResult:
"""Send a resources/list request.

Args:
cursor: Simple cursor string for pagination (deprecated, use params instead)
params: Full pagination parameters including cursor and any future fields
"""
if params is not None and cursor is not None:
raise ValueError("Cannot specify both cursor and params")

if params is not None:
request_params = params
elif cursor is not None:
request_params = types.PaginatedRequestParams(cursor=cursor)
else:
request_params = None

return await self.send_request(
types.ClientRequest(types.ListResourcesRequest(params=request_params)),
types.ClientRequest(types.ListResourcesRequest(params=params)),
types.ListResourcesResult,
)

@overload
@deprecated("Use list_resource_templates(params=PaginatedRequestParams(...)) instead")
async def list_resource_templates(self, cursor: str | None) -> types.ListResourceTemplatesResult: ...

@overload
async def list_resource_templates(
self, *, params: types.PaginatedRequestParams | None
) -> types.ListResourceTemplatesResult: ...

@overload
async def list_resource_templates(self) -> types.ListResourceTemplatesResult: ...

async def list_resource_templates(
self,
cursor: str | None = None,
*,
params: types.PaginatedRequestParams | None = None,
self, *, params: types.PaginatedRequestParams | None = None
) -> types.ListResourceTemplatesResult:
"""Send a resources/templates/list request.

Args:
cursor: Simple cursor string for pagination (deprecated, use params instead)
params: Full pagination parameters including cursor and any future fields
"""
if params is not None and cursor is not None:
raise ValueError("Cannot specify both cursor and params")

if params is not None:
request_params = params
elif cursor is not None:
request_params = types.PaginatedRequestParams(cursor=cursor)
else:
request_params = None

return await self.send_request(
types.ClientRequest(types.ListResourceTemplatesRequest(params=request_params)),
types.ClientRequest(types.ListResourceTemplatesRequest(params=params)),
types.ListResourceTemplatesResult,
)

async def read_resource(self, uri: AnyUrl) -> types.ReadResourceResult:
"""Send a resources/read request."""
return await self.send_request(
types.ClientRequest(
types.ReadResourceRequest(
params=types.ReadResourceRequestParams(uri=uri),
)
),
types.ClientRequest(types.ReadResourceRequest(params=types.ReadResourceRequestParams(uri=uri))),
types.ReadResourceResult,
)

async def subscribe_resource(self, uri: AnyUrl) -> types.EmptyResult:
"""Send a resources/subscribe request."""
return await self.send_request( # pragma: no cover
types.ClientRequest(
types.SubscribeRequest(
params=types.SubscribeRequestParams(uri=uri),
)
),
types.ClientRequest(types.SubscribeRequest(params=types.SubscribeRequestParams(uri=uri))),
types.EmptyResult,
)

async def unsubscribe_resource(self, uri: AnyUrl) -> types.EmptyResult:
"""Send a resources/unsubscribe request."""
return await self.send_request( # pragma: no cover
types.ClientRequest(
types.UnsubscribeRequest(
params=types.UnsubscribeRequestParams(uri=uri),
)
),
types.ClientRequest(types.UnsubscribeRequest(params=types.UnsubscribeRequestParams(uri=uri))),
types.EmptyResult,
)

Expand Down Expand Up @@ -422,40 +357,14 @@ async def _validate_tool_result(self, name: str, result: types.CallToolResult) -
except SchemaError as e: # pragma: no cover
raise RuntimeError(f"Invalid schema for tool {name}: {e}") # pragma: no cover

@overload
@deprecated("Use list_prompts(params=PaginatedRequestParams(...)) instead")
async def list_prompts(self, cursor: str | None) -> types.ListPromptsResult: ...

@overload
async def list_prompts(self, *, params: types.PaginatedRequestParams | None) -> types.ListPromptsResult: ...

@overload
async def list_prompts(self) -> types.ListPromptsResult: ...

async def list_prompts(
self,
cursor: str | None = None,
*,
params: types.PaginatedRequestParams | None = None,
) -> types.ListPromptsResult:
async def list_prompts(self, *, params: types.PaginatedRequestParams | None = None) -> types.ListPromptsResult:
"""Send a prompts/list request.

Args:
cursor: Simple cursor string for pagination (deprecated, use params instead)
params: Full pagination parameters including cursor and any future fields
"""
if params is not None and cursor is not None:
raise ValueError("Cannot specify both cursor and params")

if params is not None:
request_params = params
elif cursor is not None:
request_params = types.PaginatedRequestParams(cursor=cursor)
else:
request_params = None

return await self.send_request(
types.ClientRequest(types.ListPromptsRequest(params=request_params)),
types.ClientRequest(types.ListPromptsRequest(params=params)),
types.ListPromptsResult,
)

Expand Down Expand Up @@ -494,40 +403,15 @@ async def complete(
types.CompleteResult,
)

@overload
@deprecated("Use list_tools(params=PaginatedRequestParams(...)) instead")
async def list_tools(self, cursor: str | None) -> types.ListToolsResult: ...

@overload
async def list_tools(self, *, params: types.PaginatedRequestParams | None) -> types.ListToolsResult: ...

@overload
async def list_tools(self) -> types.ListToolsResult: ...

async def list_tools(
self,
cursor: str | None = None,
*,
params: types.PaginatedRequestParams | None = None,
) -> types.ListToolsResult:
async def list_tools(self, *, params: types.PaginatedRequestParams | None = None) -> types.ListToolsResult:
"""Send a tools/list request.

Args:
cursor: Simple cursor string for pagination (deprecated, use params instead)
params: Full pagination parameters including cursor and any future fields
"""
if params is not None and cursor is not None:
raise ValueError("Cannot specify both cursor and params")

if params is not None:
request_params = params
elif cursor is not None:
request_params = types.PaginatedRequestParams(cursor=cursor)
else:
request_params = None

result = await self.send_request(
types.ClientRequest(types.ListToolsRequest(params=request_params)),
types.ClientRequest(types.ListToolsRequest(params=params)),
types.ListToolsResult,
)

Expand Down
6 changes: 0 additions & 6 deletions src/mcp/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from pydantic import BaseModel, ConfigDict, Field, FileUrl, RootModel
from pydantic.networks import AnyUrl, UrlConstraints
from typing_extensions import deprecated

LATEST_PROTOCOL_VERSION = "2025-11-25"

Expand Down Expand Up @@ -1587,11 +1586,6 @@ class ResourceTemplateReference(BaseModel):
model_config = ConfigDict(extra="allow")


@deprecated("`ResourceReference` is deprecated, you should use `ResourceTemplateReference`.")
class ResourceReference(ResourceTemplateReference):
pass


class PromptReference(BaseModel):
"""Identifies a prompt."""

Expand Down
Loading