Your coding agents are smarter together.
A CLI and an MCP server that convene a panel of the agents you already run β Claude, Codex, Gemini, and more β and fuse their answers into one.
A single agent is a single model's judgment β one set of blind spots. Parley sends the same problem to a panel of agent CLIs, then fuses their replies: where they agree you get high-confidence consensus, where they disagree you get a flag worth your attention, and what none caught the panel surfaces. This is the multi-model deliberation behind ** Sakana's AB-MCTS** and
β both report combined models beating any single one β but running over the CLIs already on your machine, with
OpenRouter's Fusiontheirauth and
yourcontext.
No API keys. No new vendor. Your code never leaves.
Parley is first-class both ways β a CLI you drive, and an MCP server your agent drives. Same engine, same capabilities, whichever side you call it from:
| Capability | CLI β you run it |
MCP β your agent calls it |
|---|---|---|
Fuse a panel into one answer |
par fuse "design a rate limiter" |
fuse tool |
Ask another agent, with context |
par ask -h g -p "β¦" --context-from cl |
ask_agent tool |
Resume any agent's session here |
par resume |
list_sessions Β· get_last_session Β· resume_command |
Converse β two agents, multi-turn |
par converse --a cl --b g -p "β¦" |
(compose via ask_agent ) |
Route a prompt to any agent |
par -p "β¦" -h <agent> |
β |
Convert one config to every agent |
par convert |
β |
par fuse "design a rate limiter for this service" # panel + judge β one fused answer
par mcp connect -h cl # registers the MCP server into Claude
Parley is a small, dependency-free Rust CLI (binary: par
). It never calls a model API itself β it drives the agent CLIs you already have, so your auth, models, and permissions stay with them. The MCP server exposes the very same operations as tools, so nothing is locked to one surface.
A single agent is a single point of view. Every coding agent ships one model's training, one model's failure modes, one model's blind spots. On the calls that matter β an architecture decision, a security review, a tricky migration β there's no second opinion, no disagreement to flag risk, no way to combine the model that reasons best with the model that writes the best code.
Research labs already proved the fix. Sakana's AB-MCTS lets frontier models cooperate at inference time and reports problems no single model could solve becoming solvable. OpenRouter's Fusion runs a panel plus a judge and reports a fused pair beating every individual model. The catch with both: API-side, single-vendor, and your code leaves your machine.
Parley does it locally β and fixes the other half of the problem, that the agents are silos. Each CLI has its own headless interface (claude -p
, codex exec
, gemini --prompt
, goose run -t
, opencode run
, aider --message
), its own config format, and its own on-disk session store β none can see each other. So:
Agents can't combine. Two models with different strengths have no way to review each other's work, debate, or vote on an answer.Scripts are brittle. Switching agents means rewriting commands, model flags, provider syntax, and env vars.Config is duplicated. The same instructions, commands, and MCP servers get hand-maintained once per agent.Work gets stranded. A conversation lives inside whichever agent you started in; you can't pick it up elsewhere.
Parley is the interoperability layer that removes all four β and turns it into collective intelligence:
Fuseβpar fuse "..."
sends your prompt to a panel of agents in parallel, then a judge (Claude by default) synthesizes one answer from their consensus, contradictions, and blind spots. Same thing is anMCP tool, so an agent can convene its own panel mid-task β escalation when a question is worth more than one model.** One interface**β route any prompt to any agent by changing a single flag (par -p
,-h <agent>
). The adapter owns the translation.One configβ author your.claude/
pack once,par convert
generates each agent's native config from it.Portable sessionsβpar resume
lists and resumes any agent's past sessions for this folder, regardless of which agent created them.Agents that collaborateβpar ask
lets one agent query another (seeded with a shared session's context), andpar converse
puts two agents in a multi-turn conversation. Expose it over MCP withpar mcp
so an agent can do this itself β"ask Gemini to review this, with my Claude context."
The result: your automation describes intent, not which agent is wired up today β and your agents stop being islands and start being a team.
New to fusion?The[Fusion Playbook]is the how-to for ~10Γ better results: when to fuse, how to pick a diverse panel, and the debate / wider-deeper / second-opinion patterns.
One command:
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/KerryRitter/parley/main/install.sh | sh
This installs par
into ~/.local/bin
(plus an agent-router
alias). Make sure that directory is on your PATH
:
export PATH="$HOME/.local/bin:$PATH"
par --version # verify
par
routes to agent CLIs β it does not install them for you automatically. Install the agents you want with[, or bring your own.]par install
From source (needs Rust):
git clone https://github.com/KerryRitter/parley.git
cd parley
scripts/setup.sh --install # validates, then `cargo install --path . --force`
This creates ~/.local/bin/par
and ~/.local/bin/agent-router -> par
. Ensure both ~/.cargo/bin
and ~/.local/bin
are on your PATH
.
Direct from GitHub:
cargo install --git https://github.com/KerryRitter/parley.git --branch main --force
Install-script options (append after sh -s --
):
... | sh -s -- --install-dir /usr/local/bin # custom location
... | sh -s -- --from-source # force a source build
... | sh -s -- --from-source --git-protocol ssh
... | sh -s -- --no-agent-router # skip the agent-router alias
The script installs a prebuilt release binary for your platform when available, and falls back to a source build otherwise. (Release-binary and Homebrew distribution are planned; see Release Plan.)
| Command | Capability |
|---|---|
par -p "..." |
par fuse "..."
par default <agent>
par install <agent>
par shims install
claudey
/ codexy
one-shot shortcutspar convert
.claude/
config to every other agentpar resume
par ask
par converse
par mcp
fuse a panel, ask each other, and resume sessions
par # launch the default agent interactively
par -p "summarize this repository" # one-shot prompt
par -h co -m gpt-5.4 -p "add tests" # choose an agent + model
git diff | par -p "review this patch" # pipe context in
par -p "review src" --dry-run # print the routed command instead of running it
Choosing the agent β -h
/ --harness
takes a full name or a short code:
| Code | Agent | Code | Agent | Code | Agent |
|---|---|---|---|---|---|
cl |
|||||
| claude | g |
||||
| gemini | q |
||||
| qwen | |||||
co |
|||||
| codex | go |
||||
| goose | a / ai |
||||
| aider | |||||
cu |
|||||
| cursor | oc |
||||
| opencode | aq |
||||
| amazon-q | |||||
cp |
|||||
| copilot | k |
||||
| kimi | ag |
||||
| antigravity |
par -h cl "review this"
par -h co -m gpt-5.4 "fix tests"
par -h k -p "drain the queue"
Bare
-h
(no value) prints help;-h <name>
selects an agent.
| Flag | Purpose |
|---|---|
-p , --prompt , --print |
|
Prompt text (--print is accepted for Claude compatibility). |
|
-h , --harness <name> |
|
Target agent. Defaults to claude . Accepts short codes. |
|
--provider <name> |
|
| Provider namespace, when the agent uses provider-qualified models or env config. | |
-m , --model <name> |
|
| Model name. | |
--agent <name> |
|
| Agent/persona/profile, where supported. | |
--output-format <fmt> |
|
Output mode (e.g. json ), where supported. |
|
--input-format <fmt> |
|
| Claude-compatible input format. | |
--permission-mode <mode> |
|
| Permission/sandbox mode, where supported. | |
--max-turns <n> |
|
| Max agent turns, where supported. | |
--cwd <path> |
|
| Working directory for the child process. | |
--yolo / --no-yolo |
|
| Add / skip the agent's permission-bypass flag. On by default. | |
--dry-run |
|
| Print the routed invocation as JSON; run nothing. | |
--version , -v |
|
| Print version. | |
--help |
|
| Print help. | |
-- |
|
| Pass everything after it straight to the agent CLI. |
Pass agent-specific flags after --
:
par -h cl -p "review this" -- --verbose
par -h aider -p "fix lint" -- --yes --no-auto-commits
How prompt input is resolved:
- No prompt and no stdin β launch the agent's interactive entrypoint.
- stdin piped
and
-p
given β stdin is placed before the prompt, blank line between. - stdin piped, no
-p
β stdin becomes the prompt.
Every run adds the agent's permission-bypass flag (e.g. --dangerously-skip-permissions
for Claude) so automation runs hands-off. Opt out per run with --no-yolo
, or persistently with PARLEY_YOLO=false
. Agents with no known bypass flag (e.g. Amazon Q) simply run without one. Opt out when running untrusted prompts or in sensitive directories.
So you don't repeat -h
every time:
par default codex # set default agent
par default claude --yolo # set agent + persist yolo
par default --no-yolo # keep agent, disable yolo
par default # show current defaults
par default --path # print the config file path
par current # alias for showing defaults
par list # list supported agent names
The default lives in ~/.config/par/default
(or $XDG_CONFIG_HOME/par/default
; override with PAR_DEFAULT_FILE
).
export PARLEY_HARNESS=codex
export PARLEY_PROVIDER=openai
export PARLEY_MODEL=gpt-5.4
export PARLEY_YOLO=true
Generate *y
one-shot shortcuts for yolo-capable agents:
par shims install # writes claudey, codexy, ... to ~/.local/bin
claudey -p "work in this sandbox"
codexy "work in this sandbox"
Override the location with par shims install --dir <dir>
or PAR_SHIM_DIR
. par shims list
prints the generated names and commands.
par fuse
is the collective-intelligence command. It sends your prompt to a panel of agents in parallel, then hands every reply to a judge agent β Claude by default β that synthesizes a single answer: where the panel agreed (high-confidence), where it disagreed and who's right, and what it missed. Same idea as OpenRouter's Fusion and Sakana's AB-MCTS, over the CLIs you already run. It's available both as this command and as an MCP tool so an agent can convene its own panel mid-task.
par fuse -p "design a rate limiter for a multi-tenant API" # default panel: claude, codex, gemini
par fuse "is this migration safe to run on a live DB?" --panel cl,co,k
par fuse "..." --judge co --judge-model gpt-5.4 # choose the judge and its model
par fuse "..." --context-from cl # seed every panelist with your latest claude session here
par fuse "..." --panel cl,co,g --dry-run # print every routed command (panel + judge), run nothing
| Flag | Purpose |
|---|---|
--panel <codes> |
|
Comma-separated panel agents (short codes allowed). Defaults to claude,codex,gemini . Needs β₯2; duplicates are allowed (self-pairing is a valid technique). |
|
--judge <agent> |
|
| Agent that synthesizes the panel. Defaults to claude. | |
--judge-model <m> |
|
| Model for the judge. | |
--context-from <h[:s]> |
|
Prepend a prior session's transcript to every panelist, so the panel deliberates with your context (sources: claude , codex , opencode ). |
|
--max-context , --cwd , --no-yolo , --dry-run |
|
| As in | |
par ask |
Panelists run concurrently, so wall-clock β the slowest agent + the judge, and cost β N+1 agent runs. A panelist whose CLI isn't installed is skipped with a note; fusion needs at least two to succeed. Alias: par panel
.
Fuse selectively β it's escalation, not autopilot. Reach for it on the calls where being wrong is expensive (design, security, migrations), and use a diverse panel (different vendors, not three of the same model). The Fusion Playbook covers when to fuse, how to pick the panel, and the debate / wider-deeper patterns that stack on top.
par
can install the downstream agents it routes to:
par install list # show installer coverage
par install claude # install one agent
par install all # install every supported agent
par install --dry-run all # print the exact upstream commands, run nothing
The registry is transparent β --dry-run
prints the real upstream install command. Agents without a stable one-liner (e.g. Amazon Q) print the official install page and a verify command instead of guessing.
| Agent | Installer |
|---|---|
claude |
|
| `curl -fsSL https://claude.ai/install.sh | bash` |
codex |
|
npm install -g @openai/codex |
|
cursor |
|
| `curl https://cursor.com/install -fsS | bash` |
gemini |
|
npm install -g @google/gemini-cli |
|
goose |
|
| `curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash` |
opencode |
|
| `curl -fsSL https://opencode.ai/install | bash` |
qwen |
|
| `curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen.sh | bash` |
aider |
|
| `curl -LsSf https://aider.chat/install.sh | sh` |
amazon-q |
|
Manual official installer page; verify with q --version |
|
copilot |
|
| `curl -fsSL https://gh.io/copilot-install | bash` |
kimi |
|
| `curl -LsSf https://code.kimi.com/install.sh | bash` |
antigravity |
|
| `curl -fsSL https://antigravity.google/cli/install.sh | bash` |
par
does not manage agent versions; each downstream CLI owns its own upgrade flow.
par convert
ports a Claude command/skill pack to other agents. Your .claude/
directory (commands, skills, agents/
, references), CLAUDE.md
, and .mcp.json
stay the single source of truth; convert generates each agent's native config from them.
par convert # claude -> all targets
par convert --to kimi # claude -> one target
par convert --from claude --to codex
par convert --dry-run # show what would be written
par convert --cwd path/to/project
Source: claude
. Targets: gemini
, codex
, antigravity
, opencode
, cursor
, kimi
.
What it does:
Parses frontmatterβ real descriptions, per-commandmodel
, argument placeholders; strips the block from bodies.Reads commands, skills, personas (.claude/agents/
), references, and.mcp.json
.Emits native artifacts per targetβ e.g..kimi/skills/<name>/SKILL.md
+.kimi/mcp.json
,.codex/config.toml
+.agents/skills/
,.gemini/commands/*.toml
+GEMINI.md
,.cursor/rules/
,.opencode/config.json
, plusAGENTS.md
. MCP servers in.mcp.json
are translated into each agent's format.Resolves cross-referencesβ every/command
,**skill** skill
, persona path, and reference path is checked against the pack. The run prints a resolution report andexits non-zero if any reference dead-ends, so a typo fails the convert instead of shipping a broken pack.
Generated skills carry a par-convert:generated
marker, so re-running replaces only its own output and never a hand-authored file. Commit .claude/
; git-ignore the generated output. A typical npm run sync:instructions
is just par convert --from claude --to all
.
par resume
browses and resumes sessions from any agent, scoped to the current directory β the same scoping every agent's own --resume
uses. It reads the transcripts each agent already writes to disk; there are no extra files to maintain.
par resume # list this folder's sessions (any agent), pick one
par resume -h cl # resume a claude session here (picker if several)
par resume -h co --latest # resume the newest codex session, no prompt
par resume --list # print the listing, resume nothing
par resume --list --json # machine-readable listing
par resume -h cl <id> --print # print the resume command for a session id
par resume --cwd path/to/proj # scope to another directory
A selector is either a list index (par resume 2
) or a raw session id (par resume -h cl <id>
). Add --yolo
to append the agent's permission-bypass flag (off by default here, since resume drops into an interactive session).
Two tiers of support:
Native listingβclaude
,codex
,opencode
. Read straight from disk (~/.claude/projects/<slug>/
,~/.codex/sessions/
,~/.local/share/opencode/storage/session/
), matched on exact cwd, with title and recency. These show up in the cross-agent listing.Delegate resumeβcursor
,gemini
. Their stores are hash-scoped in a waypar
doesn't reproduce, but the binaries self-scope to the cwd. Listing is skipped (marked~
); resume runs the agent's own cwd-scoped resume (cursor-agent resume
,gemini --resume latest
).par resume -h cu
/par resume -h g
work directly.
par ask
runs another agent headless and returns its reply as text. Because par
already routes a prompt to any agent, "Claude asks Gemini" is just routing the prompt to Gemini and capturing its output. With --context-from
, par
first reads a prior session's transcript and prepends it β so the answer is informed by that history. This is the cross-agent context bridge.
par ask -h g -p "critique this approach in 3 bullets" # ask gemini, print its reply
par ask -h g -p "what did we decide?" --context-from cl # seed with your latest claude session here
par ask -h cl -p "continue this" --context-from co:<id> # use a specific source session id
par ask -h g -p "..." --max-context 8000 # cap injected context (default 12000 chars)
par ask -h g -p "..." --dry-run # show the routed command + final prompt, run nothing
--context-from
takes harness[:session]
; omit the session (or use latest
) for the newest in the directory. Context sources: claude
, codex
, opencode
(full transcripts). cursor
/ gemini
can't export transcripts, so they can't be context sources β they can still be asked.
Notes: each call is one-shot (the target keeps no memory between asks); yolo is on by default so the headless agent can't block on a permission prompt; long transcripts are truncated to the most recent turns within the budget.
par converse
puts two agents in one conversation: A speaks, B replies, A replies, and so on. Each agent is stateless and headless, so par
itself holds the running dialogue and feeds it back every turn β par ask
's context bridge, accumulated across the loop. Output streams turn by turn so you can watch them work.
par converse --a cl --b g -p "Design a rate limiter; A proposes, B critiques."
par converse --a cl --b g -p "Agree on a name." --turns 8 --until AGREED
par converse --a cl --b g -p "Continue this." --context-from co # seed turn 1 with a codex session
par converse --a cl --b g -p "..." --a-model <m> --b-model <m> --dry-run
--a
/--b
β the two agents (short codes allowed).--a-model
/--b-model
set per-agent models.--turns N
β total turns, alternating, starting with A (default 6; capped at 50).--until <phrase>
β stop early when a reply contains the phrase (agents are told to emit it when done).--context-from harness[:session]
β seed the first turn with a prior session's transcript.--max-context
,--cwd
,--no-yolo
,--dry-run
as inpar ask
. Aliases:par debate
,par relay
.
Each turn spawns a full agent process, so cost and latency scale with --turns
. The loop is two-party; --until
is the way to end before the turn budget.
par mcp
runs a small MCP server over stdio (newline-delimited JSON-RPC 2.0), so any MCP-capable agent can convene a panel and fuse it, ask other agents questions, and resume sessions β all from inside the agent you're already in. This is how you say "fuse this across Codex and Gemini", "ask Gemini to review this with my Claude context", or "pick up my last conversation from Claude" without leaving your agent.
Tools:
β the collective-intelligence tool. Sendsfuse {prompt, panel?, judge?, judge_model?, cwd?, context_from?: {harness, session?}}
prompt
to every agent inpanel
(defaultclaude,codex,gemini
)in parallel, then a judge agent (judge
, defaultclaude
) synthesizes one answer β consensus as high-confidence, contradictions resolved, gaps filled, blind spots flagged β and returns it as text.context_from
seeds every panelist with a prior session. Needs β₯2 panelists; ones whose CLI isn't installed are skipped with a note. (Same engine as thepar fuse
command.)ask_agent {harness, prompt, model?, provider?, cwd?, context_from?: {harness, session?}}
β run another agent headless and return its reply, optionally seeded with a session transcript. The agent-to-agent / context-bridge primitive.list_sessions {cwd?, harness?}
β resumable sessions for a directory, newest first.get_last_session {cwd?, harness?}
β the most recent session plus a ready-to-run resume command.resume_command {harness, id, cwd?, yolo?}
β build the native resume command for a session id (text; never spawns an interactive agent).
Why fuse is also a tool, not just a command: like OpenRouter's Fusion, fusion is
escalation, not autopilotβ exposing it as a tool lets the model decide a question is worth more than one opinion and convene the panel itself, mid-task, without you running anything. (The
par fuse
command does the same thing from the terminal.) Use a diverse panel (different vendors, not three of the same model). The
Fusion Playbookcovers when to fuse and how to pick the panel; the debate (
par converse
) and widerβdeeper patterns stack on top.
"fuse this across codex and gemini: is this migration safe on a live DB?"β the agent callsfuse
, Parley runs Claude+Codex+Gemini in parallel, and the agent writes one answer grounded in all three.
Register it into an agent β par mcp connect
runs whatever that agent needs:
par mcp connect -h cl # claude -> runs `claude mcp add -s user par -- <par> mcp`
par mcp connect -h co # codex -> runs `codex mcp add par -- <par> mcp`
par mcp connect -h g # gemini -> runs `gemini mcp add par <par> mcp`
par mcp connect -h oc # opencode -> opens its own interactive `opencode mcp add`
par mcp connect -h cu # cursor -> merges ~/.cursor/mcp.json (no add command exists)
par mcp connect -h cl --dry-run # show the exact command / file change, do nothing
connect
registers the absolute path of the running par
, so it works regardless of the caller's PATH
. Agents with a native mcp add
are invoked directly (some, like opencode, prompt in their own TUI); cursor has no add subcommand, so its config file is merged in place, preserving existing servers.
Then, from any registered agent: "use par to pick up my last claude session here" β the agent calls get_last_session
and runs the returned claude --resume <id>
.
| Agent | Aliases | Routed command |
|---|---|---|
claude |
||
cl |
||
claude -p "<prompt>" |
||
codex |
||
co , openai |
||
codex exec "<prompt>" |
||
cursor |
||
cu , cursor-agent |
||
cursor-agent -p "<prompt>" |
||
gemini |
||
g , google , google-gemini |
||
gemini --prompt "<prompt>" |
||
goose |
||
go |
||
goose run -t "<prompt>" |
||
opencode |
||
oc , open-code |
||
opencode run "<prompt>" |
||
qwen |
||
q |
||
qwen -p "<prompt>" |
||
aider |
||
a , ai |
||
aider --message "<prompt>" |
||
amazon-q |
||
aq , amazonq , aws-q , amazon |
||
q chat "<prompt>" |
||
copilot |
||
cp , github-copilot |
||
copilot -p "<prompt>" |
||
kimi |
||
k , moonshot , kimi-code |
||
kimi -p "<prompt>" |
||
antigravity |
||
ag , agy , google-antigravity |
||
agy "<prompt>" |
Per-agent flag mappings
Claude β claude -p
. Supports --model
, --output-format
, --input-format
, --permission-mode
, --max-turns
. Yolo β --dangerously-skip-permissions
.
Codex β codex exec
. --output-format json|stream-json
β --json
. Provider is preserved in PARLEY_PROVIDER
(Codex receives the plain model name). Yolo β --dangerously-bypass-approvals-and-sandbox
for routed runs; the codexy
shim uses codex --yolo
.
Cursor β cursor-agent -p
. Plain --model
; --output-format
when accepted. Yolo β --force
(required for print-mode file writes).
Gemini β gemini --prompt
. Plain --model
; --output-format
when accepted. Yolo β --yolo
.
Goose β goose run -t
. --provider
βGOOSE_PROVIDER
, --model
βGOOSE_MODEL
, --permission-mode
βGOOSE_MODE
, --max-turns
βGOOSE_MAX_TURNS
, --agent
β--with-builtin
. Yolo sets GOOSE_MODE=auto
unless --permission-mode
is given.
OpenCode β opencode run
. --provider anthropic --model claude-sonnet-4-6
β --model anthropic/claude-sonnet-4-6
. --output-format json|stream-json
β --format json
. --agent
β--agent
. Yolo β --dangerously-skip-permissions
.
Qwen β qwen -p
. Plain --model
; --output-format
when accepted. Yolo β --yolo
.
Aider β aider --message
. Provider+model joined for --model
(e.g. anthropic/claude-sonnet-4-6
). Use --
for Aider flags like --yes
. Yolo β --yes-always
.
Amazon Q β q chat
. --agent
β--agent
. Model selection owned by Amazon Q config.
Copilot β provisional. copilot -p
. Yolo β --yolo
. Validate against the installed CLI before relying on it.
Kimi β kimi -p
. Plain --model
, --output-format
. Yolo β --yolo
. Auto-loads project MCP: when ./.kimi/mcp.json
exists (relative to --cwd
or the process cwd), the adapter adds --mcp-config-file <cwd>/.kimi/mcp.json
, so the project config generated by par convert
loads automatically.
Antigravity β experimental. Uses the agy
command. Docs currently describe the interactive AGY CLI rather than a headless mode; the adapter passes the prompt and leaves version-specific flags to --
. Yolo β --dangerously-skip-permissions
.
scripts/setup.sh # full local validation (fmt, test, clippy, release build, agent check)
scripts/setup.sh --strict-harnesses # also require at least one agent CLI installed
scripts/setup.sh --install # validate, then install the binary
Direct commands:
cargo fmt
cargo test
cargo clippy --all-targets -- -D warnings
cargo build --release
cargo run -- -h oc --provider anthropic --model claude-sonnet-4-6 -p "review" --dry-run
Expected --dry-run
shape:
{
"command": "opencode",
"args": ["run", "--model", "anthropic/claude-sonnet-4-6", "review"],
"env": {}
}
src/
main.rs entrypoint, stdin handling, dry-run, dispatch
cli.rs command-line parser
model.rs provider/model resolution
process.rs child process execution (inherit-stdio run + captured run)
json.rs zero-dep JSON parser/serializer (used by convert, session, ask, mcp)
ask.rs agent-to-agent calls (headless run + transcript context injection)
converse.rs multi-turn two-agent conversation loop
fuse.rs panel fusion engine β parallel panel + judge (`par fuse` and the mcp `fuse` tool)
mcp.rs stdio MCP server (resume tools + ask_agent + fuse) + `mcp connect`
harness/ per-agent adapters (claude, codex, cursor, gemini, goose,
opencode, qwen, aider, amazon_q, copilot, kimi, antigravity)
mod.rs Harness trait, Request, HarnessFactory, normalize_harness
invocation.rs command/args/env representation
convert/ .claude/ reader + per-target writers + cross-reference resolver
session/ cross-agent session discovery, resume, and transcript export
mod.rs SessionStore trait, SessionRef, Turn, listing + resume + context
claude.rs codex.rs opencode.rs native parsers (cwd-scoped listing + transcripts)
cursor.rs gemini.rs delegate adapters (resume via native CLI)
installer.rs agent installer registry
Design constraints: no sh -c
(adapters build argv directly); no hidden API calls (only starts local CLIs); no login handling (authenticate each agent separately); agent-specific behavior stays in its module; provider/model transforms stay centralized in model.rs
; --dry-run
output stays stable enough for tests.
- Create
src/harness/<name>.rs
and implementHarness
for a small adapter struct. - Register it in
HarnessFactory::default()
. - Add aliases in
normalize_harness()
if useful. - Add dry-run tests (command, args, provider/model, env, passthrough).
- Document it in this README.
use super::{add_passthrough, plain_model, Harness, Invocation, Request};
pub(crate) fn new() -> Box<dyn Harness> {
Box::new(ExampleHarness)
}
struct ExampleHarness;
impl Harness for ExampleHarness {
fn build(&self, request: &Request) -> Result<Invocation, String> {
let mut args = vec!["run".to_string(), request.prompt.clone()];
if let Some(model) = plain_model(request) {
args.extend(["--model".to_string(), model]);
}
Ok(Invocation::new("example", add_passthrough(args, request)))
}
}
Working infrastructure for local automation.
Done: dependency-free Rust CLI Β· shared claude -p
-style prompt surface Β· isolated per-agent adapters Β· agent installers Β· provider/model resolution Β· dry-run routing Β· cross-agent session resume Β· agent-to-agent calls with context bridging Β· multi-turn two-agent conversations Β· panel fusion (par fuse
- mcp
fuse
tool) Β· stdio MCP server Β· validating setup script.
Not yet: GitHub Actions release builds Β· Homebrew formula Β· end-to-end smoke tests against every vendor CLI Β· a stable semver contract per agent mapping.
scripts/setup.sh
.- Smoke-test locally available CLIs with
--dry-run
. - CI:
cargo fmt --check
,cargo test
,cargo clippy --all-targets -- -D warnings
, and release binaries for Linux/macOS/Windows (par-<target>.tar.gz
/.zip
). - Add archive checksums, publish a GitHub release.
- Add a Homebrew tap once artifact names are stable.
par
does not inspect or redact prompt content. Anything passed via stdin or -p
is forwarded to the selected agent, which may send it to its configured provider.
Yolo (permission bypass) is on by default β each run adds the agent's bypass flag unless you pass --no-yolo
or set PARLEY_YOLO=false
. This favors hands-off automation over sandboxing; opt out for untrusted prompts or sensitive directories. Use --dry-run
to validate automation that may include secrets before running it.
Written against public docs (checked May 19, 2026): Claude, Codex, Cursor, Gemini, OpenCode, Qwen, Aider, Amazon Q, Goose, Antigravity. Installer commands live in src/installer.rs
. Agent CLIs change fast β re-check these surfaces before a public release.