Skip to content

fix(server): validate sampling tool-use history - #3049

Open
Adebayo120 wants to merge 3 commits into
modelcontextprotocol:mainfrom
Adebayo120:fix/sampling-tool-use-balance
Open

Adebayo120 wants to merge 3 commits into
modelcontextprotocol:mainfrom
Adebayo120:fix/sampling-tool-use-balance

Conversation

@Adebayo120

Copy link
Copy Markdown

While integrating sampling, I noticed the server would forward a history containing an assistant tool_use without its matching user tool_result.

Reject these incomplete histories before sending the sampling request, and add regression coverage for missing or interrupted results.

Reject sampling histories with assistant tool_use blocks that lack matching tool_result blocks in the next user message.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Adebayo120
Adebayo120 requested a review from a team as a code owner October 18, 2026 18:46
@changeset-bot

changeset-bot Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2d52e31

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@modelcontextprotocol/server Patch
@modelcontextprotocol/client Patch
@modelcontextprotocol/codemod Patch
@modelcontextprotocol/core Patch
@modelcontextprotocol/server-legacy Patch
@modelcontextprotocol/core-internal Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/@modelcontextprotocol/client@3049

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/@modelcontextprotocol/codemod@3049

@modelcontextprotocol/core

npm i https://pkg.pr.new/@modelcontextprotocol/core@3049

@modelcontextprotocol/server

npm i https://pkg.pr.new/@modelcontextprotocol/server@3049

@modelcontextprotocol/server-legacy

npm i https://pkg.pr.new/@modelcontextprotocol/server-legacy@3049

@modelcontextprotocol/express

npm i https://pkg.pr.new/@modelcontextprotocol/express@3049

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/@modelcontextprotocol/fastify@3049

@modelcontextprotocol/hono

npm i https://pkg.pr.new/@modelcontextprotocol/hono@3049

@modelcontextprotocol/node

npm i https://pkg.pr.new/@modelcontextprotocol/node@3049

commit: 2d52e31

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@claude claude Bot added the v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes label Oct 19, 2026

@tlq5l tlq5l left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ran the server unit tests (577 pass), server.test.ts in test/integration (57 pass), scenarios/sampling.test.ts and coverage.test.ts in test/e2e, and check for server, integration and e2e; all clean. I also sent a few histories through createMessage over InMemoryTransport on main and on this branch: an interrupted tool_use in the middle followed by a valid pair, a trailing tool_use, and a tool_use in a user message are accepted on main and rejected here, while two valid rounds and text + tool_use in one assistant message are still accepted. That matches the balance rule in the 2025-11-25 sampling spec.

const toolUses = content.filter((block): block is ToolUseContent => block.type === 'tool_use');
const toolResults = content.filter((block): block is ToolResultContent => block.type === 'tool_result');

if (toolUses.length > 0 && message.role !== 'assistant') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These two role checks are new rejections that the description and changeset don't mention, and neither error message is asserted anywhere in the tests. Could you add a createMessage validation case for each (e.g. [user tool_use, user tool_result] and [user text, assistant tool_result]) and a sentence in the changeset?

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.

Added separate createMessage validation tests for tool_use in a user message and tool_result in an assistant message, and updated the changeset to mention both rejections. The server integration tests pass (59/59). Thanks for catching this.

Document and test the sampling message role checks raised in review.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

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

Labels

v2 Ideas, requests and plans for v2 of the SDK which will incorporate major changes and fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants