Enhancement in list_tools for both client and servce side
Description
https://github.com/modelcontextprotocol/python-sdk/blob/6566c08446ad37b66f1457532c7f5a14f243ae10/src/mcp/client/session.py#L384-L394
Why can't we expose the params parameter of tools/list to the client, so that the server can use this params to enhance the tools/list functionality — for example, enabling context-aware tool filtering?
Hi @xlb0479 - I don't understand your requirement - by definition the PaginatedRequestParams are being used by the client for pagination, so they are available for the client to update its request for pagination.
Could you provide some more details on what you're trying to achieve?
Linking this to the ongoing protocol work around discovery/filtering (e.g. https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1300 and related scope/versioning SEPs).
From a host/client perspective, once tools/list (and friends) gain richer filtering in the spec – especially things like:
filter.groups/filter.tags(as in SEP-1300),- and potentially
filter.names/filter.excludeNamesfor explicit allow/deny lists –
the Python SDK will need a way to surface those fields ergonomically, otherwise host apps are forced to:
- either drop down to raw JSON RPC calls, or
- accept that some protocol features (like name-based whitelists) aren’t available from the high-level client.
Concretely, it would be very helpful if list_tools (and similar methods) exposed either:
- A typed
filterargument that tracks the spec, e.g.:
class ToolsFilter(TypedDict, total=False):
names: list[str]
exclude_names: list[str]
groups: list[str]
tags: list[str]
# future fields as SEPs land
async def list_tools(
self,
*,
cursor: str | None = None,
filter: ToolsFilter | None = None,
) -> ListToolsResult:
...
or, if you prefer to keep the surface area stable while SEPs evolve:
- A
paramsescape hatch that can pass through arbitrary filter fields from the spec, while still keepingcursorexplicit, e.g.:
async def list_tools(
self,
*,
cursor: str | None = None,
params: dict[str, Any] | None = None,
) -> ListToolsResult:
...
Personally I’d lean toward the typed filter once the protocol side is more settled, but even a generic params argument would unblock early adopters who want to:
- implement tool whitelists on the server side (to avoid large responses that get filtered on the client),
- align Python hosts with SEP-1300 and future discovery SEPs,
- and avoid having to bypass the SDK for common discovery operations.
Happy to adjust the suggestion once the exact filter shape is finalized in the spec – the main ask is to make sure the SDK has a clear path to expose those protocol-level filters without requiring users to reimplement the client.
I'm going to close this issue as ClientSession has recently been refactored to allow passing in the full params object, rather than just the cursor: https://github.com/modelcontextprotocol/python-sdk/blob/89ff338174cec2b28f23deaec6136a4f3b11e875/src/mcp/client/session.py#L495
Further discussions around tool filtering should happen in SEP discussion threads rather than in in the Python SDK repo.