Skip to content

Auto-wire Primo MCP during primo init #1161

Description

@elemdos

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

  1. Config file exists but isn't JSON — skip with warning, don't crash.
  2. Config has mcpServers.primo already — leave alone, print "already wired ✓".
  3. 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).
  4. No write permission — surface the error path.
  5. 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

  1. Should this also run on primo dev if MCP isn't wired? Or strictly init-time?
  2. Auto-update entry on primo-cli upgrade if schema changes? Probably not — too aggressive.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions