Skip to content

Stamp --driver <vendor> into the flows MCP registration so JSON harnesses know who is driving - #646

Merged
realtonyyoung merged 2 commits into
mainfrom
ai-2175-driver-vendor-breadth
Aug 22, 2026
Merged

Stamp --driver <vendor> into the flows MCP registration so JSON harnesses know who is driving#646
realtonyyoung merged 2 commits into
mainfrom
ai-2175-driver-vendor-breadth

Conversation

@realtonyyoung

Copy link
Copy Markdown
Collaborator

What & why

Part of AI-2175 (proactive second-harness review-flow suggestion). The list_reviewer_vendors tool echoes a driver_vendor so the suggest-review-flow skill can recommend a reviewer that differs from the harness the user is driving.

That driver_vendor was only knowable for Claude Code and Codex, which export a distinctive own-session env var (CLAUDE_CODE_SESSION_ID / CODEX_THREAD_ID) into the long-lived MCP-server child. The six JSON harnesses (Cursor, Copilot, Gemini, Kiro, OpenCode, Antigravity) export no such stable signal, so they fell back to the (already-correct, but weaker) "unknown driver → offer a choice" path.

Change

Those six harnesses now register kcap-flows as kcap mcp flows --driver <vendor>. The stamp is the harness's own vendor, and it reaches the same mcp flows subcommand and therefore the same tool schema — it only tells the server who is driving.

  • KcapMcpServers.ForHarness(vendor) derives each harness's server set from the bare list, stamping only the flows entry. All / ForCodex / the bundled .mcp.json / .codex-mcp.json stay bare.
  • HarnessMcpProjections carries the stamp plus DriverStampVendors — the single list that decides who is stamped and what the audit recognises, so the writer and the recogniser can't drift.
  • DriverVendor.Infer is now arg-first (validated against a closed vendor set) with env inference kept as the fallback for Claude/Codex, whose registrations stay unstamped. McpFlowsServer / Program.cs thread the --driver arg through.
  • McpRegistrationAudit recognises a flows --driver <known-vendor> suffix as canonical (so kcap dedup still owns its own entry); any other extra arg stays a conflict to preserve.

Scope note: Claude and Codex are deliberately left env-inferred (unstamped) — no change to their configs or to the Codex TOML ledger. Pi registers no MCP config, so it stays on the unknown-driver fallback.

Forward-looking

Takes effect only after a CLI release + re-install (registrations are written at install time). Until then, driving harnesses keep using the correct unknown-driver behaviour — no regression for anyone.

Tests

  • KcapMcpServersTestsForHarness stamps only flows, leaves the bare All list untouched.
  • DriverVendorTests — stamp used verbatim; stamp wins over a conflicting env marker; unknown/blank stamp falls back to env; never echoes arbitrary text.
  • McpRegistrationAuditTests — a known --driver <vendor> flows entry is a removable canonical duplicate; --driver without a value, an unknown vendor, or a stamp + trailing junk all stay conflicts.
  • FlowsDriverSchemaConformanceTests — the installed-driver and projection arms now assert each JSON harness stamps its own vendor while Codex stays bare (a strengthening of the identical-server invariant, not a loosening).

Refs AI-2175.

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Aug 22, 2026

Copy link
Copy Markdown

AI-2175

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Stamp --driver into kcap-flows MCP registrations for JSON harnesses

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Stamp JSON harness MCP registrations with kcap mcp flows --driver  for driver attribution.
• Prefer --driver over env inference while keeping Claude/Codex unchanged (env fallback).
• Treat stamped flows entries as canonical in registration audits; add conformance/unit test
 coverage.
Diagram

