AgentStack
MCP verified MIT Self-run

Agent Duet

mcp-chriswu727-agent-duet · by chriswu727

Local Codex + Claude Code collaboration: one writer, one independent reviewer, finite rounds, subscription-backed CLIs, no API keys.

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add mcp-chriswu727-agent-duet

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution Used
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README — it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-chriswu727-agent-duet)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
9d ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Agent Duet? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Duet

Codex builds. Claude challenges. Your subscriptions stay local.

Duet is a local desktop app that lets Codex implement a coding task while Claude Code independently reviews the result, using the subscriptions already signed in on your computer.

Duet is a bounded desktop collaboration loop for AI coding tools. Give it one concrete task in a Git repository: Codex implements the change, Claude Code independently reviews the working tree, and only evidenced findings go back for revision. One writer, one reviewer, finite rounds.

[](https://github.com/chriswu727/agent-duet/actions/workflows/ci.yml) [](https://github.com/chriswu727/agent-duet/security/code-scanning) [](https://scorecard.dev/viewer/?uri=github.com/chriswu727/agent-duet) [](#quick-start) [](./docs/COMPATIBILITY.md) [](./test) [](./LICENSE)

[Quick start](#quick-start) · [How it works](#how-it-works) · [Safety model](#safety-model) · [Compatibility](./docs/COMPATIBILITY.md) · [Privacy](./PRIVACY.md) · [Binary release status](./docs/RELEASE_READINESS.md)

The local app detects the official CLI sessions already on your machine. Handoff estimates describe compact prompt size—not account usage or remaining subscription capacity.


Current status

| Surface | Status | |---|---| | Clone and run from source | Ready on macOS, Windows, and Linux with Node.js 22.12+ and pnpm 10 | | Authentication | Existing ChatGPT and Claude.ai subscription sessions through the official local CLIs; no API keys or API-credit fallback | | Automated verification | 99 offline tests plus packaged UI startup on GitHub-hosted macOS, Windows, and Ubuntu runners | | Signed installers | Not published yet; existing v0.1.0 assets are historical unsigned alpha builds | | Real subscription smoke | Guarded and documented, but intentionally not claimed as run without explicit subscription-use consent |

Why Duet

Running two coding agents in separate terminals sounds simple until both edit the same file, paste entire transcripts back and forth, or argue through your usage limit. Duet makes the roles and stopping conditions structural.

| Ad-hoc two-agent workflow | Duet | |---|---| | Both agents may write | Codex is the only writer | | Reviewer inherits the implementer's framing | Claude starts from a fresh review context | | Full chat logs get copied between models | Only the task, diff summary, verification result, and capped findings cross the handoff | | "Looks good" can override a broken test | A failed verification command blocks PASS | | The debate can recurse indefinitely | Stops on pass, blocked review, no progress, repeated findings, cancellation, rounds, or time | | API keys often end up in another orchestrator | Uses the official local CLI logins; API-key overrides are stripped from child environments |

Duet does not promise that two models make every change correct. It makes the collaboration inspectable, asymmetric, and finite.

How it works

flowchart LR
    U([Task + clean Git repo]) --> W[Create isolatedGit worktree]
    W --> C[Codeximplement]
    C --> V[Run explicitverification]
    V --> R[Claude Coderead-only review]
    R -->|PASS + checks pass| D[Review result]
    D -->|Apply| A([Changes in original repo])
    D -->|Discard| X([Original repo untouched])
    R -->|actionable findings| H[Compact handoff]
    H --> C2[Same Codex threadrevise]
    C2 --> V
    R -->|blocked / repeated / no progress| S([Stop safely])
  1. Preflight — confirm both CLIs are installed, subscription-backed sessions

are active, required MCP and review-isolation options are available, and the selected Git working tree is clean.

  1. Isolate and implement — create a detached managed Git worktree, then launch

the official Codex stdio MCP server there with workspace-write sandboxing and no interactive approvals. The selected repository stays untouched.

  1. Verify — run the command you supplied, such as pnpm test, with an

ephemeral home and without agent, provider, proxy, or Node injection values.

  1. Challenge — launch a fresh Claude Code reviewer in plan mode with write,

delegation, web, plugin, and nested MCP capabilities disabled. Claude Code's JSON Schema output is validated again inside Duet before any finding reaches Codex.

  1. Revise or stop — send only valid findings to the same Codex thread. Stop as

soon as the result passes or a deterministic stop condition fires.

  1. Apply or discard — inspect the changed-file list, then explicitly apply the

isolated result or discard it. An exact-state Undo remains available after Apply until you edit, stage, or commit newer work.

The compact implementation policy is inspired by Ponytail: understand first, reuse what exists, prefer the platform and installed dependencies, and make the smallest correct diff. Duet never minimizes away validation, security, accessibility, or data-loss protection.

Quick start

1. Install the prerequisites and verify both subscriptions

  • Node.js 22.12+
  • pnpm 10
  • Git
  • Codex CLI, signed in with ChatGPT
  • Claude Code, signed in with Claude.ai

Confirm the same terminal that will start Duet can see both sessions:

codex login status
claude auth status --json

Codex must report a ChatGPT-backed login and Claude Code must report "authMethod": "claude.ai". API-key and provider-compatible logins are outside Duet's supported contract. Duet launches these official sessions locally, never asks for either credential, and does not fall back to API credits. Normal provider subscription limits still apply.

2. Clone and start Duet

git clone https://github.com/chriswu727/agent-duet.git
cd agent-duet
corepack enable
pnpm install --frozen-lockfile
pnpm start

If corepack is unavailable, install pnpm 10 with your normal Node.js toolchain and confirm pnpm --version reports major version 10. pnpm start opens the Electron app directly from source; it does not install an unsigned system package or contact the update channel. Keep the terminal open while Duet runs.

3. Run one bounded collaboration

  1. Choose a clean Git repository. Duet refuses dirty trees to avoid

overwriting unrelated work.

  1. Write one concrete task.
  2. Optionally provide a verification command.
  3. Choose 1–6 review rounds, a 10–120 minute ceiling, and the Claude reviewer

model.

  1. Start. The run receipt shows phases, structured findings, verification,

bounded retries, changed files, and the exact reason the loop stopped.

  1. Apply or discard the isolated result. Pending runs survive an app restart;

Duet never copies them into the original repository automatically.

The first-run guide explains these boundaries before any model can be called. Use Settings to save run defaults and choose a local-history limit; Duet stores the default rounds, time, reviewer model, verification command, and that limit, but does not remember task text or a repository path in settings. Use Inspect diff on an isolated workspace before deciding to Apply, Discard, or Undo.

By default, the 100 most recent completed, stopped, blocked, or failed run receipts are kept in Duet's local app-data folder and can be reopened from Local history. A receipt includes the task, repository path, base commit, structured findings, check outcomes, error codes, and stop reason. It does not include either agent's transcript or credentials. Keep 10–100 receipts, disable future history, delete one, or clear all history from the app. See [PRIVACY.md](./PRIVACY.md) for every local data category and deletion path.

The default is 3 rounds and 60 minutes. These are per-run safety stops—not token quotas and not a statement about your remaining subscription capacity.

Troubleshooting

| Symptom | Check | |---|---| | Duet cannot find codex or claude | Run codex --version and claude --version in the same terminal before pnpm start. Restart the terminal after installing a CLI. On Windows, also check where codex and where claude; on macOS/Linux, use command -v codex and command -v claude. | | A CLI is installed but authentication is rejected | Re-run the two status commands above. Duet accepts the supported ChatGPT and Claude.ai subscription login types, not API-key or third-party provider sessions. | | A repository is rejected before the run | Run git status --short in that repository. Commit, stash, or deliberately remove every tracked and untracked change before selecting it again. | | Claude says PASS but the run does not complete | The verification command failed or the review envelope was invalid. Machine checks always override a model verdict; run the same verification command manually to inspect its output. | | Apply or Undo is refused | The original repository changed after Duet captured its exact state. Inspect the pending diff and keep or discard it deliberately; Duet will not force an unsafe overwrite. | | Source startup fails after an update | Confirm node --version is 22.12 or newer, pnpm --version is 10.x, then rerun pnpm install --frozen-lockfile and pnpm start. |

For supported versions and redacted diagnostic guidance, see [Compatibility](./docs/COMPATIBILITY.md) and [Support](./SUPPORT.md). Never post credentials, private source, identifying local paths, or raw agent transcripts.

FAQ

Does Duet use API credits?

No. Duet supports the official Codex CLI logged in through ChatGPT and Claude Code logged in through Claude.ai. Provider API-key variables are stripped from agent child processes. Calls still count against the rules and limits of the user's own subscriptions.

Does Duet edit my selected repository immediately?

No. Work happens in a managed isolated Git worktree. The original repository changes only after an explicit Apply, and Apply fails closed if the original state changed in the meantime.

Do more rounds mean more subscription capacity?

No. Rounds and minutes are per-run safety ceilings. They neither measure nor predict remaining account capacity, and the loop stops early on pass, repeated findings, no progress, cancellation, timeout, or a blocked review.

Is source-ready the same as a signed binary release?

No. Cloning and running the source is the supported evaluation path today. Signed and notarized installers remain behind the external gates in [Release readiness](./docs/RELEASE_READINESS.md); the historical unsigned alpha assets are not presented as production-ready downloads.

Safety model

| Boundary | Enforcement | |---|---| | Single writer | Only Codex receives workspace-write access. Claude runs in plan mode. | | Clean-tree gate | A run refuses to start if Git already has tracked or untracked changes. | | Isolated writes | Codex and verification run in a managed detached worktree; the selected repository changes only after an explicit Apply. | | Guarded Apply | Apply requires the original repository to remain clean and at the exact base commit. | | Read-only diff preview | The Apply/Undo decision includes a capped, no-color unified diff built from exact Git trees, including formerly untracked files. The complete tree—not the capped display—is transferred on Apply. | | Exact-state Undo | Undo runs only while the repository fingerprint exactly matches Duet's applied result; newer edits fail closed. | | Crash recovery | Active and mid-Apply manifests are persisted. Restart recovery applies only an exact content fingerprint and locks mismatches for manual inspection. | | Credential isolation | Child environments use an allowlist; OpenAI, Anthropic, and other provider API-key variables are omitted. | | Verification isolation | Verification gets an ephemeral home/cache/config tree and no agent, provider, proxy, or Node injection variables. It still runs with the local user's OS permissions and is not claimed as a security sandbox. | | No nested agent loop | Codex MCP servers are cleared; Claude plugins, skills, nested MCP, web access, delegation, and write tools are disabled. | | Fail-closed review | Claude Code produces JSON Schema-constrained output; Duet validates field types and verdict invariants again. Missing, malformed, or contradictory reviews become BLOCKED, never PASS. | | Machine check wins | Claude cannot PASS a non-zero verification result. | | Progress detection | Duet hashes tracked diffs and untracked contents; an unchanged revision stops the loop. | | Bounded output | Agent output and cross-agent findings are capped before display or handoff. | | Bounded retry | Only an explicitly transient Claude read-only review may retry, once. Codex write calls, timeouts, protocol failures, and permanent failures are never replayed automatically. | | Stable errors | Failures carry a durable code, category, phase, and retryability flag for diagnosis without exposing child-process causes. | | Private preferences | Settings are schema-validated, atomically replaced, and stored with private file permissions. Invalid settings are quarantined and safe defaults are restored. | | Versioned history | Receipt v2 records evidence without model transcripts. The configurable newest 10–100 are written atomically with private local permissions; history can also be disabled or deleted in-app. | | Process cleanup | Cancel and timeout terminate Unix process groups or Windows process trees, with a forced cleanup fallback. | | Desktop hardening | Electron uses context isolation, renderer sandboxing, an exact-origin/top-frame IPC gate, a narrow preload bridge, CSP, denied permissions, blocked navigation, ASAR integrity, and explicit production fuses. |

Duet is designed for personal, local use. It is not a hosted credential proxy, does not implement ChatGPT or Claude.ai OAuth, and should not be turned into a multi-user service that routes subscription credentials.

Why Claude is not called through MCP today

Codex runs through its official codex mcp-server. Claude Code documents claude mcp serve, but the tested Claude Code 2.1.208 surface advertised an Agent tool without registering a usable agent type for an external MCP client. Duet therefore uses Claude Code's official non-interactive local mode for the reviewer. The isolation policy is explicit and the adapter is small, so this can move back to MCP when the external agent contract is reliable.

Development and verification

The Quick Start above is sufficient for normal local use. Contributors can run the complete offline and package checks from the cloned repository:

pnpm check
pnpm test
pnpm run pack
pnpm run verify:package-security
pnpm run smoke:package

These checks never call either model. They use fake Codex, Claude, and MCP executables to exercise stdio, Windows command shims, CLI capability detection, verification shells, and process-tree cleanup. A real end-to-end smoke is intentionally separate and refuses to start unless both consent values are present:

DUET_LIVE_SMOKE=1 \
DUET_LIVE_SMOKE_CONFIRM=I_ACCEPT_SUBSCRIPTION_USAGE \
pnpm smoke:live

That command creates a disposable Git repository and invokes both local subscription sessions once. It is not part of CI or the default test suite.

Build an installer for the current platform:

pnpm run dist

verify:package-security reads the packaged binary and fails unless app.asar exists and all eight supported Electron fuses match the repository policy. smoke:package launches that binary through Electron's embedded Chromium and checks onboarding, settings persistence, the update bridge, blocked navigation, and renderer errors without downloading a browser or calling either model.

Th

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.