From 5d2f6b4d8a4901aeea3c89b5c4e1efe1cf64b4cd Mon Sep 17 00:00:00 2001 From: 7Sageer <125936732+7Sageer@users.noreply.github.com> Date: Thu, 20 Aug 2026 16:32:20 +0800 Subject: [PATCH] docs(mcp): note probe credential effects and plane semantics --- packages/agent-core-v2/AGENTS.md | 2 +- .../src/app/mcpManagement/mcpManagement.ts | 11 +++++++---- packages/kap-server/AGENTS.md | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/agent-core-v2/AGENTS.md b/packages/agent-core-v2/AGENTS.md index 53d6d7d55..69d2bdb29 100644 --- a/packages/agent-core-v2/AGENTS.md +++ b/packages/agent-core-v2/AGENTS.md @@ -65,7 +65,7 @@ One accepted exception: `features/tower/protocol` manages the `.tower/` director ## MCP management plane -The App scope owns the process-wide MCP management surface, split across three domains: `mcpConfig` (`src/app/mcpConfig/` — the `[mcp]` config section, the layered mcp.json loader with per-entry origins, `IMcpConfigStore` as the single write point for the user-level `mcp.json`, `IMcpOAuthStore` credential persistence, and `IMcpOAuthService`, the process-wide OAuth orchestrator with credential events, single-flight refresh, and proactive refresh timers), `mcpRegistry` (`IMcpRegistryService` — the unified read view over the file layers and plugin manifests with `source`/`origin`/`mutable`; runtime-name collisions keep both entries, and runtime resolution ranks an enabled plugin entry above the file layers), and `mcpManagement` (`IMcpManagementService` — guarded CRUD, connection-test probes, the locator-addressed inspection/auth-status surface, and locator-addressed OAuth begin/complete/cancel/reset with ambiguity rejection). The engine services are ungated; the edge exposure (kap-server routes, klient facade) gates on the `mcp_management` flag. On the Workspace side, `workspaceMcpConfig` merges the same sources (same plugin-over-file precedence), watches the files and plugin reloads, follows the store's `onDidWrite` for immediate management-plane reloads, and publishes fingerprint diffs that `workspaceMcp` applies to the handler-shared `McpConnectionManager` (tombstones for removals); `workspaceMcp` also subscribes the OAuth service's credential events to reconnect affected entries. Session overlays (`session/mcp`) keep caller-injected ephemeral servers session-local. +The App scope owns the process-wide MCP management surface, split across three domains: `mcpConfig` (`src/app/mcpConfig/` — the `[mcp]` config section, the layered mcp.json loader with per-entry origins, `IMcpConfigStore` as the single write point for the user-level `mcp.json`, `IMcpOAuthStore` credential persistence, and `IMcpOAuthService`, the process-wide OAuth orchestrator with credential events, single-flight refresh, and proactive refresh timers), `mcpRegistry` (`IMcpRegistryService` — the unified read view over the file layers and plugin manifests with `source`/`origin`/`mutable`; runtime-name collisions keep both entries, and runtime resolution ranks an enabled plugin entry above the file layers; a project layer joins the view only when the queried cwd itself is trusted, matching what the workspace runtime would load), and `mcpManagement` (`IMcpManagementService` — guarded CRUD (a mutable user-level entry stays writable past a read-only collision), connection-test probes, the locator-addressed inspection/auth-status surface, and locator-addressed OAuth begin/complete/cancel/reset with ambiguity rejection plus an idle timeout that cancels abandoned flows). The engine services are ungated; the edge exposure (kap-server routes, klient facade) gates on the `mcp_management` flag. On the Workspace side, `workspaceMcpConfig` merges the same sources (same plugin-over-file precedence), watches the files and plugin reloads, follows the store's `onDidWrite` for immediate management-plane reloads, and publishes fingerprint diffs that `workspaceMcp` applies to the handler-shared `McpConnectionManager` (tombstones for removals); `workspaceMcp` also subscribes the OAuth service's credential events to reconnect affected entries. Session overlays (`session/mcp`) keep caller-injected ephemeral servers session-local. ## Session index diff --git a/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts b/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts index deb0a6c4a..3eb35a17a 100644 --- a/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts +++ b/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts @@ -123,15 +123,18 @@ export interface IMcpManagementService { /** * Legacy auth-status surface: per-server OAuth state over the registry - * catalog. Offline by default (stored-grant classification only); - * `verify: true` probes a real connection. Never mutates credentials. + * catalog. Offline by default (stored-grant classification only, never + * mutates credentials); `verify: true` probes a real connection, which may + * refresh or invalidate stored credentials and broadcast the events. */ listAuthStatuses(query?: McpAuthStatusQuery): Promise; /** * The locator-addressed catalog plus a batched real-connection probe of - * every OAuth candidate. A runtime name shared by enabled entries cannot - * be probed (or credentialed) unambiguously and reports `unavailable`. + * every OAuth candidate; a probe that hits an expired grant may refresh or + * invalidate stored credentials and broadcast the events. A runtime name + * shared by enabled entries cannot be probed (or credentialed) + * unambiguously and reports `unavailable`. */ inspectServers(targets?: readonly McpServerLocator[]): Promise; diff --git a/packages/kap-server/AGENTS.md b/packages/kap-server/AGENTS.md index 90f7ac9e3..d98befd06 100644 --- a/packages/kap-server/AGENTS.md +++ b/packages/kap-server/AGENTS.md @@ -15,7 +15,7 @@ No comments — no file headers, no section banners, no statement-level narratio `GET /api/v2/sessions` (`src/routes/v2/sessions.ts`, mounted by `src/routes/registerApiV2Routes.ts`) is the first endpoint of the v2 API. The v2 surface shares v1's wire conventions: every response is wrapped in the `{ code, msg, data, request_id }` envelope with the business outcome in `code` (`40001` invalid query params with `details`, `40922` page_token mismatch), and the HTTP status only reports server-/transport-level outcomes (401 from the global auth hook, `50001` via the catch-all error hook). Pagination is an opaque `page_token` (base64url JSON: version + sha256 query-condition fingerprint + keyset position) — any condition flip mid-pagination fails 40922. Response domains are grouped (`workspace` / `meta` / `activity` always; `git` opt-in via `include=git`, deduped per unique cwd with a 60s TTL cache over `IGitService`, all git/gh failures degrading to cached null fields). Sorts/filters are applied at the edge over the index's canonical `updatedAt desc, id desc` drain, so all three sort orders share one comparator + cursor encoding; `activity.status` maps the core `ISessionActivityView` facts (pending interaction > active turn > failed last turn > idle; cold sessions are always `idle`). -`/api/v2/mcp/*` (`src/routes/v2/mcp.ts`) exposes the agent-core-v2 `mcpManagement` plane: CRUD on the user-level `mcp.json` (`GET/POST/PUT/DELETE /mcp/servers[/{name}]`; `PUT` takes a name-less config body, the path owns the identity), a connection-test probe and the locator-addressed inspection catalog (`POST /mcp/servers:test` / `:inspect`, declared with the doubled-colon static-segment convention), the auth-status surface (`GET /mcp/auth-statuses?verify=`), and the locator-addressed OAuth flow operations (`POST /mcp/auth:begin|complete|cancel|reset`). Every route runs a shared preHandler gate on the `mcp_management` experimental flag (checked per request after `IConfigService.ready`) that answers `40928 mcp.management_disabled` while off; engine `Error2`s map `mcp.server_not_found` → `40408` and `request.invalid` / `config.invalid` → `40001`. The klient facade mirrors the same surface as `global.mcp.*` with identical wire codes, plus the name-only `global.mcp.resolveByName` helper (REST clients compose locators from the `GET /mcp/servers` catalog instead). +`/api/v2/mcp/*` (`src/routes/v2/mcp.ts`) exposes the agent-core-v2 `mcpManagement` plane: CRUD on the user-level `mcp.json` (`GET/POST/PUT/DELETE /mcp/servers[/{name}]`; `PUT` takes a name-less config body, the path owns the identity), a connection-test probe and the locator-addressed inspection catalog (`POST /mcp/servers:test` / `:inspect`, declared with the doubled-colon static-segment convention), the auth-status surface (`GET /mcp/auth-statuses?verify=`), and the locator-addressed OAuth flow operations (`POST /mcp/auth:begin|complete|cancel|reset`). Every route runs a shared preHandler gate on the `mcp_management` experimental flag (checked per request after `IConfigService.ready`) that answers `40928 mcp.management_disabled` while off; engine `Error2`s map `mcp.server_not_found` → `40408`, `request.invalid` / `config.invalid` → `40001`, and `mcp.oauth_failed` → `40929`. `auth:complete` is a long poll (up to the flow's `timeoutMs`): the server disables Node's default `requestTimeout` (`start.ts`), and the handler aborts the engine wait when the client connection closes early. The klient facade mirrors the same surface as `global.mcp.*` with identical wire codes, plus the name-only `global.mcp.resolveByName` helper (REST clients compose locators from the `GET /mcp/servers` catalog instead). ## Transcript surface