MCP Servers
Model Context Protocol servers connect Claude Code to external services. 20 are live at user scope, plus the claude.ai connectors.
Where config actually lives
Read this first. Getting it wrong is not a small mistake — it silently produces an engine with no tools.
Claude Code reads MCP servers from three places only:
| Source | Scope | Written by |
|---|---|---|
~/.claude.json → mcpServers | User | claude mcp add -s user |
~/.claude.json → projects["<path>"].mcpServers | Local | claude mcp add (default) |
.mcp.json at a project root | Project | Hand-edited, gated by enabledMcpjsonServers |
| claude.ai connectors | Account | OAuth, managed in the /mcp TUI |
It does not read ~/.claude/mcp.json or <repo>/.claude/mcp.json.
Those two kun files are catalogs — the intended fleet, version-controlled and reviewable. They are not configuration Claude Code consumes.
setup.shused to "install" MCP by copying the catalog to~/.claude/mcp.json, a file Claude Code ignores, so the fleet never loaded. Registration must go throughclaude mcp add-json "<name>" '<json>' -s user— single-quote the JSON so literal${VAR}survives.
Live fleet (20)
| Server | Purpose | Transport |
|---|---|---|
| browser | Headless Chromium — see, flow, responsive | stdio |
| browser-headed | Visible Chromium for auth flows | stdio |
| chrome-devtools | Traces, Lighthouse, network — trace, fast | stdio |
| github | Repos, issues, Actions, code search | http |
| figma · figma-desktop | Design context, screenshots, Code Connect | http |
| shadcn | Component registry and install commands | stdio |
| Neon | Postgres branching, migrations, query tuning | http |
| sentry | Error monitoring and issue triage | http |
| stripe | Payments and subscriptions | http |
| linear | Issue tracking | http |
| slack | Team messaging | http |
| notion | Docs and databases | http |
| posthog | Product analytics | http |
| ref · context7 | Technical and library documentation | stdio |
| markitdown | Any file or URL → Markdown | stdio |
| filesystem | Local file access | stdio |
| higgs | Higgsfield media generation | http |
| claude-design | Claude Labs design canvas | http |
claude.ai connectors
Gmail, Google Calendar, Google Drive, PlanetScale, Vercel, Indeed. OAuth-managed in-app — not tool-drivable. Their authenticate tool returns "run /mcp and select X"; you must use the TUI.
Catalog entries that are not registered
The catalogs hold 25 entries; 8 are deliberately not live:
| Entry | Why |
|---|---|
gcloud · keychain | Shell wrappers, not MCP servers — they case "$1" and exit |
postgres | dbhub reads DSN not DATABASE_URL, no pg driver, redundant with Neon |
algolia · design-system-analyzer · memory-bank | No published package |
airtable | Wrong package name — airtable-mcp-server, not @airtable/mcp-server |
vercel | Deduplicated — the claude.ai Vercel connector already covers it |
Trimmed for token economy on 2026-07-26 and not to be re-added without Abdout: sequential-thinking, storybook, tailwind, git (Bash covers it), a11y. Rationale and re-add path: docs/TOKEN-ECONOMY.md.
Secrets
${VAR} in a ~/.claude.json definition expands from Claude Code's launch environment, not from kun/.env — nothing sources it. Two working options:
# bake the value at registration (writes mode-600)
claude mcp add -e REF_API_KEY=... -s user ref ...
# or source the central .env in the launch shellConfig is universal; access is scoped by secrets, not config. A server whose key you don't hold simply doesn't connect. Which keys you hold is set by the Gist you're handed.
OAuth
Remote HTTP servers expose mcp__<srv>__authenticate — it returns an OAuth URL with a localhost:<port>/callback redirect, and approving completes in-session. mcp__<srv>__complete_authentication is the paste-the-callback-URL fallback. Drivable this way: higgs, sentry, stripe, notion, posthog.
A config change needs a session relaunch to take effect — a running session keeps the stale tool definitions.
Shared with the secondary agent
The Antigravity CLI (a) reuses this fleet. During setup.sh, antigravity-sync.sh transforms the catalog into ~/.gemini/config/mcp_config.json — stdio servers pass through unchanged; remote servers are rewritten from Claude's type: http|sse + url to Antigravity's serverUrl key.
Installation
# macOS/Linux
cd ~/kun && bash .claude/scripts/setup.sh engineer
# Windows (PowerShell)
cd ~/kun; .\.claude\scripts\setup.ps1 -Role engineerTroubleshooting: Browser / Playwright
If mcp__browser__* tools disappear, return "tool not found", or report "still disconnected", run /mcp-doctor — the single recovery entry point.
The doctor learns. Every distinct error is logged once to ~/.claude/skills/mcp-doctor/ERRORS.md with a permanent fix, mined from Claude Code's own logs (~/Library/Caches/claude-cli-nodejs/*/mcp-logs-browser/). It consults that ledger before improvising and appends new entries — so the same error is never debugged twice. Seven classes catalogued: E1 wrong package, E2 npm token, E3 connection-closed, E4 browser disconnect, E5 page timeout, E6 missing Chromium, E7 profile lock.
Recurring root causes
1. Project configs shadow user scope. A browser entry in a project's .mcp.json overrides user scope. Different projects have pointed at different packages, including @anthropic-ai/mcp-server-playwright, which doesn't exist on npm. Never define browser or browser-headed at project level.
2. Duplicate user-level definitions. ~/.claude.json plus a stray ~/.mcp.json competed for the browser name; whichever was read first won. ~/.claude.json is the only store.
3. CLI flag silently overridden. If ~/.claude/playwright-mcp.config.json sets userDataDir, it beats the --user-data-dir flag. Two servers on one dir → Chromium ProcessSingleton lock. The CLI flag owns the profile dir; the config key must not exist.
4. @latest version churn. npx -y @playwright/mcp@latest swaps between cached versions in ~/.npm/_npx/, and a swap can demand a Chromium revision that isn't on disk. Pin exactly — currently @playwright/mcp@0.0.75. Bump the registration and mcp-doctor/SKILL.md in lock-step.
5. Stale PIDs holding the profile. Chromium locks --user-data-dir per process; a crashed-but-running PID blocks every launch. /mcp-doctor step A (pkill -f playwright-mcp) clears it.
6. Cache bloat. 5+ GB across a dozen Chromium revisions slows first launch and confuses diagnostics. /mcp-doctor step D prunes.
Secondary: Node v25+ is newer than Playwright officially supports (LTS 24). Flag any segfaults.
Canonical configuration
| Concern | Value |
|---|---|
| Package | @playwright/mcp (official) |
| Version pin | 0.0.75 — exact, never @latest |
| Registration | ~/.claude.json, user scope |
| Runtime config | ~/.claude/playwright-mcp.config.json — no userDataDir |
| Headless profile | ~/.playwright-auth-headless |
| Headed profile | ~/.playwright-auth |
| Cache | ~/Library/Caches/ms-playwright |
| Recovery | /mcp-doctor |
Determinism
playwright-mcp.config.json is the shared tuning surface for both browsers, validated against the 0.0.75 Config type. Beyond viewport and timeouts it pins repeatability — the same screenshot twice, no analytics noise, stable dates:
reducedMotion: "reduce"— frozen animations for cleansee/responsive/mirrorshotsserviceWorkers: "block"— no cache nondeterminism between runscolorScheme: "light",locale: "en-US",timezoneId: "Asia/Dubai"— fixed default render; RTL is exercised per-call via/ar/routes, never a hardcoded localetestIdAttribute: "data-testid"— matches the stack's Playwright convention
--caps vision,pdf and --user-data-dir stay on the CLI: the config-file capabilities enum can replace rather than augment the core toolset.
Opt-in knobs (off by default):
| Need | How |
|---|---|
| Lock network to known origins | "network": { "allowedOrigins": [...] } — aborts other requests, so it muddies debug / watch |
| Emulate a device | --device "iPhone 15" |
| Replay an authenticated session | --storage-state <file.json> |
| Persist the session | --save-session |
| Auto-grant permissions | --grant-permissions |
| DevTools / perf | add devtools to --caps |
Recovery
pkill -f playwright-mcp
rm -f ~/.playwright-auth/Singleton{Lock,Cookie,Socket}
rm -f ~/.playwright-auth-headless/Singleton{Lock,Cookie,Socket}
npx -y @playwright/mcp@0.0.75 --help >/dev/null
# then restart Claude Code — MCP servers only spawn at session start