Skip to content

[AI-1226] Auto-register kcap MCP servers + steering instructions for Copilot - #297

Merged
alexeyzimarev merged 4 commits into
mainfrom
tonyyoung/ai-1226-copilot-mcp
Jul 9, 2026
Merged

alexeyzimarev merged 4 commits into
mainfrom
tonyyoung/ai-1226-copilot-mcp

Conversation

@realtonyyoung

Copy link
Copy Markdown
Collaborator

What

Third per-harness rollout of the MCP auto-config epic (AI-1224), for GitHub Copilot CLI — plus the first cut of a new, cross-harness agent-instructions mechanism.

kcap setup and kcap plugin install --copilot now:

  1. Register the kcap MCP servers in ~/.copilot/mcp-config.json (opt out --skip-copilot-mcp).
  2. Install a kcap-owned steering-instructions block in ~/.copilot/copilot-instructions.md (opt out --skip-copilot-instructions).

plugin remove --copilot / uninstall cleanly reverse both. Mirrors the merged Cursor/Codex wiring.

Why the instructions file

Registration alone doesn't make agents use the tools — the Copilot live E2E confirmed the same under-utilization we saw on Cursor (a plain "review this PR" went to native GitHub tools, not kcap-review). An always-in-context instructions file closes that gap. Validated live: with the block installed, "review <PR link>" routes to kcap-review get_pr_summary and "request a codex review" routes to kcap-flows start_review_flow, instead of gh pr diff + a self-spawned reviewer.

How

MCP (mirrors Cursor): CopilotPaths.McpConfigJson (honors $COPILOT_HOME), McpConfigShape.Copilot (mcpServers, per-entry type:"stdio"), RegisterCopilotMcpServersAsync in InstallCopilot, unconditional Unregister in RemoveCopilot (ownership-marker retained on failure for retry).

Instructions (new shared foundation, reusable by every harness):

  • KcapAgentInstructions — one canonical steering body (single source of truth).
  • AgentInstructionsWriter — non-destructive, idempotent, atomic, fail-closed writer that owns a marker-delimited block (<!-- BEGIN/END kcap -->) inside a markdown file, preserving user content around it; Remove() strips just our block (deletes the file if nothing else remains).
  • Copilot wiring via CopilotPaths.InstructionsMd + PluginEnvironment.CopilotInstructionsMd + CodingAgentsStep (HandleCopilotInstructions) + SetupCommand/InstallCopilot/RemoveCopilot.

UninstallCommand needs no change — both the MCP marker and the instructions block are owned by plugin remove --copilot (the Cursor precedent).

Config shape verified against Copilot

Live E2E on Copilot CLI v1.0.63: copilot mcp list shows all 4 kcap servers (local); copilot mcp get kcap-review → Type: local, Command: kcap mcp review, Tools: * (all). Copilot accepts type:"stdio" (normalizes to local); omitting tools/env = all tools / no env. No foundation change needed.

Tests

Full unit suite 2671/2671, build 0 warnings. New/extended: AgentInstructionsWriterTests (8), CopilotPathsTests, CodingAgentsStepTests (+8 Copilot MCP + instructions), PluginCommandCopilotTests (8). All plugin tests reuse the shared FakeUserHome helper and are verified to leave zero ownership-marker state in the real ~/.kcap/mcp-markers.

Docs

--skip-copilot-mcp / --skip-copilot-instructions documented in help-setup.txt, help-plugin.txt, and the README MCP sections.

Notes

  • Branches off main (after [AI-699] Auto-register kcap MCP servers for Cursor #296 Cursor merged); two clean commits (MCP, instructions).
  • AgentInstructionsWriter is the shared foundation — a Cursor follow-up and the remaining harnesses (Gemini/Kiro/OpenCode/Antigravity/Pi) will reuse it.

🤖 Generated with Claude Code

realtonyyoung and others added 2 commits July 8, 2026 20:59
…-config.json)

Second per-harness consumer of the MCP config-writer foundation, mirroring the
merged Cursor wiring. `kcap setup` and `kcap plugin install --copilot` now
register the 4 kcap MCP servers in ~/.copilot/mcp-config.json using
McpConfigShape.Copilot (per-entry type:"stdio"); `plugin remove --copilot` /
uninstall unregister them. Adds --skip-copilot-mcp.

