Goal
After primo init, the user's installed MCP clients have a primo server entry pointing at primo-mcp, with zero manual JSON editing.
Today users have to find their MCP client's config file, paste a JSON snippet, and restart the client — every client, every machine. For an "AI-native visual CMS" pitch this is the first onboarding friction users hit.
Scope
In:
- Detect installed clients by checking known config paths (Claude Desktop, Claude Code, Cursor on macOS/Linux/Windows).
- Prompt with a checklist of detected clients ("Wire up Primo MCP for: ☑ Claude Code ☑ Cursor ☐ Claude Desktop").
- Merge a new
primo server entry into each selected client's config without clobbering existing entries.
primo-mcp as a runtime dependency of primo-cli so it's already on disk (skip npx's first-run resolution wait).
- Idempotent — re-running in a workspace already wired is a no-op ("already wired ✓").
- Flag to skip:
primo init --no-mcp.
Out (defer):
- Auto-wiring on
primo new if init already ran.
- Per-site
mcpServers config files (Cursor's per-repo .cursor/mcp.json — addable later).
- Non-mainstream clients (Continue, Zed, Windsurf).
- Reverting on
primo uninstall — npm doesn't run uninstall hooks reliably.
Architecture
New module: primo-cli/src/utils/mcp-wiring.ts
detect_clients() → Array<ClientInfo>
wire_client(client, server_entry) → { written, already_present }
run_mcp_wiring(opts) → void
Per-client config paths:
| Client |
macOS |
Linux |
Windows |
| Claude Desktop |
~/Library/Application Support/Claude/claude_desktop_config.json |
~/.config/Claude/claude_desktop_config.json |
%APPDATA%/Claude/claude_desktop_config.json |
| Claude Code |
~/.claude/settings.json (or claude mcp add shell-out) |
same |
%USERPROFILE%/.claude/settings.json |
| Cursor |
~/.cursor/mcp.json |
~/.cursor/mcp.json |
%USERPROFILE%/.cursor/mcp.json |
Server entry shape (same across all three):
{ "mcpServers": { "primo": { "command": "npx", "args": ["-y", "primo-mcp"] } } }
Wiring integration points
init.ts — after workspace files are written, call run_mcp_wiring({ skip: opts.noMcp }). Print a one-line summary.
new.ts — no change. Init handles it.
- package.json —
"primo-mcp": "^0.1.0" to deps. Optional follow-up: detect local install and skip npx -y.
Edge cases
- Config file exists but isn't JSON — skip with warning, don't crash.
- Config has
mcpServers.primo already — leave alone, print "already wired ✓".
- Config has
mcpServers.primo pointing elsewhere (e.g. user's local dist path) — prompt: "Existing primo entry points at X. Replace with npx primo-mcp?" (default: yes).
- No write permission — surface the error path.
- Claude Code shell-out — if
claude CLI is on $PATH, prefer claude mcp add primo -- npx -y primo-mcp over JSON-rewriting ~/.claude/settings.json. Fall back to JSON if not on PATH.
Phasing
- Phase 1: bundle
primo-mcp as dep + Claude Code only (via claude mcp add). Highest-value, easiest. ~1 PR, ~100 LOC.
- Phase 2: Cursor + Claude Desktop JSON merging.
- Phase 3: idempotency polish +
--no-mcp flag + messaging.
Total realistic effort: ~1-2 days for Phase 1, another ~1-2 for Phase 2+3.
Open questions
- Should this also run on
primo dev if MCP isn't wired? Or strictly init-time?
- Auto-update entry on
primo-cli upgrade if schema changes? Probably not — too aggressive.
- Should
primo new re-check (quiet, idempotent) in case user added a new client since init?
Workaround today
Users have to hand-edit their MCP client config:
{ "mcpServers": { "primo": { "command": "npx", "args": ["-y", "primo-mcp"] } } }
Config paths above. Restart the client after editing.
Goal
After
primo init, the user's installed MCP clients have aprimoserver entry pointing atprimo-mcp, with zero manual JSON editing.Today users have to find their MCP client's config file, paste a JSON snippet, and restart the client — every client, every machine. For an "AI-native visual CMS" pitch this is the first onboarding friction users hit.
Scope
In:
primoserver entry into each selected client's config without clobbering existing entries.primo-mcpas a runtime dependency ofprimo-cliso it's already on disk (skipnpx's first-run resolution wait).primo init --no-mcp.Out (defer):
primo newif init already ran.mcpServersconfig files (Cursor's per-repo.cursor/mcp.json— addable later).primouninstall — npm doesn't run uninstall hooks reliably.Architecture
New module:
primo-cli/src/utils/mcp-wiring.tsPer-client config paths:
~/Library/Application Support/Claude/claude_desktop_config.json~/.config/Claude/claude_desktop_config.json%APPDATA%/Claude/claude_desktop_config.json~/.claude/settings.json(orclaude mcp addshell-out)%USERPROFILE%/.claude/settings.json~/.cursor/mcp.json~/.cursor/mcp.json%USERPROFILE%/.cursor/mcp.jsonServer entry shape (same across all three):
{ "mcpServers": { "primo": { "command": "npx", "args": ["-y", "primo-mcp"] } } }Wiring integration points
init.ts— after workspace files are written, callrun_mcp_wiring({ skip: opts.noMcp }). Print a one-line summary.new.ts— no change. Init handles it."primo-mcp": "^0.1.0"to deps. Optional follow-up: detect local install and skipnpx -y.Edge cases
mcpServers.primoalready — leave alone, print "already wired ✓".mcpServers.primopointing elsewhere (e.g. user's local dist path) — prompt: "Existingprimoentry points at X. Replace withnpx primo-mcp?" (default: yes).claudeCLI is on$PATH, preferclaude mcp add primo -- npx -y primo-mcpover JSON-rewriting~/.claude/settings.json. Fall back to JSON if not on PATH.Phasing
primo-mcpas dep + Claude Code only (viaclaude mcp add). Highest-value, easiest. ~1 PR, ~100 LOC.--no-mcpflag + messaging.Total realistic effort: ~1-2 days for Phase 1, another ~1-2 for Phase 2+3.
Open questions
primo devif MCP isn't wired? Or strictly init-time?primo-cliupgrade if schema changes? Probably not — too aggressive.primo newre-check (quiet, idempotent) in case user added a new client since init?Workaround today
Users have to hand-edit their MCP client config:
{ "mcpServers": { "primo": { "command": "npx", "args": ["-y", "primo-mcp"] } } }Config paths above. Restart the client after editing.