feat: serve toolset-backed mcp_servers under the wrapper's configuration - #5918
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TCzhsvUYz5VMieXYaQUC2Z
🦋 Changeset detectedLatest commit: d1c7863 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
|
Running ultrareview automatically — This cross-cutting MCP hosting migration changes RBAC keying, audience validation, endpoint resolution fallback, and serving configuration across 25 files — authorization bypass or a broken fallback here would affect every hosted MCP server once the backfill lands.. I'll post findings when complete. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Ultrareview completed in 7m 47s
All reported issues were addressed across 25 files
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TCzhsvUYz5VMieXYaQUC2Z
There was a problem hiding this comment.
All reported issues were addressed across 15 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TCzhsvUYz5VMieXYaQUC2Z
End-to-end verification (this PR's changes)Context: all three Phase-1 branches (#5917, #5918, #5919) were merged into a scratch tree (zero conflicts), the full server suite ran on the merged tree — 14,334 tests, 1 failure: a pre-existing skills-subsystem clock flake, passes in isolation, unrelated to these PRs — and a local stack was booted from the merged tree with simulated backfill rows (a toolset-backed Scenarios exercising this PR:
One expected nuance, not a bug: with the wrapper disabled but the toolset's own flags public, the toolset's legacy No panics or unexpected errors in server logs. All test rows and flag changes were reverted after the run (verified by query). 🤖 Generated with Claude Code |
AIM-21
Summary
mcp_endpointsrow to a toolset-backedmcp_serversrow, hosting configuration now comes from the wrapper: a newhostedServingresolved-config value carries visibility, the user-session issuer, the RBAC resource id, and the tool-variation-group override into the toolset serving path, replacing the previous boolean parameters.toolsets.mcp_is_publicandtoolsets.user_session_issuer_idare no longer consulted when a wrapper is present; tools, resources, prompts, environment, tool selection mode, and external OAuth still come from the toolset.mcp:connectchecks key onmcp_servers.idfor wrapper-governed requests — connection-level, per-tool (tools/call and tools/list), and the consent tool picker. Meta-member and internal agent-workflow paths deliberately keep toolset-keyed checks.x/mcpdefault is removed). Bearer validation accepts the legacy toolset-URN audience for toolset-backed wrappers only, on audience mismatch only, counted bymcp.legacy_audience_accepted{user_session_issuer.id}; stored consent tool-selection resources get the same legacy acceptance so restricted sessions are not forced into reauth.mcpendpoints.BySlugAndCustomDomaindistinguishes an address miss from a resolvable-but-unavailable address (disabled visibility, dangling backend) via a newErrEndpointUnavailable. Only a true miss falls through to the legacy toolset lookup; a disabled wrapper can no longer resurrect its slug through the toolset, on any surface.mcp.toolset_slug_fallback{gram.mcp.entry_point}increments at all seven legacy resolve points (ServePublic, GET/DELETE proxy, both well-known handlers, the OAuth family viaLoadResolvedMcpEndpointBySlug, the install page resolver, cached-challenge resume), only when the legacy lookup resolves a live toolset so scanner probes cannot keep it nonzero. The hosted serving path also stampsgram.mcp_server.idon the request span when a wrapper is present.No production behavior changes on deploy: no toolset-backed
mcp_serversrows exist yet, so the wrapper-governed paths are dormant until the backfill populates them.Motivation
Hosted (toolset-backed) MCP servers are migrating under
mcp_servers/mcp_endpoints. This PR establishes the runtime contract that migration depends on: the wrapper governs hosting configuration, the audience and RBAC conventions converge on the server id with a counted compatibility window for outstanding legacy bearers, and the two counters introduced here are the merge gate for later removing thetoolsets.mcp_slugfallback entirely. It also closes the resolver hole behind INC-420, where a disabled server could keep serving through the legacy fallback.🤖 Generated with Claude Code
https://claude.ai/code/session_01TCzhsvUYz5VMieXYaQUC2Z
Summary by cubic
When a request resolves through an
mcp_endpointsrow to a toolset-backedmcp_serversrow, hosting configuration now comes from the wrapper: visibility, issuer gating, the RBAC resource id formcp:connect, and the variation-group override. The toolset'smcp_is_publicanduser_session_issuer_idcolumns are no longer consulted on that path, and the JWT audience now binds to the issuer URN with the route base taken from the inbound surface instead of the hardcodedx/mcpdefault.Migration compatibility
mcp.legacy_audience_accepted, so pre-backfill sessions aren't forced into reauth.toolsets.mcp_slugresolve points incrementmcp.toolset_slug_fallbackby entry point, but only when the lookup resolves a live toolset.Endpoint authority
mcpendpoints.BySlugAndCustomDomainnow returnsErrEndpointUnavailablefor a resolvable-but-unavailable address instead of a plain not-found.gram.mcp_server.idon the request span.No production behavior changes on deploy: no toolset-backed
mcp_serversrows exist yet, so the wrapper-governed paths stay dormant until the backfill populates them.Written for commit d1c7863. Summary will update on new commits.