- CopilotPaths.McpConfigJson honors $COPILOT_HOME (via Root) like the rest of
  the layout — the key difference from Cursor's fixed ~/.cursor.
- RemoveCopilot rewritten to unregister unconditionally (independent of the
  hooks file) with hooksFailed || mcpFailed exit; the ownership marker is owned
  by Unregister (cleared on non-Failed, retained on Failed for retry), so no
  UninstallCommand sweep line is added.
- Tests reuse the shared FakeUserHome helper (no marker leak into the real
  ~/.kcap/mcp-markers). Full unit suite 2655/2655, build 0 warnings.
- Docs: --skip-copilot-mcp in help-setup/help-plugin + README MCP sections.

Stacked on the AI-699 Cursor branch (FakeUserHome + foundation consumer).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Registration alone doesn't make agents route to the kcap tools (confirmed in
the Copilot live E2E). Ship a per-agent instructions file that steers the model
to prefer the kcap tools for why/history/prior-work questions.

Foundation (reused by every harness):
- KcapAgentInstructions: one canonical steering body (the text validated in the
  E2E), single source of truth.
- AgentInstructionsWriter: non-destructive, idempotent, atomic, fail-closed
  writer that owns a marker-delimited block (<!-- BEGIN/END kcap -->) inside a
  markdown instructions file, preserving user content around it; Remove() strips
  just our block (and deletes the file if nothing else remains).

Copilot wiring (mirrors the MCP wiring):
- CopilotPaths.InstructionsMd (~/.copilot/copilot-instructions.md, honors
  $COPILOT_HOME); PluginEnvironment.CopilotInstructionsMd.
- CodingAgentsStep SkipCopilotInstructions/CopilotInstructionsPath/
  InstallCopilotInstructions/CopilotInstructionsInstalled + HandleCopilotInstructions.
- SetupCommand + InstallCopilot (write) + RemoveCopilot (strip, contributes to
  exit code) wiring; --skip-copilot-instructions opt-out. Uninstall rides on
  `plugin remove --copilot`.

Tests reuse FakeUserHome (no marker leak): AgentInstructionsWriter (8),
CopilotPaths (+1), CodingAgentsStep (+4), PluginCommandCopilot (+3). Full unit
suite 2671/2671, build 0 warnings. Docs: --skip-copilot-instructions in
help-setup/help-plugin + README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Jul 9, 2026

Copy link
Copy Markdown

AI-1226

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Auto-register Copilot MCP servers and manage Copilot steering instructions

✨ Enhancement 🧪 Tests 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Auto-register kcap MCP servers in Copilot’s ~/.copilot/mcp-config.json (opt-out flags).
• Install/remove a kcap-owned Copilot instructions block to steer tool routing.
• Add CLI/docs coverage plus unit tests for Copilot paths, MCP, and instructions.
Diagram

