Skip to content

feat(agents): agents init --mcp wiring (PR 8)#135

Merged
SutuSebastian merged 12 commits into
mainfrom
feat/agents-init-mcp
May 25, 2026
Merged

feat(agents): agents init --mcp wiring (PR 8)#135
SutuSebastian merged 12 commits into
mainfrom
feat/agents-init-mcp

Conversation

@SutuSebastian
Copy link
Copy Markdown
Contributor

@SutuSebastian SutuSebastian commented May 25, 2026

Summary

  • codemap agents init --mcp (and interactive confirm) writes registry-driven MCP config for 8 integrations: Cursor, Claude Code, VS Code/Copilot, Continue, Cline, Amazon Q, Gemini CLI, and Windsurf (user-global, only when that integration is selected).
  • Default --mcp writes 8 registry targets (project-local MCP JSON) plus .claude/settings.json permissions — 9 project-local paths on disk. Windsurf is opt-in via integration selection.
  • Per-target paths: .cursor/mcp.json, .mcp.json + .claude/settings.json, .vscode/mcp.json, .continue/mcpServers/codemap-mcp.json, .cline/mcp.json, .amazonq/default.json (IDE canonical) + .amazonq/mcp.json (legacy workspace), .gemini/settings.json, ~/.codeium/windsurf/mcp_config.json (Windsurf only).
  • Command shape: codemap mcp --watch --root ${workspaceFolder} (Cursor); other hosts use stdio MCP entries from AGENTS_INIT_MCP_REGISTRY. Amazon Q IDE entries include transportType: stdio.
  • Claude: merges permissions.allow with mcp__codemap__*.
  • Idempotent merge — foreign MCP servers and unrelated settings keys preserved; verify-after-write on JSON.
  • Side-effect-only re-runs: --mcp / --git-hooks work when .agents/ already exists without --force.
  • Interactive -i: MCP writes only for selected integrations; empty selection skips MCP.

Test plan

  • bun test src/agents-init-mcp*.ts src/agents-init.test.ts src/cli.test.ts
  • bun run typecheck
  • CI green
  • Manual: codemap agents init --force --mcp in a test repo; spot-check Cursor + .amazonq/default.json + .amazonq/mcp.json

Dependencies

Independent of #134 (no file overlap). Can merge in either order.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 25, 2026

🦋 Changeset detected

Latest commit: 6c0377f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@stainless-code/codemap Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Warning

Review limit reached

@SutuSebastian, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 18 minutes and 3 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fca1aa2e-b0e7-4da0-a0aa-d86680350be8

📥 Commits

Reviewing files that changed from the base of the PR and between 1128b26 and 6c0377f.

📒 Files selected for processing (20)
  • .changeset/agents-init-mcp.md
  • README.md
  • docs/README.md
  • docs/agents.md
  • docs/architecture.md
  • docs/plans/agent-surface-delivery.md
  • docs/plans/agents-init-mcp-wiring.md
  • docs/roadmap.md
  • src/agents-init-interactive.ts
  • src/agents-init-mcp-registry.test.ts
  • src/agents-init-mcp-registry.ts
  • src/agents-init-mcp.test.ts
  • src/agents-init-mcp.ts
  • src/agents-init-targets.ts
  • src/agents-init.test.ts
  • src/agents-init.ts
  • src/cli.test.ts
  • src/cli/bootstrap.ts
  • src/cli/cmd-agents.ts
  • src/cli/main.ts
📝 Walkthrough

Walkthrough

Adds codemap agents init --mcp command to configure MCP server entries for Cursor and Claude Code. Includes core utilities for idempotent JSON merging, integration with existing agent initialization, CLI argument parsing, comprehensive test coverage, and updated documentation.

Changes

MCP Initialization Feature

