---
title: MCP Servers (the outside tools your sessions can call)
---

# MCP Servers (manager + per-project/session control + usage tracking)

## What it is

### What it is

An **MCP server** (Model Context Protocol) is an external tool process Claude Code can talk to — Playwright, Gcloud, a third-party server, anything that speaks the MCP spec. The **MCP Servers** sidebar view does three things: (1) **manages your own custom servers** (add / edit / delete), (2) shows **per-server usage** (count, last-used, tool breakdown) so you can spot dead weight, and (3) is the home of the **+ Custom** manager. _Whether_ a server reaches a given session is decided by the per-project/per-session control layered on top of the global default — see "Controlling which servers a session gets" below.

## Where to find it

The **MCP Servers** entry in the sidebar — the manager and the usage list live behind it, and **+ Custom** starts a new server. A few built-in servers are switched on from **Settings**, next to the features that use them.

## How it behaves

**No AMC-built MCP server is composed into a session's `.mcp.json` any more** (owner decision, 2026-09-19). MemPalace, KMS, Google Workspace, Fathom, Image Studio and web-app verification were each removed from per-session composition; their launch toggles are gone from Settings. Their capabilities are not: the **KMS Vault** is reached through the control server's `/kms/*` routes (and the vault skill), MemPalace through its own routes and feature flag, and the rest through their own routes/CLIs — nothing needs a per-session tool process. What still composes is the third-party set below plus your own custom servers.

### Controlling which servers a session gets

Each MCP server resolves on/off **most-specific-first**: **session override → project default → global default**. Nothing changes for existing setups unless you set an override.

- **Global default** — the Settings toggles (Zapier, Playwright, Canva, Google Drive, Mobbin) + each custom server's "On by default". These are the _default for all sessions_. "Off" = installed-but-dormant.
- **Per project** — **Edit a project → MCP tools**: flip each tool on or off for that project's sessions.
- **Per session** — override for just that session, from **two** entry points: the session's **⋯ menu → MCP servers** any time, OR — on a brand-new session — the **"MCP servers"** button in the launch-config block, right next to the provider/model/thinking pickers. Both open the same on/off switch editor (titled **"MCP tools for this session"**) and write the same per-session override; it applies on the session's **next start** (MCP servers load when the CLI launches), so choosing at launch takes effect on the first message.

Scope covered: the composed built-ins (Zapier, Playwright, Canva, Google Drive, Mobbin) + all custom servers.

### Adding a custom server

1. **MCP Servers sidebar → + Custom** opens the manager.
2. **Add server** — name, key (the `.mcp.json` entry name), type (local `stdio` command, or remote `http`/`sse` URL), args, env vars / headers (secrets), and "On by default".
3. Secrets are **encrypted at rest** and never shown back (you re-enter to change them). A custom server is **off by default** until you switch it on per project/session.
4. **Edit / delete** from the same manager. Delete is confirm-gated.

### Install an official server (catalog)

The **Add MCP server** dialog opens with a searchable **catalog of 80+ official remote servers** — Nous Research's Hermes Agent set _plus_ official servers we independently verified beyond it (GitHub, HubSpot, Firecrawl, Perplexity, PagerDuty, Box, Zoom, and more; Linear, Notion, Figma, GitLab, Stripe, Datadog, Grafana, Sentry, Supabase, Vercel, Netlify, Cloudflare, Atlassian, Asana, Intercom, HuggingFace) — so you never have to hunt down a URL. It works like a plugin marketplace: nothing is installed until you choose it. The full, verified list lives in [/src/shared/mcp-install-catalog.ts](/src/shared/mcp-install-catalog.ts).

- **Browse or search** the list, then click **Install** on a server to add it — the row flips to **Installed** once it's in your list, and you can install several without closing the dialog.
- **Each row shows the service's own logo**, so you can spot the one you want at a glance. The artwork is bundled with the app (public-domain [Simple Icons](https://simpleicons.org) path data, generated into [/src/shared/mcp-brand-icons.generated.ts](/src/shared/mcp-brand-icons.generated.ts) by `npm run mcp-icons:reindex`) — the dialog never calls out to a logo service, so browsing the catalog leaks nothing about which servers you're looking at and works offline. A service with no bundled mark shows a neutral glyph instead: a missing logo is fine, a wrong one is not.
- **Nothing is added by default.** The catalog is just a list of what's _available_; installing is an explicit, per-item choice.
- **Same add path.** Install just pre-fills the name, remote URL, and transport, then runs the exact `addManagedMcp()` a manual server uses — so a catalog server behaves identically (full per-project/per-session control, delete from the same manager).
- **Sign-in is on first use.** These are remote servers that run their own OAuth login the first time a session actually connects — installing only _registers_ the server. GitLab's endpoint is Beta and needs a GitLab admin to enable it for your instance first (ClickUp is public beta); both caveats are shown on the row.
- The catalog is a small curated data file, [/src/shared/mcp-install-catalog.ts](/src/shared/mcp-install-catalog.ts) — every URL is verified against the vendor's own docs (a wrong URL is worse than no entry). Browse UI: `McpCatalogBrowser` in [/src/renderer/src/features/mcp-servers/](/src/renderer/src/features/mcp-servers/).

