cd /news/ai-agents/show-hn-cli-and-mcp-for-model-fusion… Β· home β€Ί topics β€Ί ai-agents β€Ί article
[ARTICLE Β· art-37815] src=github.com β†— pub= topic=ai-agents verified=true sentiment=↑ positive

Show HN: CLI and MCP for model fusion via harnesses

Parley, a new CLI and MCP server, enables local multi-model deliberation by fusing answers from multiple AI coding agents like Claude, Codex, and Gemini into a single response, providing consensus or flagging disagreements without sending code to external APIs.

read24 min views6 publishedJun 24, 2026
Show HN: CLI and MCP for model fusion via harnesses
Image: source

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.

── more in #ai-agents 4 stories Β· sorted by recency
── more on @parley 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/show-hn-cli-and-mcp-…] indexed:0 read:24min 2026-06-24 Β· β€”