Skip to content

Conversation

@jlowin
Copy link
Contributor

@jlowin jlowin commented Dec 4, 2025

SEP-1577 added tool calling support to sampling (via #1594). This PR adds the necessary client-side support:

  1. Capability advertisement: The spec requires servers to error when tools or toolChoice are provided but clientCapabilities.sampling.tools is missing. The SDK's types already support this, but ClientSession had no way to advertise it—servers would always see the capability as missing and error. This adds a sampling_capabilities parameter. If not provided, the previous logic applies: the presence of a sampling_callback enables basic sampling support without tools.
session = ClientSession(
    read_stream, write_stream,
    sampling_callback=my_callback,
    sampling_capabilities=SamplingCapability(
        tools=SamplingToolsCapability()
    ),
)
  1. Return type for tool responses: When tools are provided in a sampling request, the LLM may respond with tool calls, requiring CreateMessageResultWithTools (which supports array content). The SamplingFnT callback and ClientResultType didn't include this type, so the client's response validation would reject it before it could be sent back to the server. This adds CreateMessageResultWithTools to both.

FWIW, with these changes we have full agentic sampling wired up in a branch of FastMCP, which is extremely exciting!

@jlowin jlowin changed the title feat: expose sampling_capabilities parameter for SEP-1577 tool support feat: client-side support for SEP-1577 sampling with tools Dec 4, 2025
@felixweinberger felixweinberger added the needs maintainer action Potentially serious issue - needs proactive fix and maintainer attention label Dec 8, 2025
write_stream: MemoryObjectSendStream[SessionMessage],
read_timeout_seconds: timedelta | None = None,
sampling_callback: SamplingFnT | None = None,
sampling_capabilities: types.SamplingCapability | None = None,
Copy link
Contributor

@maxisbey maxisbey Dec 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thoughts on moving to the bottom of kwargs or keyword only to avoid breaking positional uses of the constructor? I'm probably leaning towards positional keyword only

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call! (assuming you meant leaning "keyword" only, and I agree - will update)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

woops yea meant keyword only haha

@maxisbey maxisbey added the improves spec compliance When a change improves ability of SDK users to comply with spec definition label Dec 9, 2025
@maxisbey maxisbey enabled auto-merge (squash) December 9, 2025 18:58
@maxisbey maxisbey merged commit 0dedbd9 into modelcontextprotocol:main Dec 9, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improves spec compliance When a change improves ability of SDK users to comply with spec definition needs maintainer action Potentially serious issue - needs proactive fix and maintainer attention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants