Skip to content

feat(agent-core-v2): add the unified MCP management plane - #3002

Draft
7Sageer wants to merge 1 commit into
mainfrom
feat/v2-mcp-management-plane
Draft

feat(agent-core-v2): add the unified MCP management plane#3002
7Sageer wants to merge 1 commit into
mainfrom
feat/v2-mcp-management-plane

Conversation

@7Sageer

@7Sageer 7Sageer commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

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.json with 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.json store, 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 from workspaceMcpConfig, now with per-entry origins and __proto__-safe parsing); IMcpConfigStore, the single write point for the user-level mcp.json over the filesystem byte store (byte-identical to v1's format, mutation tail, onDidWrite event); and IMcpOAuthService, 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, offline tokenState, 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 with source / 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.
  • Workspace runtime — collision precedence flipped to match v1 (enabled plugin > file layers; shadows revive when the winner disappears), and management writes reload immediately via onDidWrite instead of waiting out the watch debounce. WorkspaceMcpService subscribes the shared OAuth service's credential events and reconnects affected entries (pending entries defer until their initial connect settles).
  • Edge — the node-sdk v2 facade's 16 global MCP methods delegate to the engine service (deleting ~400 lines of in-process duplication); kap-server exposes /api/v2/mcp/* (12 routes) and klient gains global.mcp.*. The engine services are deliberately ungated so in-process hosts can delegate today; the mcp_management flag (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.json writes and a real token endpoint) kept green as the behavior contract.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, 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-default mcp_management flag, so nothing here is perceivable on a shipped surface yet; a changeset should land when the flag flips to default-on.
  • Ran gen-docs skill, 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.

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.
@changeset-bot

changeset-bot Bot commented Aug 17, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2304554

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

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