**From the CLI** — add any catalog server over the control server by POSTing its entry to the standard add route `POST /managed-mcp` (full-trust `amc-cli` token — the add route is secret-capable). Example (Linear):

```bash
curl -sS -X POST http://127.0.0.1:19519/managed-mcp \
  -H "Authorization: Bearer $(cat ~/.amc/cli-token)" \
  -H 'Content-Type: application/json' \
  -H "X-AMC-Source-Session-Id: $AMC_SESSION_ID" \
  -d '{"key":"linear","displayName":"Linear","transport":"http","url":"https://mcp.linear.app/mcp"}'
```

Look up any service's `key` / `transport` / `url` in [/src/shared/mcp-install-catalog.ts](/src/shared/mcp-install-catalog.ts).

### Usage tracking (unchanged)

1. **Sort** — Most / Least / **Never used** / Recently used / Alphabetic. "Never used" is the "what should I uninstall?" lens.
2. **Per-tool breakdown** — click a server to see its per-tool invocation table.
3. **Reset usage** — right-click a row (`UsageRowContextMenu`); footer **Clear usage** wipes all, both confirm-gated.
4. **Scan** — forces an immediate re-scan of `~/.claude/projects/**/*.jsonl`.

## For agents

### How it works

**Control** — a pure resolver [/src/shared/mcp-selection.ts](/src/shared/mcp-selection.ts) (`resolveMcpSelection`) decides each server's enablement (session ?? project ?? global). At spawn, [/src/main/process/spawn-cluster-manager.ts](/src/main/process/spawn-cluster-manager.ts) feeds the session's `mcp_overrides`, the project's `projectMcpDefaults`, and the live custom-server list into the orchestrator [/src/main/services/mcp/mcp-config-orchestrator.ts](/src/main/services/mcp/mcp-config-orchestrator.ts), which composes the per-session `.mcp.json` — written to a **private path** (`<userData>/session-mcp/`, never the project folder) and handed to the CLI via `--mcp-config` (see [backend-spawn-contract.md](/.claude/memory/contracts/backend-spawn-contract.md) §12). The **credential-safety clamp runs AFTER resolution** — Search/Ask sessions get no MCP, KMS-vault sessions get no secret-bearing server — so a user choice can never re-enable a force-disabled server. Custom servers are **project-scope-only** (DB table `mcp_servers`, secrets `safeStorage`-encrypted), never written to `~/.claude.json`, which is what makes per-session off possible. Invariants: [mcp-server-control-contract.md](/.claude/memory/contracts/mcp-server-control-contract.md).

**Usage** — the same JSONL scanner that powers the Skills sidebar upserts every `mcp__<server>__<tool>` `tool_use` into `tool_invocations`. The view is the virtual project `__mcp_servers__`; UI in [/src/renderer/src/features/mcp-servers/](/src/renderer/src/features/mcp-servers/) (`McpServersSubSidebar` list + `McpServerManagerDialog`/`McpServerFormDialog` manager + `McpSelectionEditor` reused by the project/session pickers), stores `mcp-servers-store` (usage) + `mcp-control-store` (custom CRUD). `TOOL_INVOCATIONS_LIST_MCP_SERVERS` marks each row **known** when its name is in any current source — `~/.claude.json`, an Omniscio-composed built-in (`BUILTIN_MCP_SERVER_NAMES` / `DIRECT_COMPOSED_MCP_SERVER_NAMES`), or a live custom server — so Omniscio's own per-session servers (`zapier`, `playwright`, …) are **never falsely badged "Stale"**; the amber **Stale** badge shows only for a server gone from every source (e.g. a deleted custom server, or one of the servers retired from composition). The `mcp-servers:*` channels do custom CRUD. Stale-badge invariants: [mcp-stale-badge-contract.md](/.claude/memory/contracts/mcp-stale-badge-contract.md).

### Over the CLI

A session's per-session override is settable without the picker, so a script or an outside AI can
change what one session gets on its next start:

- **`POST /session/:id/mcp-override`** — body `{ "override": { "<serverId>": true | false } }`, or
  `{ "override": null }` to clear the override and fall back to the layers below. The body is
  `.strict()`, so an unrecognised field is a `400` rather than being ignored.

The map is **partial by design**, which is the part worth understanding before you write one: a
server id **absent** from the map means *inherit* — the session keeps whatever the project, then
the global list, decide for it. Only an explicit `false` forces a server off at this layer, and only
an explicit `true` forces one on. So an override that turns a single server off never disturbs the
other twenty, and clearing it (`null`) returns the whole session to the inherited set.

Like the picker, this **takes effect on the session's next start** — MCP servers are composed when
the CLI launches — so it does not change a running turn. The route needs the bearer token; an
agent's scoped token may only touch a session it originated (`403` otherwise), and it is charged to
the mutation budget. The credential-safety clamp still runs *after* resolution, so nothing set here
can re-enable a server the app force-disabled.

## Related

### Related

- [use-skills.md](use-skills.md) — sibling Skills sidebar (same usage model)
- [zapier-integration.md](zapier-integration.md) — the composed built-in MCP servers that remain
- [kms-agent-tools.md](kms-agent-tools.md) — the Vault's agent surface, now served entirely by the control server's `/kms/*` routes (no per-session MCP)
