feat(agent-core-v2): add the unified MCP management plane - #3002
Draft
7Sageer wants to merge 1 commit into
Draft
Conversation
Port the v1 MCP management plane (#2858) onto the v2 DI x Scope engine: - App-scope IMcpOAuthService shared by every workspace handler and session overlay: credential events, single-flight refresh, proactive refresh timers, OAuthTokenTransaction-serialized writes, offline tokenState, shutdown. Providers read tokens through the store so grants written or revoked by another process are honored immediately; http/sse transports ride the transaction fetch. - IMcpConfigStore: the single write point for the user-level mcp.json over the filesystem byte store, byte-identical to v1's format, with per-entry validation, name normalization, __proto__-safe parsing, a mutation tail, and an onDidWrite event. - IMcpRegistryService: the unified read view over the layered config files (with per-entry origins) and plugin manifests (full descriptors incl. disabled, with provenance); collisions stay visible and runtime resolution ranks an enabled plugin above the file layers. - IMcpManagementService: guarded CRUD, connection-test probes, the locator-addressed inspection/auth-status surface, and locator-addressed OAuth begin/complete/cancel/reset with ambiguity rejection. Engine services stay ungated; the mcp_management flag gates the edge exposure. - Workspace runtime aligns with v1 precedence (an enabled plugin entry wins over the file layers, shadows revive), and management writes reload immediately via onDidWrite instead of the watch debounce. - node-sdk v2 facade delegates to the engine service (deleting its in-process duplication); kap-server exposes /api/v2/mcp/* and klient gains global.mcp.*, both flag-gated.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related Issue
No tracking issue — the problem is explained below. This is the v2 follow-up to #2858 (which unified the v1 MCP management plane and left the v2 side as an in-process SDK facade).
Problem
v1 has a unified MCP management plane (#2858): one registry over the layered config files / plugin manifests / caller injection, a single write point for the user-level
mcp.jsonwith live-session reconciliation, and a process-wide OAuth service with credential events, single-flight + proactive refresh, and serialized token writes.On the v2 engine none of that existed in-process: the node-sdk v2 facade hand-rolled the same surface in the SDK process (its own
mcp.jsonstore, throwaway connection managers, OAuth flow bookkeeping), which cannot propagate credential events to live sessions, suffers token-snapshot staleness (worked around with per-call service construction), and is unreachable for kap-server / klient clients (the server only had session-level list/restart). The v2 runtime also diverged from v1 on name-collision precedence (file won over plugins; v1 ranks an enabled plugin above the file layers).What changed
Ports the plane onto the v2 DI × Scope architecture, split by state lifetime:
mcpConfig(App) — the layered mcp.json loader (moved up fromworkspaceMcpConfig, now with per-entry origins and__proto__-safe parsing);IMcpConfigStore, the single write point for the user-levelmcp.jsonover the filesystem byte store (byte-identical to v1's format, mutation tail,onDidWriteevent); andIMcpOAuthService, the process-wide OAuth orchestrator shared by every workspace handler and session overlay — credential events (tokens-saved/tokens-invalidated/refresh-failed), single-flight refresh, proactive refresh timers,OAuthTokenTransaction-serialized writes, offlinetokenState, shutdown. Providers now read tokens through the store on every call (no construction-time snapshot), and the http/sse transport fetches ride the token transaction, matching v1.mcpRegistry(App) — the unified read view withsource/origin/mutable; collisions keep both entries, and runtime resolution ranks an enabled plugin entry above the file layers. Plugin provenance comes from a new full descriptor list (IPluginService.mcpServerEntries, disabled plugins included, strict on load failure so a guard never runs on a degraded view).mcpManagement(App) — guarded CRUD (read-only plugin / project-layer entries reject, disabled plugin descriptors never block), connection-test probes (inline config or registry-resolved name), the locator-addressed inspection / auth-status surface, and locator-addressed OAuth begin / complete / cancel / reset with shared-runtime-name ambiguity rejection.onDidWriteinstead of waiting out the watch debounce.WorkspaceMcpServicesubscribes the shared OAuth service's credential events and reconnects affected entries (pending entries defer until their initial connect settles)./api/v2/mcp/*(12 routes) and klient gainsglobal.mcp.*. The engine services are deliberately ungated so in-process hosts can delegate today; themcp_managementflag (default off) gates only the wire exposure (kap-server preHandler + klient dispatcher, both answering wire code 40928).Tests: ~150 new engine cases (OAuth service port of the v1 suite, store byte-parity, registry, management, workspace credential-event branches), kap-server route tests (flag on/off), klient contract parity + dual-transport conformance, and the existing node-sdk v1↔v2 parity suite (109 cases, incl. byte-identical
mcp.jsonwrites and a real token endpoint) kept green as the behavior contract.Checklist
gen-changesetsskill, or this PR needs no changeset. — No changeset: the plane lives on the experimental v2 engine and the wire exposure stays behind the off-by-defaultmcp_managementflag, so nothing here is perceivable on a shipped surface yet; a changeset should land when the flag flips to default-on.gen-docsskill, or this PR needs no doc update. — No user-doc update for an unreleased flag-gated surface; the package AGENTS.md files (agent-core-v2, kap-server) document the architecture.