Layer / File(s) Summary
MCP configuration utilities and contracts
src/agents-init-mcp.ts
Implements core MCP functions: buildCodemapMcpServerEntry, normalizeExistingMcpServersFile, mergeCodemapMcpServer, upsertMcpServersFile, mergeClaudeCodemapPermissions, upsertClaudeSettingsPermissions, and applyAgentsInitMcp. Exports constants CODEMAP_MCP_SERVER_KEY and CODEMAP_MCP_PERMISSION_ALLOW, plus data shapes for MCP server entries and Claude settings. Provides idempotent JSON merge/upsert for .cursor/mcp.json, .mcp.json, and .claude/settings.json.
MCP utilities comprehensive test coverage
src/agents-init-mcp.test.ts
370 lines of Bun tests covering MCP entry building, JSON validation/normalization with force behavior, server merging while preserving foreign entries, permission management, and filesystem effects across Cursor and Claude targets including error handling and console.error output capture.
MCP integration into agents initialization
src/agents-init.ts
Adds mcp?: boolean to AgentsInitOptions, imports applyAgentsInitMcp, and introduces conditional MCP application in three paths: after git-hook uninstall, as allowed side effect when .agents/ exists without --force, and after normal template write completion.
MCP prompting in interactive mode
src/agents-init-interactive.ts
Adds optional mcp?: boolean to RunAgentsInitInteractiveOptions; prompts user for MCP configuration when not provided and wires result into runAgentsInit call.
Agents initialization with MCP test coverage
src/agents-init.test.ts
83 lines of tests verifying MCP generates .cursor/mcp.json with codemap command, MCP runs as side effect on existing .agents/, git-hook installation preserves user content, and combined git-hook uninstall with MCP updates post-commit hook.
CLI argument parsing and flag recognition
src/cli/main.ts
Updates help text to document --mcp flag, adds it to recognized flags, and extends options object to pass mcp boolean derived from --mcp presence to runAgentsInitCmd.
CLI help text and validation updates
src/cli/bootstrap.ts
Updates printCliUsage() help output and validateIndexModeArgs() error message to document --mcp, --git-hooks, and --no-git-hooks flags for agents init.
CLI error handling for agents init
src/cli/cmd-agents.ts
Wraps runAgentsInitCmd execution in try/catch with new reportAgentsInitError helper that normalizes error messages, logs with Codemap: prefix, and returns false.
CLI tests for MCP flag integration
src/cli.test.ts
Tests successful .cursor/mcp.json creation under --root with --force --mcp and error handling when existing MCP files contain unparseable JSON.
Documentation for MCP initialization feature
.changeset/agents-init-mcp.md, README.md, docs/agents.md, docs/architecture.md, docs/plans/...
Documents codemap agents init --mcp usage, target-specific files (Cursor .cursor/mcp.json and Claude Code .mcp.json plus .claude/settings.json), idempotent merge behavior, --force and --git-hooks flag interactions, and updates planning docs to reflect feature completion in PR #135.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • stainless-code/codemap#52: Modifies .gitignore handling in src/agents-init.ts to add /.codemap/audit-cache/, overlapping with this PR's agents-init integration points.
  • stainless-code/codemap#4: Introduces the agents init interactive/CLI initialization flow that this PR extends with MCP configuration side effects.

Suggested labels

enhancement

Poem

🐰 A codemap takes flight,
MCP whispers configure just right,
Cursor and Claude aligned,
Idempotent merges combined,
The agents init shines bright!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(agents): agents init --mcp wiring (PR 8)' clearly and specifically describes the main feature addition of MCP wiring for the agents init command with appropriate semantic commit format.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/agents-init-mcp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

