Skip to content

Preserve per-request client capability extensions when the session declares its own - #1921

Open
nathangobinet wants to merge 2 commits into
modelcontextprotocol:mainfrom
nathangobinet:fix/1920-preserve-request-extensions
Open

nathangobinet wants to merge 2 commits into
modelcontextprotocol:mainfrom
nathangobinet:fix/1920-preserve-request-extensions

Conversation

@nathangobinet

Copy link
Copy Markdown

Fixes #1920

Problem

On the 2026-07-28 revision, McpSessionHandler.InjectRequestMeta overlays the session capabilities onto the request's _meta.clientCapabilities one top-level key at a time. When the session declares any extension, its extensions object replaces the request's. That drops the per-request io.modelcontextprotocol/tasks opt-in added by CallToolAsTaskAsync, and the server answers synchronously.

Change

  • Merge JSON objects recursively (MergeJsonObject). A key present only on the request survives, and the session's values still win where both sides set the same key.
  • New regression test: McpClientTaskMethodsTests.CallToolAsTaskAsync_WithSessionLevelExtensions_StillReturnsCreatedTask. It fails without the fix.

Testing

  • dotnet build succeeds with 0 warnings.
  • ModelContextProtocol.Tests (net10.0): 2391 passed, 6 skipped.
  • ModelContextProtocol.AspNetCore.Tests (net10.0): 623 passed, 42 skipped.
  • Other target frameworks were not run locally.

Note

This pull request was AI-generated (Claude Code).

Nathan GOBINET and others added 2 commits October 12, 2026 11:13
…clares its own

InjectRequestMeta overlaid the session capabilities onto the request's
_meta.clientCapabilities one top-level key at a time, so a session that
declares any extension replaced the request's whole "extensions" object and
dropped the io.modelcontextprotocol/tasks opt-in added by CallToolAsTaskAsync.
Merge JSON objects recursively instead.

Fixes modelcontextprotocol#1920

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.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

None yet

1 participant