graph TD
  A["kcap setup"] --> B["CodingAgentsStep"] --> C["Copilot integration"]
  D["kcap plugin install/remove --copilot"] --> C --> E["JsonMcpConfigWriter"] --> F[("~/.copilot/mcp-config.json")]
  C --> G["AgentInstructionsWriter"] --> H[("~/.copilot/copilot-instructions.md")]
  subgraph Legend
    direction LR
    _cmd["Command/Step"] ~~~ _lib["Writer/Library"] ~~~ _file[("User file")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Per-repo instructions file (instead of user-level)
  • ➕ Keeps steering scoped to repos that actually use kcap
  • ➕ Avoids affecting Copilot behavior globally across projects
  • ➖ Copilot’s primary supported mechanism is user-level instructions; repo-level support may be inconsistent
  • ➖ Harder to ensure the file is always in-context for ad-hoc PR reviews
2. Rely on MCP registration only (no instructions)
  • ➕ Less intrusive; no edits to user-authored instruction files
  • ➕ Simpler install/remove surface area
  • ➖ Does not address observed tool under-utilization; agents may continue to prefer native tools
  • ➖ Misses the main behavioral goal (routing “why/history/review request” intents to kcap tools)
3. Separate ownership sidecar for instructions (like MCP markers)
  • ➕ Avoids embedding markers in user markdown
  • ➕ Potentially easier to version/track ownership externally
  • ➖ More files and failure modes
  • ➖ Harder to be robust when users move/rename instruction files; embedded markers are self-contained

Recommendation: Proceed with the current approach: non-destructive, marker-delimited instructions embedded in the harness’s native instructions file is the most reliable way to keep the steering text in-context, and it avoids the operational overhead of sidecar ownership for markdown. The opt-out flags plus idempotent/atomic writer keep the UX and failure modes reasonable.

Files changed (14) +861 / -21

Enhancement (7) +329 / -11
CopilotPaths.csAdd Copilot paths for MCP config and instructions file +15/-0

Add Copilot paths for MCP config and instructions file

• Introduces helpers for resolving ~/.copilot/mcp-config.json and ~/.copilot/copilot-instructions.md. Both honor $COPILOT_HOME by using the Copilot root path abstraction.

src/Capacitor.Cli.Core/Copilot/CopilotPaths.cs

AgentInstructionsWriter.csAdd atomic, idempotent writer for marker-delimited instruction blocks +89/-0

Add atomic, idempotent writer for marker-delimited instruction blocks

• Implements a read-modify-write engine that inserts/replaces/removes a kcap-owned block inside a markdown file while preserving user content. Uses atomic temp-file moves and fail-closed error handling with Updated/Unchanged/Failed outcomes.

src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs

KcapAgentInstructions.csDefine canonical kcap steering instructions content +45/-0

Define canonical kcap steering instructions content

• Adds a single shared markdown body that instructs agents to prefer kcap MCP tools for history/why/prior-work and distinguishes “review yourself” vs “request a hosted review flow”. Intended to be rendered identically across harnesses via AgentInstructionsWriter.

src/Capacitor.Cli.Core/Instructions/KcapAgentInstructions.cs

CodingAgentsStep.csWire Copilot MCP registration and instructions install into setup step +84/-5

Wire Copilot MCP registration and instructions install into setup step

• Extends options/paths/installers/results to include Copilot MCP and instructions operations. Adds gated handlers that run only when Copilot hooks were installed and the corresponding skip flags are not set, emitting user-facing status/warnings.

src/Capacitor.Cli/Commands/CodingAgentsStep.cs

PluginCommand.csRegister/unregister Copilot MCP and manage Copilot instructions on plugin install/remove +80/-3

Register/unregister Copilot MCP and manage Copilot instructions on plugin install/remove

• During plugin install --copilot, registers kcap MCP servers in Copilot’s mcp-config.json and installs the kcap-owned instructions block (both warn-only on failure). During remove --copilot, un-registers MCP servers independently of hook removal and strips the instructions block, returning non-zero if any step fails.

src/Capacitor.Cli/Commands/PluginCommand.cs

PluginEnvironment.csExpose Copilot MCP and instructions paths via PluginEnvironment +2/-0

Expose Copilot MCP and instructions paths via PluginEnvironment

• Adds computed environment properties for CopilotMcpConfigJson and CopilotInstructionsMd, derived from CopilotPaths using the configured home directory.

src/Capacitor.Cli/Commands/PluginEnvironment.cs

SetupCommand.csAdd setup flags and installer wiring for Copilot MCP and instructions +14/-3

Add setup flags and installer wiring for Copilot MCP and instructions

• Parses new setup opt-out flags and passes them into CodingAgentsStep.Options. Provides installers for registering Copilot MCP servers (Copilot config shape) and writing Copilot’s instruction block using the shared writer/content.

src/Capacitor.Cli/Commands/SetupCommand.cs

Tests (4) +502 / -1
AgentInstructionsWriterTests.csAdd unit tests for instruction block writer semantics +122/-0

Add unit tests for instruction block writer semantics

• Covers creation, idempotency, user-content preservation, in-place refresh, removal behavior (including deleting empty files), and fail-closed behavior when the target path is invalid.

test/Capacitor.Cli.Tests.Unit/AgentInstructionsWriterTests.cs

CodingAgentsStepTests.csAdd setup-step tests for Copilot MCP and instructions gating and warnings +148/-1

Add setup-step tests for Copilot MCP and instructions gating and warnings

• Adds test cases verifying Copilot MCP/instructions run only when hooks succeed, are suppressible via flags, and emit warnings on writer failures. Extends the fake installer call tracking and test paths accordingly.

test/Capacitor.Cli.Tests.Unit/CodingAgentsStepTests.cs

CopilotPathsTests.csTest Copilot path resolution and $COPILOT_HOME override behavior +25/-0

Test Copilot path resolution and $COPILOT_HOME override behavior

• Verifies that McpConfigJson and InstructionsMd resolve under ~/.copilot by default, and that McpConfigJson correctly relocates under a COPILOT_HOME override root.

test/Capacitor.Cli.Tests.Unit/CopilotPathsTests.cs

PluginCommandCopilotTests.csAdd plugin install/remove tests for Copilot MCP and instructions integration +207/-0

Add plugin install/remove tests for Copilot MCP and instructions integration

• Validates that plugin install registers MCP servers without clobbering user entries and honors skip flags and --if-installed behavior. Validates remove unregisters kcap servers while preserving user entries, retains markers on failed unregister for retry, and strips only the managed instructions block while preserving user content.

test/Capacitor.Cli.Tests.Unit/PluginCommandCopilotTests.cs

Documentation (3) +30 / -9
README.mdDocument Copilot MCP auto-registration and new agent-instructions block +8/-6

Document Copilot MCP auto-registration and new agent-instructions block

• Extends the MCP server docs to include GitHub Copilot CLI alongside Claude/Codex/Cursor. Adds documentation for the new cross-harness agent-instructions mechanism and the corresponding skip flags.

README.md

help-plugin.txtAdd Copilot MCP/instructions skip flags and clarify Copilot install behavior +18/-3

Add Copilot MCP/instructions skip flags and clarify Copilot install behavior

• Documents --skip-copilot-mcp and --skip-copilot-instructions under plugin install options. Updates Copilot notes to reflect that hooks, MCP config, and instructions are installed non-destructively and require a Copilot restart.

src/Capacitor.Cli.Core/Resources/help-plugin.txt

help-setup.txtExpose setup flags for Copilot MCP and Copilot instructions +4/-0

Expose setup flags for Copilot MCP and Copilot instructions

• Adds --skip-copilot-mcp and --skip-copilot-instructions to setup help output so users can opt out of these behaviors during kcap setup.

src/Capacitor.Cli.Core/Resources/help-setup.txt

@qodo-code-review

qodo-code-review Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Refresh skips Copilot artifacts ✓ Resolved 🐞 Bug ☼ Reliability
Description
PluginCommand.InstallCopilot() returns early in --if-installed mode when the Copilot hooks
marker is already current, so it never attempts MCP registration or instructions installation even
though those are separate files. This prevents postinstall/refresh runs from healing missing Copilot
MCP/instructions after a prior warning-level failure or manual deletion.
Code

↗ src/Capacitor.Cli/Commands/PluginCommand.cs

                : $"Copilot hooks installed ({hooksPath})"
Evidence
The --if-installed early-return happens before the new MCP/instructions calls, so the refresh path
can no-op without re-registering MCP servers or reinstalling instructions.

src/Capacitor.Cli/Commands/PluginCommand.cs[1021-1026]
src/Capacitor.Cli/Commands/PluginCommand.cs[1053-1062]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
In `plugin install --copilot --if-installed`, the command exits early when the **hooks** marker matches the current version. Because the MCP registration and instructions install steps run *after* that marker gate, they are skipped—even though they live in separate files and may be missing/stale.

### Issue Context
This can happen if:
- MCP/instructions writes previously failed (they are warning-only), or
- the user deleted `~/.copilot/mcp-config.json` / `copilot-instructions.md` after a successful hooks refresh.

### Fix
When `--if-installed` is set and Copilot is installed, skip rewriting hooks if the hooks marker is current, but still run the idempotent Copilot MCP registration and instructions write (unless skip flags are present).

### Fix Focus Areas
- src/Capacitor.Cli/Commands/PluginCommand.cs[1018-1064]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Malformed marker duplicates block ✓ Resolved 🐞 Bug ☼ Reliability
Description
If the instructions file contains the BEGIN marker but is missing the END marker (truncation/manual
edit), AgentInstructionsWriter.Write() treats the block as absent and appends a new block,
creating duplicates that Remove() also can’t strip. This can permanently strand a broken/duplicate
kcap block until the user manually edits the file.
Code

src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[R56-81]

+    static string ReplaceOrAppendBlock(string content, string block) {
+        var (start, end) = FindBlock(content);
+        if (start >= 0) return content[..start] + block + content[end..]; // replace in place
+        if (content.Length == 0) return block + "\n";                     // fresh file
+        var sep = content.EndsWith("\n") ? "\n" : "\n\n";                 // one blank line before ours
+        return content + sep + block + "\n";
+    }
+
+    static string StripBlock(string content) {
+        var (start, end) = FindBlock(content);
+        if (start < 0) return content;
+        var before = content[..start].TrimEnd('\n');
+        var after  = content[end..].TrimStart('\n');
+        if (before.Length == 0) return after;
+        if (after.Length == 0)  return before + "\n";
+        return before + "\n\n" + after;
+    }
+
+    // Returns the [start, end) span of the whole block (markers inclusive), or (-1, -1) if absent.
+    static (int start, int end) FindBlock(string content) {
+        var start = content.IndexOf(BeginMarker, StringComparison.Ordinal);
+        if (start < 0) return (-1, -1);
+        var end = content.IndexOf(EndMarker, start, StringComparison.Ordinal);
+        if (end < 0) return (-1, -1);
+        return (start, end + EndMarker.Length);
+    }
Evidence
ReplaceOrAppendBlock appends whenever FindBlock returns (-1,-1), and FindBlock returns
(-1,-1) when BeginMarker is present but EndMarker is missing—so a malformed file causes block
duplication and prevents removal.

src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[56-61]
src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[74-81]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AgentInstructionsWriter` only recognizes a managed block when *both* markers exist. If `BeginMarker` exists but `EndMarker` is missing, `FindBlock()` returns `(-1,-1)` which makes `Write()` append a second block and makes `Remove()` a no-op, leaving the file in a broken state.

### Issue Context
This is a realistic scenario after a truncated write, merge conflict, or a user accidentally deleting the end marker.

### Fix
Detect the “partial block” case (BEGIN present, END missing) and **fail-closed** (return `Change.Failed`) rather than appending a second block / silently doing nothing.

### Fix Focus Areas
- src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[20-81]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Verbose AgentInstructionsWriter summary comment ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
New XML doc comments are overly verbose and largely restate the implementation details. This reduces
maintainability and violates the guideline to prefer self-explanatory code with minimal comments.
Code

src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[R3-9]

+/// <summary>
+/// Read-modify-write engine for a harness's markdown agent-instructions file (Copilot's
+/// <c>copilot-instructions.md</c>, Gemini's <c>GEMINI.md</c>, <c>AGENTS.md</c>, …). kcap owns only a
+/// marker-delimited block inside the file, so user-authored content around it is preserved:
+/// non-destructive, idempotent, atomic, fail-closed. The inline markers are self-identifying — no
+/// sidecar ownership file is needed (unlike the JSON MCP config).
+/// </summary>
Evidence
PR Compliance ID 4 requires concise comments; the added summary block is long and describes multiple
implementation qualities ("non-destructive, idempotent, atomic, fail-closed") that are apparent from
the code, rather than providing minimal context.

CLAUDE.md: Avoid verbosity in comments; prefer self-explanatory code
src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[3-9]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New/modified comments are excessively verbose and explain straightforward behavior instead of adding only necessary context.

## Issue Context
The compliance checklist asks to avoid verbosity in comments and prefer self-explanatory code.

## Fix Focus Areas
- src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs[3-9]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs
Comment thread src/Capacitor.Cli.Core/Instructions/AgentInstructionsWriter.cs Outdated
- Malformed block (bug): AgentInstructionsWriter now distinguishes a partial
  block (BEGIN marker with no following END — truncation, merge conflict, or
  hand-edit) from an absent one, and returns Change.Failed from both Write and
  Remove instead of appending a duplicate block (Write) or silently no-op'ing
  (Remove). +2 tests.
- Refresh self-heal (bug): InstallCopilot's --if-installed path now skips only
  the hooks rewrite when the hooks marker is current — it still runs the
  idempotent MCP registration and instructions install, so a refresh restores a
  deleted/failed mcp-config.json or copilot-instructions.md rather than skipping
  them. +1 test.
- Trim the AgentInstructionsWriter class doc comment (rule: concise comments).

Full unit suite 2674/2674.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

Addressed Qodo finding #3 (refresh skips Copilot artifacts) in b71bd0e: InstallCopilot's --if-installed path now skips only the hooks rewrite when the hooks marker is current — it still runs the idempotent MCP registration and instructions install, so a refresh self-heals a deleted or previously-failed mcp-config.json / copilot-instructions.md. Added install_copilot_if_installed_heals_mcp_and_instructions_when_hooks_current. Full suite 2674/2674.

🤖 Addressed by Claude Code

- AgentInstructionsWriter marker ambiguity: FindBlock now fail-closes
  (BlockState.Malformed) when the file contains more than one BEGIN marker —
  a second block, or the marker quoted in user prose above/below ours. Previously
  "first BEGIN … first END" could span and delete unrelated user content on Write
  (or mis-strip on Remove). +1 regression test.
- InstallCopilot refresh no longer bails on a hooks-write failure: on
  --if-installed, a failed hook rewrite now warns and still runs the independent,
  idempotent MCP + instructions writes (they live in separate files and must
  self-heal), rather than returning early. Fresh install still fails on hook
  write error. +1 regression test.

Full unit suite 2676/2676.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung

Copy link
Copy Markdown
Collaborator Author

@alexeyzimarev — ready for review; the automated cycle is complete and clean on c14fcce.

What it does: adds GitHub Copilot CLI to the MCP auto-config epic (registers the 4 kcap servers in ~/.copilot/mcp-config.json, --skip-copilot-mcp) plus a new cross-harness agent-instructions mechanism: AgentInstructionsWriter (non-destructive, marker-delimited <!-- BEGIN/END kcap --> block writer — idempotent/atomic/fail-closed) + KcapAgentInstructions (canonical steering body), installed into ~/.copilot/copilot-instructions.md (--skip-copilot-instructions). Live-E2E validated: registration alone didn't make Copilot route to the tools; with the instructions block, "review " → kcap-review and "request a codex review" → kcap-flows.

Review status: Qodo — 3 findings fixed + resolved. Codex code-review flow — 2 findings (marker-ambiguity fail-closed; refresh heals MCP/instructions on a hook-write failure), both fixed, re-reviewed clean. 0 unresolved threads. Full suite 2676/2676.

AgentInstructionsWriter is the shared foundation — a Cursor follow-up (and the remaining harnesses) reuse it. Thanks!

@alexeyzimarev
alexeyzimarev merged commit 752984c into main Jul 9, 2026
5 checks passed
@alexeyzimarev
alexeyzimarev deleted the tonyyoung/ai-1226-copilot-mcp branch July 9, 2026 14:03
realtonyyoung added a commit that referenced this pull request Jul 9, 2026
`kcap setup` / `kcap plugin install --gemini` now also register the four
kcap MCP servers into the shared ~/.gemini/settings.json (Standard shape,
non-destructive) and install kcap's marker-delimited steering-instructions
block into Gemini's global ~/.gemini/GEMINI.md context file, mirroring the
Copilot integration (#297). Both are idempotent + fail-closed; opt out with
--skip-gemini-mcp / --skip-gemini-instructions. `remove --gemini` unregisters
the servers and strips the block.

AI-1227

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
alexeyzimarev pushed a commit that referenced this pull request Jul 10, 2026
…Gemini CLI (#303)

* feat(gemini): auto-register kcap MCP servers + steering instructions

`kcap setup` / `kcap plugin install --gemini` now also register the four
kcap MCP servers into the shared ~/.gemini/settings.json (Standard shape,
non-destructive) and install kcap's marker-delimited steering-instructions
block into Gemini's global ~/.gemini/GEMINI.md context file, mirroring the
Copilot integration (#297). Both are idempotent + fail-closed; opt out with
--skip-gemini-mcp / --skip-gemini-instructions. `remove --gemini` unregisters
the servers and strips the block.

AI-1227

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(gemini): unregister MCP marker even when settings.json is absent

Review finding (#303): `remove --gemini` only called JsonMcpConfigWriter.Unregister
inside `if (File.Exists(settingsPath))`, but Unregister also owns the ownership-marker
cleanup. If the user deleted ~/.gemini/settings.json before running remove, the sidecar
marker went stale and a later user-authored `mcpServers.kcap-*` entry (command `kcap`)
could be misclassified as kcap-owned. Call Unregister unconditionally — on an absent file
it's a no-op that still clears the marker and never creates a config file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(gemini): address #303 review — hook-file guard + independent GEMINI.md heal

Qodo + Codex-flow review on #303:
- hooksCurrent now also requires File.Exists(settings.json). A lone marker (settings.json
  deleted by hand) no longer lets --if-installed skip the hook write, which would otherwise
  let MCP registration recreate settings.json with only mcpServers and leave hooks missing
  while the marker stays current. (Qodo "Action required")
- Decouple GEMINI.md (independent file) from hook-write success: setup gates instructions on a
  new `selected` signal (Gemini opted-in + kcap on PATH) rather than geminiHooksInstalled, and the
  CLI fresh-install path installs GEMINI.md even when the shared settings.json hook write fails
  (still returns non-zero). Flagged by both Qodo and the Codex review flow.
- Trim the verbose PluginCommandGeminiTests header comment. (Qodo rule)

Tests: instructions install on hook-write failure but skip when not selected; refresh reinstalls
hooks when settings.json was deleted. Rebased onto main (#298 AI-1285 skills-decouple).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [AI-1293] Auto-approve read-only kcap MCP servers on registration (#302)

* feat(mcp): auto-approve read-only kcap MCP servers on registration

Mark the read-only kcap servers (kcap-review, kcap-sessions) auto-approved
where a harness exposes a per-server trust knob, so agents don't stop to ask
before every read. The write-capable kcap-memory (save) and work-launching
kcap-flows (starts a paid hosted reviewer) are deliberately left prompting.

- KcapMcpServer.ReadOnly designates the safe-to-auto-approve servers.
- McpConfigShape.TrustStyle + JsonMcpConfigWriter emit Gemini's per-server
  "trust": true (new McpConfigShape.Gemini; Cursor keeps the trust-less
  Standard shape). Ownership/idempotency unaffected (Owns keys off command),
  and existing untrusted entries self-heal to include trust on re-register.
- CodexConfigToml sets default_tools_approval_mode = "approve" on the
  read-only servers, additively healing existing entries without overriding a
  user's explicit mode or touching command/args.
- Cursor + Copilot have no per-server auto-approve field in the config we
  write (Cursor: permissions.json classifier / --approve-mcps; Copilot: tools
  is availability, approval is --allow-tool/--allow-all-tools) — documented in
  the README rather than emitting a no-op field.

Tests: JsonMcpConfigWriter (trust on read-only only / none on Standard / heal),
CodexConfigToml (approve on read-only / heal without override), Gemini plugin
e2e trust assertions. Full unit suite 2701/2701.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(mcp): gate Codex read-only auto-approve heal on command == kcap AND matching args

Review findings (#302 Codex flow): the Codex heal added
default_tools_approval_mode = "approve" to an existing kcap-review/kcap-sessions
table by NAME only. Gate the additive heal on the existing entry being demonstrably
the read-only server — command == "kcap" AND args matching the expected read-only
args — since the heal never rewrites command/args. A same-named wrapper (foreign
command), or a kcap-named entry that actually points at a write-capable server
(e.g. args = ["mcp","memory"]), is left prompting. +2 regression tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

2 participants