SutuSebastian added a commit that referenced this pull request May 25, 2026
MCP-only re-run on existing .agents/, interactive prompt fix, git-hook
combo paths, force-replace warnings, expanded tests, and v1 docs/plan updates.
SutuSebastian added a commit that referenced this pull request May 25, 2026
Validate mcpServers shape, clean CLI exit on MCP JSON errors, expand
tests, architecture/docs sync, and add changeset for --mcp.
Project .cursor/mcp.json and Claude .mcp.json merge idempotently;
Claude permissions allow mcp__codemap__*.
MCP-only re-run on existing .agents/, interactive prompt fix, git-hook
combo paths, force-replace warnings, expanded tests, and v1 docs/plan updates.
Validate mcpServers shape, clean CLI exit on MCP JSON errors, expand
tests, architecture/docs sync, and add changeset for --mcp.
@SutuSebastian SutuSebastian force-pushed the feat/agents-init-mcp branch from e19e226 to 1128b26 Compare May 25, 2026 14:28
Unblocks the Release workflow — changeset version failed because two files referenced "codemap" instead of "@stainless-code/codemap".
Clean wave-2 table after rebase: PR 6 merged, PR 8 open (#135).
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cli/main.ts (1)

108-113: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Handle -i in the interactive/git-hooks conflict guard.

Line 102 checks only --interactive, so -i can bypass the intended conflict validation with --git-hooks / --no-git-hooks.

💡 Suggested fix
-    if (gitHooks !== undefined && rest.includes("--interactive")) {
+    if (
+      gitHooks !== undefined &&
+      (rest.includes("--interactive") || rest.includes("-i"))
+    ) {
       console.error(
         "codemap: --git-hooks / --no-git-hooks cannot be combined with --interactive.",
       );
       process.exit(1);
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/main.ts` around lines 108 - 113, The conflict guard that validates
mutually exclusive interactive/git-hooks options currently only checks for
"--interactive" and can be bypassed by "-i"; update the validation logic (the
code that determines the interactive variable passed into runAgentsInitCmd and
the pre-check that guards gitHooks vs interactive) to treat "-i" the same as
"--interactive" (e.g., use rest.includes("--interactive") ||
rest.includes("-i")) so both the conflict detection and the runAgentsInitCmd
call use the same combined check for interactive when evaluating gitHooks and
enforcing mutual-exclusion.
🧹 Nitpick comments (2)
src/agents-init-mcp.test.ts (1)

280-315: ⚡ Quick win

Add a regression test for malformed permissions.allow shape in .claude/settings.json.

Current tests cover invalid JSON, but not parseable invalid schema (e.g., permissions.allow: "bad"). A focused case should assert: throws without --force, replaces with --force.

Also applies to: 317-370

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/agents-init-mcp.test.ts` around lines 280 - 315, Add a regression test
alongside the existing invalid-JSON tests to cover a parseable but
schema-invalid `.claude/settings.json` (e.g., permissions.allow set to a
string). Create two specs using applyAgentsInitMcp and
CODEMAP_MCP_PERMISSION_ALLOW: one that writes a settings.json with
permissions.allow: "bad" and asserts applyAgentsInitMcp throws when called
without force, and a second that calls applyAgentsInitMcp with force: true and
asserts the file is replaced and the resulting JSON.permissions.allow contains
CODEMAP_MCP_PERMISSION_ALLOW; reuse the same console.error capture and cleanup
pattern and reference the '.claude/settings.json' path and applyAgentsInitMcp in
the test text to locate the code.
src/cli.test.ts (1)

164-166: ⚡ Quick win

Tighten the parse-error assertion to avoid false positives.

Line 165 currently passes on any Codemap: error, even if parsing is not the failure.

💡 Suggested refinement
-      expect(err).toMatch(/could not parse|Codemap:/);
+      expect(err).toMatch(/Codemap:.*could not parse/i);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli.test.ts` around lines 164 - 166, The assertion is too loose because
matching "Codemap:" lets non-parse errors pass; update the test to assert the
parser-specific message only by replacing expect(err).toMatch(/could not
parse|Codemap:/) with a stricter match that requires the parse failure text
(e.g., expect(err).toMatch(/could not parse/)) so the test only succeeds on
actual parse errors while keeping the existing exitCode and the negative check
for upsertMcpServersFile.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/plans/agent-surface-delivery.md`:
- Around line 44-51: Remove the Git conflict markers (<<<<<<<, =======, >>>>>>>)
from docs/plans/agent-surface-delivery.md and resolve the table rows for entries
**6** and **7** by using the merged variant: set the row for **6** to status
"merged" (keep the MCP trace description and PR links) and update the row for
**7** to include PR 6 in its "planned" PR list, ensuring the resulting markdown
table has no conflict markers or duplicate rows.

In `@docs/plans/agents-init-mcp-wiring.md`:
- Line 3: Update the contradictory status fields: if PR `#135` is merged, change
the "**Status:** open (PR [`#135`]...)" text to "**Status:** shipped (PR
[`#135`]...)" so it matches the existing "Shipped: `#135`" note; if the PR is still
open, remove or rephrase the "Shipped: `#135`" line so it doesn't claim the PR
shipped. Ensure the document's "Status" and "Shipped" statements refer to the
same PR state and use the exact PR reference "`#135`" for clarity.

In `@src/agents-init-mcp.ts`:
- Around line 149-163: The mergeClaudeCodemapPermissions function assumes
existing.permissions.allow is an array; first validate that existing.permissions
is an object and Array.isArray(existing.permissions.allow) — if the shape is
malformed, do not mutate or append; instead throw or return a clear error
indicating the settings file is malformed and instruct the user to rerun the
command with --force to overwrite, and add the same validation/behavior to the
other merge routine referenced around lines 175-188 (the other merge/upsert
function) so both functions guard against non-array permissions.allow before
merging.

In `@src/cli/bootstrap.ts`:
- Around line 140-142: The help/error message for unknown agents subcommands in
the console.error call is missing the supported flags --git-hooks and
--no-git-hooks; update the error hint string (the console.error invocation that
prints `codemap: unknown agents command "${rest[1] ?? "(missing)"}". Expected:
codemap agents init [...]`) so the Expected text lists all valid flags for
agents init, including --git-hooks and --no-git-hooks (alongside --force,
--interactive|-i, and --mcp) to keep the hint aligned with actual CLI support.

In `@src/cli/cmd-agents.ts`:
- Around line 23-34: The interactive branch returns the promise from
runAgentsInitInteractive without awaiting it, so rejections bypass the
surrounding try/catch; change the return runAgentsInitInteractive(opts) call to
await the imported runAgentsInitInteractive inside the try block (i.e., await
runAgentsInitInteractive(opts)) so any rejection is caught by the existing catch
handling and errors are handled correctly.

---

Outside diff comments:
In `@src/cli/main.ts`:
- Around line 108-113: The conflict guard that validates mutually exclusive
interactive/git-hooks options currently only checks for "--interactive" and can
be bypassed by "-i"; update the validation logic (the code that determines the
interactive variable passed into runAgentsInitCmd and the pre-check that guards
gitHooks vs interactive) to treat "-i" the same as "--interactive" (e.g., use
rest.includes("--interactive") || rest.includes("-i")) so both the conflict
detection and the runAgentsInitCmd call use the same combined check for
interactive when evaluating gitHooks and enforcing mutual-exclusion.

---

Nitpick comments:
In `@src/agents-init-mcp.test.ts`:
- Around line 280-315: Add a regression test alongside the existing invalid-JSON
tests to cover a parseable but schema-invalid `.claude/settings.json` (e.g.,
permissions.allow set to a string). Create two specs using applyAgentsInitMcp
and CODEMAP_MCP_PERMISSION_ALLOW: one that writes a settings.json with
permissions.allow: "bad" and asserts applyAgentsInitMcp throws when called
without force, and a second that calls applyAgentsInitMcp with force: true and
asserts the file is replaced and the resulting JSON.permissions.allow contains
CODEMAP_MCP_PERMISSION_ALLOW; reuse the same console.error capture and cleanup
pattern and reference the '.claude/settings.json' path and applyAgentsInitMcp in
the test text to locate the code.

In `@src/cli.test.ts`:
- Around line 164-166: The assertion is too loose because matching "Codemap:"
lets non-parse errors pass; update the test to assert the parser-specific
message only by replacing expect(err).toMatch(/could not parse|Codemap:/) with a
stricter match that requires the parse failure text (e.g.,
expect(err).toMatch(/could not parse/)) so the test only succeeds on actual
parse errors while keeping the existing exitCode and the negative check for
upsertMcpServersFile.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9d183307-cc0a-4ef6-9e82-6fc48cf41159

📥 Commits

Reviewing files that changed from the base of the PR and between ff89d8c and 1128b26.

📒 Files selected for processing (16)
  • .changeset/agents-init-mcp.md
  • README.md
  • docs/agents.md
  • docs/architecture.md
  • docs/plans/agent-surface-delivery.md
  • docs/plans/agents-init-mcp-wiring.md
  • docs/roadmap.md
  • src/agents-init-interactive.ts
  • src/agents-init-mcp.test.ts
  • src/agents-init-mcp.ts
  • src/agents-init.test.ts
  • src/agents-init.ts
  • src/cli.test.ts
  • src/cli/bootstrap.ts
  • src/cli/cmd-agents.ts
  • src/cli/main.ts

Comment thread docs/plans/agent-surface-delivery.md Outdated
Comment thread docs/plans/agents-init-mcp-wiring.md Outdated
Comment thread src/agents-init-mcp.ts
Comment thread src/cli/bootstrap.ts
Comment thread src/cli/cmd-agents.ts
Preserve non-mcpServers keys on force shape repair; clearer warnings;
CLI subprocess side-effect tests; git-hooks+mcp combo coverage.
Registry-driven MCP wiring with verify-after-write for all project-local
integrations; address CodeRabbit review (await interactive, bootstrap hints,
-i/git-hooks guard, permissions.allow validation).
Empty interactive integration selection skips MCP; slim registry exports;
Claude settings Codemap error re-throw; changeset patch bump; docs/roadmap sync.
Per AWS docs, workspace MCP uses .amazonq/default.json (canonical) and
.amazonq/mcp.json (legacy, default-on). Registry maps one integration to
both writers; IDE entries include transportType stdio.
Amazon Q legacy shape + idempotency tests, filtered integration E2E,
registry JSDoc fix, agents.md --mcp wording.
@SutuSebastian SutuSebastian merged commit c4b4b36 into main May 25, 2026
19 of 23 checks passed
@SutuSebastian SutuSebastian deleted the feat/agents-init-mcp branch May 25, 2026 15:24
@github-actions github-actions Bot mentioned this pull request May 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant