Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,17 @@ Tokens are omitted from durable workspace metadata. Launch configuration avoids

Sources: [HTTP host](src/mcp/runtime/BuiltInMcpHttpHost.ts), [tool registrar](src/mcp/runtime/createBuiltInMcpServer.ts), [launch configuration](src/providers/shared/runtime/builtInMcpLaunch.ts).

**User MCP servers (#1143).** Users can also attach their own MCP servers to Claude and Codex agents.

- **Storage.** Main owns them in `mcp-servers.json`, stored in the de facto `mcpServers` entry shape. Secret values live in separate `safeStorage` blobs, and entries refer to them as `${input:id}`.
- **Launch.** The renderer sends only a pane's explicit per-agent choices, as `user:<id>` keys in the same override map as built-in domains. At launch, main applies the per-provider defaults, secret readiness, transport support, Codex name collisions and Claude's enterprise MCP policy. It passes the result to the providers.
- **Claude.** User entries are added to the same private config file as the built-in server. Secrets are `${VAR}` references expanded from the process environment.
- **Codex.** User servers become `--config mcp_servers.<name>.*` overrides. Header values go through `env_http_headers`, and stdio secrets through `env_vars`.
- **Failure handling.** A requested server that cannot attach is reported (`user-mcp-unavailable`) and never fails the launch. The attached ids are an observed backend fact (`userMcpServerIds`), like `builtInMcpDomains`.
- **Config files.** Provider config files are never written. The user-scope servers each CLI loads itself are only read, to list them and to detect collisions.

Sources: [service](src/main/userMcp/service.ts), [translators](src/providers/shared/runtime/userMcpLaunch.ts), [model and import](src/shared/userMcp), [design](docs/superpowers/specs/2026-09-22-user-mcp-servers-design.md).

#### 5.6.2 Domains and scope

| Domain | Tools/responsibility | Scope notes |
Expand Down
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,31 @@ a running session can move mid-task among Claude Code, Codex, and OpenCode.
<img src="docs/screenshots/orchestration.png" alt="Agent Code agent index with orchestration MCP tool calls (send_prompt, wait_agents, read_agent, close_run) running in a live session" />
</p>

- **TLDR peek** — enable **TLDR MCP** for an agent, then hold **Cmd+L** to
- **MCP servers** — add any MCP server (stdio, HTTP or SSE) by pasting the
config from its README, for example Beeper Desktop's, and choose per provider
which ones new Claude and Codex agents get. **Settings → MCP** shows Agent
Code's own MCP servers and yours in one grid with a column per provider, and
**Agent MCP Servers…** changes one agent's set with a single reload. Tokens
are stored encrypted and reach the server through environment variables,
never a config file or the command line. Servers the CLIs already load from
their own config are listed read-only and can be copied in.
- **TLDR peek** — turn on **TLDR** for an agent, then hold **Cmd+L** to
see each visible agent’s latest short status centered over its pane.
A small footer shows **Last active** and **Note written** independently, using
relative times and calendar dates for older activity. Release to return. The
**TLDR** palette command also opens the preview; Escape dismisses it. Reporting
is off by default. MCP settings apply to new agents and existing agents on their
next reload, including the managed reporting skill. Explicit per-agent choices
take priority; **Use Global MCP Settings** clears those choices and reloads the
in **Agent MCP Servers…** take priority; its Reset clears them and reloads the
agent. Claude and Codex agents with TLDR are asked to set their goal on the
first prompt (through Goal instead when Goal MCP is also on), and at turn end to update after work that used tools without a
report; the footer notes when that check is not running. **View TLDR History**
shows how an agent's status evolved. The editor keeps Cmd+L Select Line.
- **Goal peek** — enable **Goal MCP** for an agent, then hold **Cmd+G** to see
- **Goal peek** — turn on **Goal** for an agent, then hold **Cmd+G** to see
what each visible agent’s work is for, next to the TLDR’s where-it-is status.
Agents set a goal once they understand a task and change it only when the
direction changes, so it stays meaningful while the TLDR moves. Goal has its
own MCP setting, off by default, and works with or without TLDR; only the agent
own row in Settings → MCP, and works with or without TLDR; only the agent
writes it. Claude and Codex agents with Goal are asked for one at the first
prompt and at turn end if it is still missing. **View TLDR History** shows goal
changes alongside status updates. The editor keeps Cmd+G Find Next.
Expand Down
119 changes: 119 additions & 0 deletions docs/superpowers/plans/2026-09-22-user-mcp-servers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# MCP Servers: Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task by task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** One MCP interface for every MCP server. Users can:
- add any MCP server by pasting its README snippet;
- keep its secrets encrypted;
- choose per provider which servers new agents get, for Agent Code's built-in servers and their own alike;
- override those choices per agent with one staged reload;
- see and copy in the servers the CLIs already load directly.

Agents receive user servers when they launch, through the path the built-in MCP servers already use. Provider config files are never written.

**Spec:** `docs/superpowers/specs/2026-09-22-user-mcp-servers-design.md`. Its **Revision 2** section overrides anything in the rest of the spec that conflicts with it. Read Evidence, Decisions and Revision 2 before starting any task.

**Issue:** #1143 (Refs #244). **Status:** user-approved 2026-09-22 (plan auto-approved); Tasks 1–8 implemented on this branch. Verification notes are in the PR.

**Working tree:** `.worktrees/user-mcp-servers`, branch `feat/user-mcp-servers`, based on `origin/main` `672d0941`. Submodules are initialized and `node_modules` is symlinked. Use Node 24 for vitest, because Node 25 breaks happy-dom.

**Conventions:**
- Write thick WHY comments at every code site that enforces a decision.
- Use Conventional Commits with scope `mcp`.
- Test fixtures are the real published Beeper snippets.
- Verify with `npx tsc -b` and vitest once at the end.
- Never launch the app.

---

### Task 1: Shared model (`src/shared/userMcp/`)
- [x] `types.ts`:
- `UserMcpServer`, `UserMcpServerEntry`, `UserMcpInput` and `UserMcpDocument`.
- The view and problem types.
- `USER_MCP_PROVIDERS` (`claude`, `codex`) and the reserved names.
- `userMcpOverrideKey(id)` and `userMcpOverridesFrom(map)`.
- [x] `validate.ts`:
- Name rules, entry validation and type normalization.
- The rule that `${input:…}` may appear only in `env` and `headers` values.
- The support matrix (SSE is Claude-only).
- `coerceUserMcpDocument`, which keeps unknown keys and flags malformed servers instead of dropping them.
- [x] `inputs.ts`: scan and substitute `${input:id}`.
- [x] `importConfig.ts`:
- Accepts the `mcpServers`, VS Code `servers`/`inputs`, bare-map and bare-entry forms.
- Moves every literal env and header value into a secret input, returned as `pendingSecrets`.
- [x] Tests for each of the above, using the Beeper fixtures.

### Task 2: Launch translators (`src/providers/shared/runtime/userMcpLaunch.ts`)
- [x] `userMcpSecretVariable`: deterministic variable names (needed so Claude's OAuth key stays stable).
- [x] `claudeUserMcpEntries`: builds Claude's config entries.
- [x] `addCodexUserMcpLaunchConfig`: builds the Codex arguments, and drops a server whose `env_vars` collide with another's.
- [x] Widen `createPrivateClaudeMcpConfig(builtIns, userEntries)`.
- [x] Golden tests, including one asserting that no secret appears in argv.

### Task 3: Main service (`src/main/userMcp/`)
- [x] `store.ts`: an atomic write of `STATE_DIR/mcp-servers.json` with mode 0600. A corrupt file is preserved rather than overwritten.
- [x] `secrets.ts`: `safeStorage` blobs, with only a hint ever returned.
- [x] `nativeServers.ts`:
- Lists the CLIs' own user-scope servers for Claude and Codex.
- Collects the Codex names used for the collision check.
- Detects Claude's managed-policy lock.
- [x] `service.ts`:
- Snapshot and mutations, run through a serialized queue.
- `resolveForLaunch(provider, overrides, cwd)`, which returns `{ servers, attachedIds, dropped }`.
- A change emitter.
- [x] IPC in `src/main/ipc/userMcp.ts`, the preload API in `src/preload/api/userMcp.ts`, and wiring in `src/main/index.ts`.
- [x] Tests for the store, secrets, resolution and native parsing.

### Task 4: Session wiring (main and providers)
- [x] Add `userMcpOverrides` to the spawn and recover options.
- [x] Add `userMcpServerIds` to the snapshot, spawn result and recover result.
- [x] `SessionManager` resolves user servers beside `builtInMcpServers` and records the attached ids per session.
- The Codex replacement restore reuses the recorded overrides.
- It emits `user-mcp-unavailable`, which the forwarder broadcasts.
- [x] Claude and Codex sessions accept `userMcpServers`.
- [x] Tests: a missing secret still spawns; the token is absent from argv.

### Task 5: Renderer model
- [x] Per-provider `defaultBuiltInMcpDomains`, covering:
- type and coercion;
- the resolver picking the provider's list;
- the refs input type;
- the `store.ts` comment.
- [x] `normalizeBuiltInMcpOverrides` keeps `user:` keys.
- [x] `clonedMcpOverrides` keeps them too.
- [x] Every renderer spawn and recover call site sends `userMcpOverrides`, and the pane meta stores `userMcpServerIds`.
- [x] `features/mcp/store.ts`: a mirror of main's snapshot plus a sync hook, mounted in `App.tsx`.
- [x] Global toast for `user-mcp-unavailable`.

### Task 6: Settings → MCP
- [x] Add the `mcp` category.
- [x] Add the `mcp-servers` marker row, which replaces the eight built-in default toggle rows.
- [x] Move `external-control` into the new category.
- [x] `McpServersRow`:
- The grid of built-in and user servers, with a column per enabled provider.
- Master switches, problem chips, and the ⋯ actions.
- The native section with Copy in.
- [x] `McpServerDialog`:
- Add and edit, with paste import and a JSON editor.
- Masked secret fields.
- Sign in help shows a copyable `codex mcp login <name> -c 'mcp_servers.<name>.url=…'` command and Claude `/mcp` guidance. Changed during implementation: the command is shown rather than run in a new terminal pane, because login opens a browser and waits on the user, and that belongs in a terminal the user controls. Codex login reads the effective config including `-c`, so the stored token is reused by every later launch.
- [x] `ui.openSettings(category?)`.

### Task 7: Commands and the per-agent modal
- [x] `AgentMcpServersModal` and its surface: staged toggles, one reload, a reset row, and Root Management going through its confirmation dialog.
- [x] New commands: `mcp-servers`, `add-mcp-server` and `agent-mcp-servers`.
- [x] Retire `use-global-mcp-settings` and the eight `enable-*-mcp` toggles.
- [x] Update the control references, `catalog.test.ts`, `taxonomy.test.ts` and the affected renderer tests.

### Task 8: Documentation, verification and PR
- [x] Update README and ARCHITECTURE.
- [x] Run `npx tsc -b` and vitest.
- [x] Real-binary check of the generated Codex `-c` arguments with `codex mcp list`.
- [ ] Open the PR `feat(mcp): manage MCP servers per provider and per agent` with `Fixes #1143` and `Refs #244`. Run two orchestrated reviewers, fix the valid findings, wait for CI, and do not merge.

## Out of scope (follow-up issues)
- Add from MCP Registry.
- OpenCode and Grok user servers.
- User servers for workflow subagents.
- Project-scope native server listing.
- #244 hosted extension servers.
Loading
Loading