graph TD
H["JSON harness"] --> P["HarnessMcpProjections"] --> K["KcapMcpServers.ForHarness"] --> C["Flows registration args"]
C --> M["McpFlowsServer"] --> D["DriverVendor.Infer"]
C --> A["McpRegistrationAudit"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Introduce stable per-harness env markers for JSON harnesses
  • ➕ No CLI argv shape changes; keeps registrations strictly identical across harnesses.
  • ➕ Driver inference remains purely env-based (no config-derived trust surface).
  • ➖ Requires each harness runtime to propagate a distinctive, long-lived env var into the MCP server child (often not feasible).
  • ➖ Harder to audit/guarantee correctness across installer paths and harness versions.
2. Add structured driver metadata to MCP config instead of argv
  • ➕ Avoids overloading argv for metadata; clearer separation of command vs identity.
  • ➕ Could allow richer identity data later (version, channel, etc.).
  • ➖ More invasive: requires schema support and harness compatibility for additional fields.
  • ➖ Audit and dedup logic would still need special-casing for legacy configs.

Recommendation: The PR’s argv-stamp approach is the best trade-off: it’s deterministic for JSON harnesses that lack env signals, preserves Claude/Codex behavior via env fallback, and keeps the tool schema stable by staying on the same kcap mcp flows subcommand. The added closed-set validation and audit recognition reduce risk of echoing arbitrary driver text and avoid breaking dedup/removal semantics.

Files changed (10) +203 / -30

Enhancement (6) +106 / -27
HarnessMcpProjections.csStamp flows server per JSON harness and centralize stamped vendor list +18/-8

Stamp flows server per JSON harness and centralize stamped vendor list

• Switch JSON harness projections to use 'KcapMcpServers.ForHarness(<vendor>)' so only the flows server is registered with a '--driver' stamp. Add 'DriverStampVendors' derived from the projection list to keep stamping and audit recognition in sync.

src/Capacitor.Cli.Core/Mcp/HarnessMcpProjections.cs

KcapMcpServers.csAdd 'ForHarness(vendor)' to stamp kcap-flows args with '--driver' +23/-3

Add 'ForHarness(vendor)' to stamp kcap-flows args with '--driver'

• Introduce constants for the flows server name and driver flag, and add 'ForHarness(string vendor)' that appends '--driver <vendor>' only for 'kcap-flows' while leaving the shared 'All' descriptors unchanged.

src/Capacitor.Cli.Core/Mcp/KcapMcpServers.cs

McpRegistrationAudit.csTreat 'kcap-flows ... --driver <known-vendor>' as canonical args +26/-4

Treat 'kcap-flows ... --driver <known-vendor>' as canonical args

• Refactor canonical-args checks into 'ArgsAreCanonical', allowing exactly one tolerated extension for 'kcap-flows': a trailing '--driver <vendor>' where vendor is in 'HarnessMcpProjections.DriverStampVendors'. Preserve conflicts for missing/unknown vendor or any other extra args to avoid removing user customizations.

src/Capacitor.Cli.Core/Mcp/McpRegistrationAudit.cs

DriverVendor.csPrefer '--driver' stamp with closed-set validation; keep env fallback +34/-9

Prefer '--driver' stamp with closed-set validation; keep env fallback

• Extend driver inference to accept an optional '--driver' value, prefer it when it matches a known vendor, and fall back to Claude/Codex env markers otherwise. Add normalization and a closed vendor set to prevent echoing arbitrary text as 'driver_vendor'.

src/Capacitor.Cli/Commands/DriverVendor.cs

McpFlowsServer.csThread '--driver' arg into flows driver-vendor inference +4/-2

Thread '--driver' arg into flows driver-vendor inference

• Update the flows server entrypoint to accept an optional 'driverArg' and use it when resolving 'driverVendor', ensuring JSON harness stamps win deterministically while Claude/Codex continue via env inference.

src/Capacitor.Cli/Commands/McpFlowsServer.cs

Program.csParse and forward '--driver' to 'kcap mcp flows' server +1/-1

Parse and forward '--driver' to 'kcap mcp flows' server

• Pass 'GetArg(args, "--driver")' through the 'mcp flows' command path so the server can consume the registration stamp.

src/Capacitor.Cli/Program.cs

Tests (4) +97 / -3
KcapMcpServersTests.csVerify flows-only stamping and immutability of shared descriptors +27/-0

Verify flows-only stamping and immutability of shared descriptors

• Add tests asserting 'ForHarness(vendor)' modifies only 'kcap-flows' args and does not mutate 'KcapMcpServers.All', protecting audit/registry canonical-prefix behavior.

test/Capacitor.Cli.Core.Tests.Unit/Mcp/KcapMcpServersTests.cs

McpRegistrationAuditTests.csCover canonical-duplicate classification for known driver stamps +22/-0

Cover canonical-duplicate classification for known driver stamps

• Add cases asserting flows entries stamped with '--driver <known-vendor>' are removable canonical duplicates, while malformed/unknown stamps (or stamps with trailing extra args) remain conflicts and are preserved.

test/Capacitor.Cli.Core.Tests.Unit/Mcp/McpRegistrationAuditTests.cs

DriverVendorTests.csAdd stamp-precedence and safety tests for DriverVendor inference +31/-0

Add stamp-precedence and safety tests for DriverVendor inference

• Test that known stamps are used verbatim, stamps override conflicting env markers, and unknown/blank stamps fall back safely to env or null (never echoing arbitrary vendor strings).

test/Capacitor.Cli.Tests.Unit/Commands/DriverVendorTests.cs

FlowsDriverSchemaConformanceTests.csStrengthen flows schema conformance to require correct per-harness stamps +17/-3

Strengthen flows schema conformance to require correct per-harness stamps

• Document and enforce the one allowed argv variation: JSON harness installers must stamp '--driver <their own vendor>' on flows while Codex (bare install) remains unstamped. Update projection assertions to require the stamped args.

test/Capacitor.Cli.Tests.Unit/Commands/FlowsDriverSchemaConformanceTests.cs

…harnesses

The reviewer-vendor tool echoes driver_vendor so the suggest-review-flow skill
can recommend a reviewer that differs from the driving harness. That value was
env-inferable only for Claude Code and Codex (their own-session env vars); the
six JSON harnesses (Cursor, Copilot, Gemini, Kiro, OpenCode, Antigravity)
export no distinctive var into the long-lived MCP-server child, so they fell
back to the unknown-driver path.

Those harnesses now register kcap-flows as "kcap mcp flows --driver <vendor>".
The stamp is the harness's own vendor and reaches the same subcommand and tool
schema; DriverVendor prefers it and keeps env inference as the fallback for
Claude/Codex, whose registrations stay unstamped. Pi registers no MCP config,
so it stays on the unknown-driver fallback.

- KcapMcpServers.ForHarness derives each harness's set from the bare list,
  stamping only the flows entry; All / ForCodex / the bundled configs stay bare.
- HarnessMcpProjections carries the stamp plus DriverStampVendors, the single
  source of which vendors are stamped and therefore recognised by the audit.
- McpRegistrationAudit recognises a flows "--driver <known-vendor>" suffix as
  canonical, so dedup still owns kcap's own entry; any other extra arg stays a
  conflict to preserve.

FlowsDriverSchemaConformanceTests now asserts each harness stamps its OWN
vendor -- a strengthening, not a loosening, of the identical-server invariant.

Refs AI-2175.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung
realtonyyoung force-pushed the ai-2175-driver-vendor-breadth branch from c146afe to 566f63e Compare August 22, 2026 03:07
@qodo-code-review

qodo-code-review Bot commented Aug 22, 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


Action required

1. Stamped flows misclassified duplicate ✓ Resolved 🐞 Bug ≡ Correctness
Description
McpRegistrationAudit.ArgsAreCanonical treats kcap-flows ... --driver <known-vendor> as a
canonical duplicate, so kcap daemon doctor --clean can delete a user entry even though --driver
changes driver_vendor output and is therefore a real customization. This can silently change
list_reviewer_vendors results by reverting from stamped driver identity to env inference.
Code

src/Capacitor.Cli.Core/Mcp/McpRegistrationAudit.cs[R234-238]

+        return extra == 2
+            && string.Equals(name, KcapMcpServers.FlowsServerName, StringComparison.OrdinalIgnoreCase)
+            && string.Equals(StringValue(args[descriptor.Args.Length]), KcapMcpServers.DriverArg, StringComparison.Ordinal)
+            && StringValue(args[descriptor.Args.Length + 1]) is { } vendor
+            && HarnessMcpProjections.DriverStampVendors.Contains(vendor, StringComparer.Ordinal);
Evidence
The audit now accepts a --driver <vendor> suffix as canonical for kcap-flows, meaning doctor
cleanup will remove such entries. But the flows server treats --driver as higher-precedence than
env inference and passes the resulting driverVendor into ReviewerVendorLookup.Aggregate, which
is serialized by the list_reviewer_vendors tool; removing the stamped entry therefore changes tool
output and is not semantically equivalent to the canonical plugin entry.

src/Capacitor.Cli.Core/Mcp/McpRegistrationAudit.cs[216-239]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[17-31]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[389-430]
src/Capacitor.Cli/Commands/DriverVendor.cs[20-47]
src/Capacitor.Cli/Commands/McpDoctorSection.cs[19-26]

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

### Issue description
`McpRegistrationAudit` currently classifies a `kcap-flows` entry with trailing `--driver <vendor>` as canonical, meaning `kcap daemon doctor --clean` will remove it. However `--driver` changes runtime behavior by changing the inferred `driverVendor`, which is surfaced via the `list_reviewer_vendors` tool output (`driver_vendor`). That makes the entry semantically divergent from the plugin-shipped canonical `kcap-flows` registration and it should be treated as a conflict (preserved), not a removable duplicate.

### Issue Context
- `ArgsAreCanonical` explicitly allows `kcap-flows` registrations to be considered canonical even when they include `--driver <vendor>`.
- The flows server prefers this stamp over env inference, so deleting the stamped entry changes tool responses.
- `kcap daemon doctor --clean` uses `McpRegistrationAudit.RemoveClaudeDuplicates`, so this can delete user customizations.

### Fix Focus Areas
- src/Capacitor.Cli.Core/Mcp/McpRegistrationAudit.cs[216-239]

### Suggested approach
- Make `IsCanonicalKcapEntry`/`ArgsAreCanonical` require an exact args match for canonical classification in the Claude duplicate audit, i.e., remove the special-case acceptance of `--driver`.
 - If you still need to tolerate stamped args elsewhere, parameterize the audit with an explicit mode or expected harness/vendor and only allow the stamp when auditing that harness’s own config (not Claude plugin shadowing).
- Update the unit tests accordingly (the tests that currently assert stamped flows are canonical duplicates should instead assert `Conflict`).

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


2. --driver flag undocumented ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The PR introduces a new --driver argument for kcap mcp flows but the user-facing README
documentation for the flows MCP server does not mention it. This can mislead users and leaves the
documented CLI surface out of sync with the actual behavior.
Code

src/Capacitor.Cli/Program.cs[R419-420]

            case "flows":
-                return await McpFlowsServer.RunAsync(baseUrl!);
+                return await McpFlowsServer.RunAsync(baseUrl!, GetArg(args, "--driver"));
Evidence
The PR threads GetArg(args, "--driver") into the flows subcommand and defines `DriverArg =
"--driver", making this a new CLI surface/flag. The README’s kcap mcp flows` documentation shows
only kcap mcp flows with no mention of --driver, indicating the README was not updated to
reflect the new flag.

CLAUDE.md: CLI User-Facing Surface Changes Must Update README.md in the Same PR
src/Capacitor.Cli/Program.cs[419-420]
src/Capacitor.Cli.Core/Mcp/KcapMcpServers.cs[16-21]
README.md[438-445]

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

## Issue description
This PR adds a new `--driver <vendor>` argument to the `kcap mcp flows` command path, but the README section that documents `kcap mcp flows` does not mention the new flag.

## Issue Context
Per compliance, user-facing CLI surface changes (new flags/args) must update `README.md` in the same PR.

## Fix Focus Areas
- src/Capacitor.Cli/Program.cs[419-420]
- src/Capacitor.Cli.Core/Mcp/KcapMcpServers.cs[16-21]
- README.md[438-445]

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


Grey Divider

Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/Capacitor.Cli/Program.cs
Comment thread src/Capacitor.Cli.Core/Mcp/McpRegistrationAudit.cs Outdated
…al --driver arg

- McpRegistrationAudit no longer treats a "--driver <vendor>" flows entry as a
  canonical duplicate. Its only callers audit CLAUDE's config (doctor --clean
  and the Claude launcher), whose flows entry is always the unstamped bundled
  .mcp.json; the six JSON harnesses' stamped entries live in their own configs,
  owned via their per-entry marker, and never reach this audit. A stamped entry
  appearing in Claude's config is a customization to preserve -- so
  "doctor --clean" can no longer delete it and silently revert driver_vendor
  from the stamp back to env inference.
- README now documents that kcap writes the internal "--driver <vendor>" arg
  into the JSON harnesses' flows registration -- it is not a flag users set.

Refs AI-2175.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung
realtonyyoung merged commit ca4ad3a into main Aug 22, 2026
6 checks passed
@realtonyyoung
realtonyyoung deleted the ai-2175-driver-vendor-breadth branch August 22, 2026 03:32
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