feat(setup): register the insta-cloud remote MCP server during insta setup agent#57
Conversation
… setup agent` Railway-parity: after the user-global skill install, setup now also registers https://mcp.instacloud.com/mcp with Claude Code (--transport http --scope user), authenticated by a durable insta_ API token minted via POST /tokens (named mcp-<hostname>; the CLI's own session token expires, so it can't be reused). Behavior: best-effort and idempotent — skipped silently when claude isn't installed, left alone when insta-cloud is already registered (no token re-mint), and a login hint is printed when the CLI isn't authenticated. INSTA_MCP_URL overrides the server URL for beta/self-host setups. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…adless fallback The platform's Better Auth MCP authorization server is live (RFC 8414 metadata + DCR at /api/auth/mcp/*), so the default registration now carries NO credential: Claude Code discovers the AS via RFC 9728 and runs the browser flow on first /mcp use — managed, expiring, revocable tokens, nothing static on disk. `insta setup agent --mcp-token` keeps the minted insta_ token path for headless machines/CI where no browser exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…pencode/copilot/factory-droid) New command writes the insta-cloud remote server into each agent's own config format: Cursor ~/.cursor/mcp.json, Codex ~/.codex/config.toml, OpenCode ~/.config/opencode/opencode.json, Copilot ~/.copilot/mcp-config.json, Factory Droid ~/.factory/mcp.json. Claude Code keeps going through claude mcp add. All entries are OAuth (URL only, no credential). `insta setup agent` now also configures every detected agent after the Claude Code registration. Safety: merges never clobber — existing JSON keys preserved, unparseable configs skipped with a manual hint, TOML appended only when the table is absent; idempotent re-runs report already-configured. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Added |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
jwfing
left a comment
There was a problem hiding this comment.
Summary
Adds remote MCP-server registration to insta setup agent plus a new insta mcp install command that registers insta-cloud with Claude Code (via its claude mcp add registry CLI) and writes config-file entries for Cursor/Codex/OpenCode/Copilot/Factory Droid — clean, well-factored, DI-friendly code with solid test coverage and no blocking issues.
Requirements context
No matching spec/plan found — insta-cli has no /docs/superpowers/ (or docs/specs/) directory, so this is assessed against the PR description and repo conventions (AGENTS.md, .claude/skills/developing-insta-cli) alone. Verified locally on the PR head: npm run typecheck is clean and npm test passes 92/92 (18 files). I also confirmed against current Claude Code docs (via context7) that claude mcp add --transport http --scope user <name> <url> --header "Authorization: Bearer <token>" is valid, non-stale syntax and that Bearer <token> is the correct header format.
Findings
Critical
(none) — no correctness, security, data-loss, or compatibility issues found. Best-effort design is respected (skill install stays the primary outcome; MCP steps never set a failure exit code), the merge logic never clobbers an unparseable config, idempotency is real, and secret injection uses spawn with an args array (no shell → no injection).
Suggestion
- Software engineering / test — serializer tests are self-referential (
src/commands/mcp.ts:12-45,test/mcp-install.test.ts). The tests assert the exact shape the serializer emits, so they confirm internal consistency but can't catch a wrong target schema or path for a real agent (e.g. Copilot's~/.copilot/mcp-config.json+mcpServers/tools:['*'], Factory Droid's~/.factory/mcp.json, OpenCode'stype:"remote"). Since these are best-effort and unverifiable in-repo, a one-line doc-version citation per agent (like the OpenCodedocs.opencode.ainote) and/or a manual smoke test per client would harden this against silent drift. - Functionality — Codex append doesn't validate existing TOML (
src/commands/mcp.ts:48-53). JSON configs refuse to clobber unparseable content (renderJsonConfig→null→skipped), butrenderCodexConfigblindly appends to whatever is on disk. A pre-existing malformedconfig.tomlwould be written to anyway. Minor inconsistency given the deliberate no-TOML-parser choice; worth a comment noting the asymmetry. - Test coverage — untested branches (
src/commands/mcp.ts:84-96). Theunknown --agentpath ininstallAgentConfigsand themcpInstallorchestration itself have no direct test. Low blast radius, but a close-call for the--agentrouting.
Information
- Security —
--mcp-tokenpersists a durable credential (src/commands/setup.ts:133-141). The mintedinsta_token is passed via argv (briefly visible in the process table to local users) and lands in Claude Code's user-scoped MCP config in plaintext. This is the documented headless tradeoff vs. the OAuth default — flagging only for awareness; no change requested. No secret is logged. - Convention — cli-reference mirror (
AGENTS.mdnon-negotiable #4). New commands/flags (insta mcp install,--agent,--mcp-token) must be mirrored inskills/insta/cli-reference.mdin the superprojectskills/submodule — out of scope for this repo's diff. The PR body says the skills-repo doc update is paired; please confirm that companion PR carries these. - Functionality —
/tokensresponse shape (src/commands/setup.ts:114).POST /tokens→{ token }is the only usage of this endpoint in the repo and can't be verified here; worth a quick confirm against the platform API contract.
Performance
No concerns — this is a one-shot setup path (a few subprocess calls and file writes), nothing on a hot path or request loop.
Verdict
approved (informational — the human still approves via the approve flow). Zero Critical findings; the Suggestion/Information items are non-blocking. Nice work — clean DI, honest best-effort semantics, and the OAuth-default / token-fallback split is the right call.
jwfing
left a comment
There was a problem hiding this comment.
Review — feat(setup): register the insta-cloud remote MCP server
Summary: Solid, well-tested addition that registers the insta-cloud remote MCP server with Claude Code (via claude mcp add) and writes OAuth config for the config-file agents; the merge/idempotency/never-clobber logic is careful and correct, and I found no blocking issues.
Requirements context
This repo has no docs/superpowers/ (nor docs/specs/) directory — no matching spec/plan found, so I assessed against the PR description, the cubic summary, and repo conventions in .claude/skills/developing-insta-cli/SKILL.md. Note the PR's own What section and the cubic summary disagree on the default auth mode; I treated the code as source of truth (default = OAuth, no header; --mcp-token = minted token).
Findings
Critical
(none)
Suggestion
- Software engineering — orchestration paths untested.
src/commands/mcp.ts:105-123(installAgentConfigsunknown---agentbranch,INSTA_MCP_URLoverride, detect→install loop) andmcpInstall(src/commands/mcp.ts:126-134) have no direct tests, unlike the renderers/installFor/registerMcpbranches which are covered well.renderJsonConfig's "refuse non-object JSON" guard (src/commands/mcp.ts:38— array/scalar root →null) is also only exercised for the unparseable case, not the valid-but-not-object case. Cheap to add given the existing DI-free style. - Functionality — Cursor entry omits a transport type.
src/commands/mcp.ts:44writes{ url }for Cursor while copilot/factory-droid get{ type: 'http', … }. The comment says Cursor auto-detects HTTP fromurl; that's true for some Cursor versions but recent schemas prefer an explicit"type": "http". Worth confirming against current Cursor docs — if the schema is off the server just silently won't load for Cursor (best-effort, degraded not broken), which is why this is a suggestion rather than a blocker. (I verified the OpenCode{ type: 'remote', url, enabled: true }shape atsrc/commands/mcp.ts:35against opencode.ai docs — correct, including the$schemadefault.) - Security — durable token passed as a CLI argument. With
--mcp-token,src/commands/setup.ts:140appends--header "Authorization: Bearer <insta_…>"to theclaudeargv. Process arguments are visible inps/process listings for the lifetime of the call (and in shell history if a user runs the printed command manually). It's opt-in and headless-only, andclaude mcp add --headeris the only interface Claude Code offers, so there's no clean alternative — but worth a note. Good hygiene elsewhere: the config-file agents are all OAuth (no credential on disk), and neither the success nor the failure message echoes the token (the manual-fallback hint atsrc/commands/setup.ts:147deliberately omits the header).
Information
- Functionality — PR description is stale. The What section describes the default registration as including
--header "Authorization: Bearer <insta_…>"and minting a token on every run. The actual code (src/commands/setup.ts:126-148) defaults to OAuth with no header/mint and only mints under--mcp-token; the cubic summary matches the code. Please update the PR body so the changelog/reviewers aren't misled. - Convention — mirror the CLI surface in the skills repo.
SKILL.mdrequires new commands/flags to be mirrored inskills/insta/cli-reference.md"in the same change set." That file is in the companion skills submodule (empty in this checkout), and the PR body says it pairs with a skills-repo doc update — so it can't appear in this diff. Just confirm that skills-repo PR lands in lockstep so agents learninsta mcp installand--mcp-token. - Security — minted token scope. The minted
insta_token handed to the MCP server is a full API token (POST /tokens,src/commands/setup.ts:114). Confirm the platform mints an appropriately-scoped token for MCP use rather than a full-privilege CLI token. - Performance: no performance-relevant changes — the additions are one-shot spawns and small config-file writes during setup only.
Verdict
approved (informational — a human still gives the GitHub approval). Zero Critical findings; the Suggestion/Information items above are non-blocking. Nice work on the never-clobber merge logic and the OAuth-by-default posture.
What
insta setup agentnow closes the last Railway-parity onboarding gap: after installing the insta skill user-globally, it registers the remote MCP server (https://mcp.instacloud.com/mcp) with Claude Code:insta_API token viaPOST /tokens(namedmcp-<hostname>) — the CLI's refreshable session token would expire inside the MCP config.insta-cloudregistration is left alone; no token re-mint on re-runs.claudeisn't installed (the skill install remains the primary outcome); prints ainsta loginhint when unauthenticated;INSTA_MCP_URLoverrides the URL.Pairs with InsForge/insta-mcp#11 (CLI-parity tool surface) and the skills-repo doc update.
Testing
npm run typecheck && npm test— 83 pass (4 new: no-claude skip, idempotency/no re-mint, add args incl. header, login-hint path).🤖 Generated with Claude Code
Summary by cubic
Installs the Insta skill user‑globally and registers the
insta-cloudremote MCP server with Claude Code and other agents. Defaults to OAuth (no static credential);--mcp-tokenis available for headless Claude Code setups.https://mcp.instacloud.com/mcpviaclaude mcp add --transport http --scope userwith no header; first/mcptriggers browser auth.insta mcp installto write OAuth-only config for Cursor, Codex, OpenCode, Copilot, and Factory Droid;--agenttargets one;insta setup agentruns it automatically.--mcp-tokenmints a durableinsta_viaPOST /tokens(mcp-<hostname>) and addsAuthorization: Bearer <insta_…>for headless Claude Code; prints aninsta loginhint if minting fails.claudeisn’t installed or already registered; merges without clobbering; unparseable configs are skipped with a hint;INSTA_MCP_URLoverrides; tests cover OAuth, token, idempotency, no‑claude, and agent‑config paths.Written for commit 9956663. Summary will update on new commits.