Skip to content

[Schema][Server] feat: support sampling with tools - #409

Open
wWzZb wants to merge 3 commits into
modelcontextprotocol:mainfrom
wWzZb:codex/issue-155-sampling
Open

[Schema][Server] feat: support sampling with tools#409
wWzZb wants to merge 3 commits into
modelcontextprotocol:mainfrom
wWzZb:codex/issue-155-sampling

Conversation

@wWzZb

@wWzZb wWzZb commented Aug 7, 2026

Copy link
Copy Markdown

What

  • Add tools and toolChoice to sampling requests and wire them through ClientGateway::sample().
  • Add sampling tool-use and tool-result content blocks, array content support, message metadata, and standard stop-reason values with open-string compatibility.
  • Expose sampling.context and sampling.tools client capabilities.
  • Add round-trip and validation coverage for the new schema types.

Why

The SDK did not yet model the SEP-1577 protocol additions, so servers could not express tool-enabled sampling loops through the typed API.

Impact

Existing single-content sampling calls remain supported. The new constructor parameters are optional and appended to preserve current call sites.

Checks

  • make cs
  • make phpstan
  • make tests — 938 tests, 2786 assertions, 7 existing skips
  • make docs

Closes #155

@wWzZb
wWzZb marked this pull request as ready for review August 7, 2026 07:13
@chr-hertel chr-hertel added Server Issues & PRs related to the Server component Schema Issues & PRs related to the Schema component improves spec compliance Improves consistency with other SDKs such as TyepScript labels Aug 10, 2026
@chr-hertel chr-hertel changed the title feat: support sampling with tools [Schema][Server] feat: support sampling with tools Aug 10, 2026
@chr-hertel chr-hertel added this to the 0.8.0 milestone Aug 10, 2026

@chr-hertel chr-hertel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @wWzZb for working on this - please extend the CHANGELOG.md for upcomgin release 0.8.0, extend docs and example where meaningful and double-check if there's still missing unit tests here and there - i at least caught one place where i think it makes sense to add some.

Thanks again, great addition for feature parity with the spec! 👍

public readonly TextContent|ImageContent|AudioContent|ToolUseContent|array $content,
public readonly string $model,
public readonly ?string $stopReason = null,
public readonly SamplingStopReason|string|null $stopReason = null,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if we adopt the enum here, we can basically drop string, right?

Suggested change
public readonly SamplingStopReason|string|null $stopReason = null,
public readonly ?SamplingStopReason $stopReason = null,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I kept the string arm intentionally. The current MCP schema defines stopReason as an open string so clients can return provider-specific reasons, while SamplingStopReason documents the standard values. fromArray() now maps known values to the enum and preserves unknown values; the provider-specific path is covered by a unit test. See https://modelcontextprotocol.io/specification/2025-11-25/schema#create-message-result.

Comment thread src/Schema/Content/SamplingMessage.php
Comment thread src/Schema/ClientCapabilities.php
@chr-hertel chr-hertel added the needs more work Not ready to be merged yet, needs additional follow-up from the author(s). label Aug 10, 2026
@wWzZb

wWzZb commented Aug 11, 2026

Copy link
Copy Markdown
Author

Addressed the review feedback in 991fe4f:

  • added the sampling content PHPStan alias;
  • covered both array- and object-form sampling capability hydration;
  • added the upcoming 0.8.0 changelog entry;
  • documented tool-enabled sampling with a callback example;
  • strengthened the provider-specific stopReason round-trip test.

I kept SamplingStopReason|string|null because the MCP schema explicitly defines stopReason as an open string for provider-specific values, and replied with the spec reference in that thread.

Local checks: make cs, make phpstan, make tests (937 tests, 2785 assertions, 7 skips), and make docs.

@wWzZb

wWzZb commented Aug 11, 2026

Copy link
Copy Markdown
Author

Follow-up spec audit in 0b1cb6d:

  • tightened ToolResultContent so its constructor only accepts standard tool-result content blocks;
  • added regression coverage for rejecting non-standard nested message content;
  • updated the server-side sampling guide to the 2025-11-25 specification and documented tools, toolChoice, and the capability requirements;
  • documented the soft-deprecation rules for includeContext.

Checks: make cs, make phpstan, make tests (938 tests, 2786 assertions, 7 skips), and make docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improves spec compliance Improves consistency with other SDKs such as TyepScript needs more work Not ready to be merged yet, needs additional follow-up from the author(s). Schema Issues & PRs related to the Schema component Server Issues & PRs related to the Server component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Server][Schema] Implement SEP-1577: Sampling With Tools

2 participants