Skip to content

Migrate both MCP hosts to ModelContextProtocol SDK 2.0 (MCP 2026-07-28 spec) - #2004

Merged
erikdarlingdata merged 1 commit into
devfrom
mcp-sdk-2-migration-1990
Aug 3, 2026
Merged

Migrate both MCP hosts to ModelContextProtocol SDK 2.0 (MCP 2026-07-28 spec)#2004
erikdarlingdata merged 1 commit into
devfrom
mcp-sdk-2-migration-1990

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

What does this PR do?

Fixes #1990. Takes the ModelContextProtocol 1.4.1 → 2.0.0 major deliberately, the way the issue prescribed after #1822's grouped auto-bump half-applied it: the version moves in every referencing project in one commit (PerformanceMonitor.Common, Lite, Darling.Service, deprecated/Dashboard) with all six affected packages.lock.json files regenerated together under the CI-pinned SDK 10.0.302. (A first regeneration pass under SDK 10.0.300 silently downgraded framework packages 10.0.10 → 10.0.8 in the locks — caught and redone; worth knowing for future lockfile work on non-CI machines.)

No code changes were needed. Walking the issue's checklist:

  1. Stateless-by-default HTTP — a no-op: both hosts have run Stateless = true explicitly since MCP server doesn't expose tools in Google Antigravity #1074 (clients that don't echo Mcp-Session-Id otherwise connect but list zero tools). The 2.0 default now simply matches what we ship. Every exposed tool already works without session state — see the live verification below.
  2. Discovery-first negotiation — the Host-header guard (Security: MCP hosts lack a Host-header allowlist (DNS rebinding) - Darling + Lite #1648) and the network-mode bearer/CIDR gates are pipeline middleware installed before MapMcp, so whatever endpoints 2.0 adds inherit them structurally. Verified live, not just structurally (below).
  3. Deprecated APIs (Roots/Sampling/Logging) — audited both hosts and the shared tool plumbing: no usage (the only matches are ShowPlan SamplingPercent false positives). McpSchemaCompat (the Gemini schema rewriter, the deepest SDK-API consumer we have) compiles unchanged.
  4. Caching hints / headers / OAuth changes — inert for these hosts; nothing references the affected surfaces.
  5. Dependabot ignore rule removed per Dependabot: target dev, defer ModelContextProtocol majors to #1990 #1991's "remove this once Migrate to ModelContextProtocol SDK 2.0 (MCP 2026-07-28 spec): stateless-by-default HTTP, deprecated-API audit, discovery-first negotiation #1990 lands" — SDK patches/minors resume flowing through the weekly group.

How was this tested?

  • Live run of the real Darling service on this branch (SDK 2.0 packages) against a scratch TimescaleDB store: initialize returns the correct envelope with no session header (stateless confirmed); tools/list with no session round-trip returns all 89 tools; tools/call list_servers executes against the store; and a request with a non-loopback Host is rejected 400 by the DNS-rebinding guard before any 2.0 endpoint (evil.example.localtest.me resolved to 127.0.0.1).
  • Local builds of Common and Darling.Service: 0 warnings, 0 errors. Lite/Dashboard/tests compile in CI (the MCP surface pins — DarlingMcpServerAdminToolsTests, alert-settings key parity, HostHeaderGuard install-order — all run there).
  • The identical SDK 2.0 hosting surface (AddMcpServer/WithHttpTransport/WithTools/MapMcp) was validated end-to-end on Performance Studio first (deps: Bump ModelContextProtocol and ModelContextProtocol.AspNetCore PerformanceStudio#422): stateless handshake, tool listing/calls, and Host/Origin guard behavior all confirmed there against a booted host.
  • Restore is clean under locked mode semantics: no NU1605/NU1004 anywhere — the exact failure class that killed Bump the nuget group with 2 updates #1822.

Dogfood plan after merge: nightly → monitor-box upgrade → this session's own MCP client (89-tool surface) reconnecting against the upgraded box is the final live-client check the issue asks for.

Which component(s) does this affect?

  • Lite
  • Darling
  • Lite Tests
  • Darling Tests
  • SQL collection scripts
  • Documentation
  • Full Dashboard (deprecated)
  • CLI Installer (deprecated)

Checklist

  • I have read the contributing guide
  • My code builds with zero warnings (dotnet build -c Debug)
  • I have tested my changes against at least one SQL Server version
  • I have not introduced any hardcoded credentials or server names

🤖 Generated with Claude Code

The 1.4.1 -> 2.0.0 major, taken deliberately after a grouped auto-bump
demonstrated the failure mode (#1822: half-applied across projects,
NU1605/NU1004 across every lockfile). The version moves in every
referencing project in one commit - Common, Lite, Darling.Service,
deprecated/Dashboard - with all six affected lockfiles regenerated
together under the CI-pinned SDK (10.0.302; a first pass under 10.0.300
silently downgraded framework packages 10.0.10 -> 10.0.8, so the exact
SDK matters for lockfile work).

No code changes were needed:

- Stateless-by-default HTTP is a no-op here: both hosts have set
  HttpServerTransportOptions.Stateless = true explicitly since #1074
  (clients that don't echo Mcp-Session-Id otherwise connect but list
  zero tools).
- Deprecated-API audit (Roots/Sampling/Logging): no usage in either
  host or the shared tool plumbing (the only greps are ShowPlan
  SamplingPercent false positives).
- McpSchemaCompat (the Gemini schema rewriter) compiles unchanged
  against 2.0's McpServerTool.Create/McpServerToolCreateOptions.

Live-verified against the real Darling service running this branch on
the SDK 2.0 packages (local run against a scratch TimescaleDB store):
initialize returns the correct envelope with NO session header;
tools/list returns all 89 tools with no session round-trip; tools/call
executes against the store; and the #1648 DNS-rebinding guard still
rejects a non-loopback Host with 400 ahead of MapMcp's 2.0
discovery-first endpoint surface (it is pipeline middleware installed
before MapMcp, so new endpoints inherit it structurally). The same SDK
2.0 hosting surface was separately validated end-to-end on Performance
Studio (erikdarlingdata/PerformanceStudio#422) before this migration.

With the major taken, the dependabot ignore rule deferring
ModelContextProtocol* majors to #1990 is removed (per #1991's "remove
this once #1990 lands"), so SDK patches/minors resume flowing through
the weekly group.

Closes #1990

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review

Reviewed the diff (gh pr diff 2004) plus the checked-out branch source for the MCP hosts. This is a clean, dependency-only migration — no findings.

What it does: Bumps ModelContextProtocol/ModelContextProtocol.AspNetCore 1.4.1 → 2.0.0 in lockstep across every referencing project (PerformanceMonitor.Common, Lite, Darling.Service, deprecated/Dashboard), regenerates all six affected packages.lock.json files under the CI-pinned SDK, and removes the temporary Dependabot major-version ignore rule for ModelContextProtocol* now that the deliberate migration has landed.

Verified during review:

  • Version consistency: grep across all four .csproj files confirms every one now pins 2.0.0 — no project was left on 1.4.1 (the exact half-applied-bump failure mode from Bump the nuget group with 2 updates #1822 that this PR's own CHANGELOG entry describes).
  • Lite/Darling/Dashboard parity: all three MCP hosts moved together; lockfiles for Lite, Lite.Tests, Darling/Darling.Tests, Darling/PerformanceMonitor.Darling.Viewer, deprecated/Dashboard, deprecated/Dashboard.Tests are all regenerated consistently (same resolved versions/hashes for shared transitive packages like Microsoft.Extensions.AI.Abstractions 10.8.3, Microsoft.Extensions.* 10.0.10).
  • No source changes needed, and the claim checks out: Stateless = true is already set in Lite/Mcp/McpHostService.cs, Darling/.../DarlingMcpHostService.cs, and deprecated/Dashboard/Mcp/McpHostService.cs, and MapMcp() is called after the Host-header/CIDR guard middleware in all three — matches the PR description's claim that 2.0's stateless-by-default and discovery-first behavior are no-ops here.
  • No leftover 1.4.1 references anywhere outside the CHANGELOG's historical entries (which correctly describe past state, not current).
  • The one non-MCP lockfile delta (Installer.Core 3.2.0 → 3.3.0 picked up in deprecated/Dashboard.Tests/packages.lock.json) is just the lock regeneration catching up to the <Version> already set in deprecated/Installer.Core/Installer.Core.csproj — not something this PR introduced or needs to account for.

No correctness, security, parity, or performance concerns. The lockfile-only diff is exactly what's expected for a version bump of this shape.

@erikdarlingdata
erikdarlingdata merged commit c180b8f into dev Aug 3, 2026
4 checks passed
@erikdarlingdata
erikdarlingdata deleted the mcp-sdk-2-migration-1990 branch August 3, 2026 11:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant