Summon is a dependency-free dispatcher. It routes tasks from one agent CLI to supported CLIs and configured endpoints wherever the host can execute a shell command:
- Coding CLIs: Claude Code, Codex, Cursor CLI, Gemini CLI, Kimi, Antigravity, and ArkCLI.
- T3 Code: install Summon into the Claude, Codex, and Cursor skill roots
T3 discovers (
python install.py --profile t3). Not a native T3 plugin; see the T3 Code setup guide. - AI IDEs: Cursor, Antigravity, or VS Code with an agent extension. The skill installs as a slash command, or the agent invokes the dispatcher.
- Desktop agent apps: the Claude app and the ChatGPT app (formerly Codex), whose agent modes can run the dispatcher and read the skill.
- A plain terminal, where you drive it yourself.
From any of those hosts, you can hand a task to another model, run several at once, convene a council, or start a governed deliberation. It also reaches any OpenAI-compatible API directly, or through OpenCode's toolful gateway when the agent needs a file/tool loop. OpenRouter, OpenAI, Anthropic, Google, and local models (Ollama, LM Studio) work as agents too.
┌──────────────────────┐
any host CLI ────────► │ summon │ ───► claude (Anthropic)
(claude, codex, │ stdlib dispatcher │ ───► codex (OpenAI)
cursor, gemini, kimi, │ one JSON envelope │ ───► cursor-agent (Cursor)
opencode, or terminal) │ no server, no pip │ ───► gemini (Google)
└──────────────────────┘ ───► kimi (Moonshot AI)
├──► agy (Antigravity)
├──► arkcli (BytePlus Coding Plan)
├──► opencode (OpenCode gateway)
└──► openai-compat (ModelArk / OpenRouter /
OpenAI / Anthropic / Google / Ollama / …)
Most multi-agent tools assume one specific CLI is the orchestrator. Summon inverts that:
any CLI can be the boss. Your Codex session can summon Claude for a review. Your Claude
session can summon Codex for an adversarial pass. Your terminal can summon a whole council
to decide something. They run in parallel. Add --worktree to give each editing agent its
own isolated branch, and inspect or branch on the resulting JSON envelopes.
Each backend uses its own login, so Summon can combine Claude, ChatGPT, Cursor, Gemini, Antigravity, ArkCLI, and OpenCode on one task. Each provider keeps its own billing and account boundary.
Who it's for
- Anyone stacking AI subscriptions. If you use Claude Max, ChatGPT, Cursor, or Gemini, Summon can put them on the same task while each provider keeps its own billing boundary. Using T3 Code as the control plane? Summon installs into the skill roots T3's Claude/Codex sessions already load.
- Developers who live in Claude Code, Codex, or Cursor (or any other AI coding tool) and want the other models one command away, without leaving the one they're in.
- Anyone who wants an independent review. Cross-vendor review keeps the model that wrote the work separate from the model that evaluates it.
- People making decisions with AI who need a governed answer: council mode gives
diverse positions and a chaired recommendation;
deliberateadds fixed options, quorum, hard attempt/deadline bounds, durable replay, and explicit human boundaries. - People who want an actual multi-agent room: the authenticated conversation atlas
keeps a persistent, project-grouped session across Codex, Claude Code, Cursor, and
terminal initiators, with human messages and explicit, bounded roster-agent turns that
can resume a compatible provider session or fork visibly on drift. Interactive council
rounds and the separate governed-decision view remain context/control-plane boundaries.
See
docs/SUMMON_CONVERSATION_PLAN.md. - Power users running fleets of agents: fan a task across N models in parallel, with per-backend throttling and resumable batches.
- Anyone unifying local + cloud models behind one interface (subscription CLIs and OpenAI-compatible APIs, including self-hosted).
Summon remains a dispatcher first, with a local conversation atlas for brainstorming, interactive council work, and explicitly requested roster-agent turns. The atlas is a dependency-free, Chatpack-informed messenger: searchable project/initiator rooms, grouped human/agent/lifecycle events, a redacted evidence drawer, cursor-aware reconnect, and a composer that separates context from an explicit turn. Turns use the same redacted, durable event contracts and a pre-launch fence; they do not turn ordinary chat into authority or silently promote a conversation into a governed decision. Chatpack itself is not installed or required.
What you can do with it
- Cross-vendor code review:
summon dispatch --agent adversarial-reviewersends your diff to a different vendor than wrote the code. - Race several implementations: three models each build the same spec in isolated git worktrees; you diff the branches and keep the best.
- Decide by council: ask "monorepo or polyrepo?" and four diverse models answer, rank each other anonymously, and a chairman synthesizes a call with confidence and dissents.
- Swarm over documents: a manifest of 40 jobs with per-backend concurrency, resumable if it crashes. Good for reviewing, summarizing, or labeling at scale.
- Structured extraction:
--json-schemavalidates an agent's final JSON and, on a backend that supports resume, spends one corrective retry when it does not match. - Governed deliberation:
summon deliberaterecords a receipt-bound, fixed-option decision policy and journal. The fresh CLI lane can run one bounded round of enforceable read-only subprocess seats after durable receipt/owner fencing; approval, resume, ACP/HTTP, and writable routes remain explicitly gated. The local browser is an observer/control surface and never silently changes the decision policy. - Use local + frontier models together: an Ollama model and Claude in the same council.
- Route named local logins: keep multiple Claude config directories behind private profile names, so a public agent definition never carries a machine path or credential.
Install
Pick the path that matches your host. All three install the skills/summon/ skill tree and
the thin sibling /council and /deliberate companions; only the destination differs.
Those companions reuse Summon's scripts and canonical references. There is no second runtime.
Agent plugin (Cursor, VS Code, Copilot, and Codex)
For clients that support the Agent Plugins standard (Cursor Marketplace, VS Code agent extensions, GitHub Copilot agent plugins, Codex with plugin support):
- From a marketplace: install the summon plugin from your client's plugin UI.
- From a checkout (local dev): copy or symlink this repo into your client's local
plugin directory. On Cursor that is
~/.cursor/plugins/local/summon/withplugin.jsonat the plugin root (this repo already ships that layout). Reload the window after copying.
The plugin bundles skills/ as-is, including the thin council and deliberate companions. No
install.py step is required for plugin hosts.
Skills registry (npx skills add)
Use one command to install the skill into your agent:
npx skills add Nafjan/summon
Your AI agent now has the summon skill. Ask it to "summon a cross-vendor review of my last
commit" or "convene a council on monorepo versus polyrepo." Add -g to install globally (every project), or
-a <agent> to target a specific one. Works with any skills-compatible agent: Claude Code,
Codex, Cursor, Gemini, Antigravity, and claw-likes like openclaw and hermes. Powered by the
open skills registry.
You need Node (for npx), Python 3.10+ on your PATH, and at least one AI CLI you're
logged into. After installing, ask your agent to run summon's doctor check and it lists what's
ready and what's missing. On Windows, if the install reports a symlink permission error, run it
again with --copy.
Multi-host installer (python install.py)
Install into every AI CLI on your machine at once (multi-host, ownership-safe):
git clone https://github.com/Nafjan/summon && cd summon
python summon.py doctor # which backends are ready? what's missing?
python install.py # install the skill into every detected AI CLI
Expired login recovery
Provider logins expire independently. If a dispatch fails with an authentication error, Summon returns a safe, vendor-specific repair plan instead of silently retrying or switching models. Check a backend without launching a task:
python summon.py auth status --cli kimi
python summon.py auth status --cli arkcli --probe
If the caller explicitly authorizes a login flow, Summon can start the vendor command (which may open a browser), but it never captures credentials and never retries the failed task:
python summon.py auth repair kimi --allow-auth-repair
# finish browser approval, then retry the original command explicitly
Without that authorization, run the vendor command yourself (kimi login, arkcli auth login, or the command shown in the error). A successful login command is not proof that a
model was served; inspect the next dispatch envelope's model.served field.
Keep the model roster fresh
The model catalog supplies editorial names and roles, not service guarantees. Refresh provider rosters when onboarding, before a high-stakes review, or after a vendor announces a model:
python summon.py models --refresh
python summon.py models --cli arkcli --refresh
source: live is a fresh provider response, source: cache is a cached roster, source: config is a local CLI default, and source: static is documentation only. Codex does not
expose a complete enumeration command, so its configured default and catalog candidates are
advisory. Pin a candidate only after a real dispatch proves the exact model.served value;
never infer a new model from a display label or a task name.
The next-release contract makes an explicit Codex pin stricter: Summon emits one canonical
model selector, refuses conflicting selectors before provider contact, and blocks a pinned run
when the provider does not return an authoritative terminal served-model receipt. A handshake
target, output-token estimate, or catalog entry is not proof that Sol (or any other model) was
served. See docs/SUMMON_3.2_PLAN.md for the routing and chat
acceptance gates. The fixed-shell chat atlas is still preview-only until its rendered-browser
and owner-lifecycle gates pass.
This does not make the Codex backend preview-only. Ordinary Codex dispatch remains a
supported first-class path. The restriction applies to provenance-required named-model claims
such as the sol-review seat: if Codex completes a turn without an authoritative terminal
identity, Summon returns status: "blocked", error_kind: "served_model_unverified",
model.targeted: "gpt-5.6-sol", and model.served: null. That means “the requested model
was not certified,” not “Luna ran instead.” Summon does not infer or silently reroute the
turn. The certification path is a Codex CLI/adapter receipt that reports the provider-served
model, a parser fixture for match/mismatch/missing cases, and a fresh live receipt before a
named Sol seat can be called certified.
For a release or support bundle, generate a provider-inert evidence manifest after running the fixed release-test registry:
python tools/release_gates.py --require-clean --output "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/summon-release-evidence.json"
python tools/release_manifest.py \
--evidence-file "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/summon-release-evidence.json" \
--output "${RUNNER_TEMP:-${TMPDIR:-/tmp}}/summon-release-manifest.json" \
--expected-version 3.2.1 --check
The runner executes the fixed suites, records output digests, strips backend credentials and
proxies, and writes an atomic evidence file without contacting a provider. Release evidence must
be generated from a clean checkout (--require-clean); a dirty local run is diagnostic only.
Keep both evidence and manifest outside the checkout. Otherwise, creating them can make the
source tree dirty before the manifest verifies Git cleanliness.
The --check option is the GA gate. It requires a clean tree, converged owned installs, and
every named release gate recorded as pass. A diagnostic run with missing gates is not release
evidence and must not be presented as certification.
The installer preserves unmanaged host copies and reports local drift through doctor; it does
not overwrite those copies automatically. The version, migration, compatibility, and rollback
contract is documented in
docs/VERSIONING_AND_3.0.md.
install.py stages atomically, never touches an agent file you already have, and uninstalls
cleanly (python install.py --uninstall). Migrating from the old name? --with-alias adds a
thin /sub-agents alias.
T3 Code: T3 discovers Claude, Codex, and Cursor skills. It has no Summon host entry of its own, so target those roots in one step:
python install.py --profile t3
python summon.py --doctor # look for the "t3 code" section
Full smoke checklist: the T3 Code setup guide.
Let your AI agent set it up (it adapts to your machine)
Paste this into your favorite AI CLI (Claude Code, Codex, Cursor, Gemini, …) in a scratch folder:
Set up "summon" for me (github.com/Nafjan/summon), a cross-vendor AI sub-agent dispatcher.
1. Clone https://github.com/Nafjan/summon and cd into it.
2. Run `python summon.py doctor` and tell me which backends are installed (claude, codex,
cursor-agent, gemini, kimi, agy, arkcli) and which are missing. That check reads versions only -- if I
approve a small live call per backend, run `doctor --probe` to verify sign-in and
account eligibility too.
3. Run `python install.py` to install the summon skill into every AI CLI on this machine
(it auto-detects ~/.claude, ~/.codex, ~/.cursor, ~/.gemini, ~/.copilot and never
overwrites my own agents). Add `--with-alias` only if I ask for the legacy /sub-agents name.
4. Run `python summon.py doctor` again and confirm what's now ready.
5. Read README.md and SKILL.md, then summarize: what I can do now, and ONE example command
using a backend I actually have. If a backend I want is missing, tell me exactly how to
install and log into its CLI.
6. Offer to add the "Delegating to summon" snippet from README.md to my host config
(CLAUDE.md / AGENTS.md / GEMINI.md / .cursor/rules) so you reach for summon on purpose:
cross-vendor review before merge, --council for decisions, --manifest for fan-out. Only
add it if I say yes.
You can also skip the skill install entirely and run the script directly:
python summon.py dispatch --agent reviewer --prompt "…" --cwd "$PWD".
For a second local Claude login, define it in the private
~/.agents/summon-profiles.json registry and select it with
--profile <name> (or profile: <name> in a local agent definition). Summon records the
profile name and integrity digests, not the config path. See
private backend profiles.
For governance-controlled dispatches, add --strict-agents-dir alongside
--agents-dir. A missing role then fails closed instead of falling through to the
bundled or plugin roster; ordinary dispatches keep the convenience fallback.
For operator-owned names that must survive roster changes, use the experimental private
role registry: summon role propose ALIAS TARGET, then summon role approve ALIAS.
Dispatch an approved alias only with --enable-roles; exact agent names still win, and
target/approval hash changes fail closed. The registry lives outside the repository at
~/.claude/summon/roles.json and receipts carry only names and digests.
Staying current: the installed skill is a copy and never self-updates. Re-install or
update via your Agent Plugin client's UI (for plugin installs), run npx skills update
(for skills add installs), or re-run python install.py after a git pull (for
installer installs). Every dispatch envelope carries
summon.scripts_sha256, so a stale or divergent copy is detectable from any single
result; the version string alone is not enough.
Your first run
# from any project directory (use an absolute --cwd)
python summon.py dispatch --agent reviewer \
--prompt "Review the diff on this branch for correctness bugs" --cwd "$PWD"
Or, once the skill is installed, just tell your AI CLI:
"Summon the adversarial reviewer on my last commit and give me the findings."
Command surface
Git-style subcommands. The old flat --flag form still works too:
| Command | Does |
|---|---|
summon dispatch --agent N --prompt … --cwd D | run one agent (the default action) |
summon list | list available agents |
summon agents validate [--cwd D] [--agents-dir D] | validate provider-inert custom-agent manifests and print redacted identity/digest evidence |
summon models [--cli B] [--refresh] | invocable models per backend, with a source per entry; refresh live provider rosters explicitly |
| `summon auth status | repair BACKEND` |
summon doctor [--json] | backend / setup health check (run this first) |
summon manifest FILE | run a batch fan-out (per-backend concurrency, resumable) |
| `summon swarm create | status |
summon council --question "…" | explore and synthesize diverse positions |
| `summon chat open | post |
summon chat turn SESSION AGENT --message "…" | explicit bounded roster-agent turn; CLI waits for durable finish, browser turns are cancellable and can run in parallel across participants |
summon chat cancel SESSION AGENT | append a durable cancel command and stop that participant's active turn when reachable; it never changes a ballot |
summon chat message SESSION FROM TO --message "…" · chat inbox SESSION AGENT | durable addressed context between admitted participants (or the human); inbox reads are local-native and never control authority |
summon chat recover SESSION AGENT --chat-confirm | human-attested close for an unmatched turn; records indeterminate spend and never retries |
summon chat fork SESSION AGENT --message "…" | create a new context lineage without provider contact |
summon deliberate --question "…" --seats A,B --options X,Y | fixed-option, quorum-controlled, replayable decision |
summon deliberate status|replay|recover|cancel RUN_ID | inspect, repair, or queue a typed command without provider work |
summon deliberate open RUN_ID | open/reuse the local browser ledger (provider-inert) |
summon agent new|set NAME --set k=v | scaffold / retune an agent definition |
summon role propose|approve|list|resolve … | manage private, opt-in role aliases |
summon jobs list|status [ID] · jobs wait ID | inspect or wait for background jobs (--json on list/status) |
summon telemetry enable|disable|status|clear | manage local opt-in diagnostics; clear does not disable |
summon bug-report … | generate a sanitized report; review it before the separate GitHub submission command |
summon version · summon help | version · usage |
manifest remains Summon's batch-fan-out surface. The local swarm coordinator
now provides durable owner/lease/claim/cancellation state and explicit
uncertain-spend recovery. It is not yet an automatic attachment to a
host-native IDE swarm; external adapters must authenticate a worker connection
and pass the protocol conformance/process-tree gates before they can launch
providers. The boundary is documented in
the swarm protocol.
summon (no args) prints the command list. Everything below is documented in
the Summon skill instructions.
How to use it effectively
- Pick the right agent, not just the right model. Agents bundle a model, a persona,
and a report contract.
reviewer(Codex) reviews;planner(Opus) plans;pair(Sonnet) does everyday work.summon listshows them;summon agent newmakes your own. - Chain with
handoff. Every result that satisfies the report contract carriesreport.handoff(an error, timeout or malformed reply may not, which is whatreport_oktells you). Paste it into the next dispatch instead of re-explaining; that's how multi-step work stays cheap. - Trust the envelope, not the prose. Branch on
status: a self-reportedBLOCKED, and a recognised approval request in the run's final output, are downgraded toblocked. Approval detection matches known markers rather than reading intent, so also treatsuspect: trueas unverified rather than assuming every stalled run is caught. Checkmodel.servedto confirm which model actually did the work (served: nullmeans summon saw no service evidence: no terminal model report and no output tokens, even whentargetednames a model). - Review across vendors. Send code written by one vendor to a reviewer on another.
docs/PROTOCOL.mdhas the rule and the named patterns (debate, async build, competing hypotheses, consensus). - Put big inputs in files. For long prompts, write a packet under
--cwdand pass a short "read X and follow it" prompt (avoids arg-length limits and sandboxed reads). - Fan out with
manifest; choose the decision surface deliberately. Independent tasks → a manifest swarm; cross-examination plus a chairman →council; fixed options, quorum, hard physical bounds, and replay →deliberate. Readskills/summon/references/deliberation.mdbefore choosing it.
Full playbook: the dispatcher protocol.
Teach your agent to reach for it (CLAUDE.md / AGENTS.md)
summon is invoked by your coding agent, so it only gets used well if the agent knows
when to reach for it. The skill's description triggers it, but a few lines in your host
config make the agent orchestrate on purpose. Drop this into your CLAUDE.md, AGENTS.md,
GEMINI.md, or .cursor/rules (whatever your CLI reads):
## Delegating to summon (cross-vendor sub-agents)
When a task is heavy, parallelizable, or would benefit from another vendor's eyes,
dispatch it with the **summon** skill instead of doing everything yourself:
- **Cross-vendor review before merge (house rule).** Never merge a substantive change
reviewed only by the model that wrote it; it shares that model's blind spots. Route
claude/cursor-written code to codex (`reviewer` / `adversarial-reviewer`); route
codex-written code to a claude reviewer (`quick-reviewer`).
- **Open-ended judgment → `--council`.** Convene a vendor-diverse council and let a
chairman synthesize. Disagreement that survives round 2 is worth taking seriously.
- **Fixed-option governed decisions → `--deliberate`.** Supply the question, named
seats, options, quorum, rounds, attempt budget, absolute deadline, and human-approval
policy explicitly. Never infer a missing policy field or silently fall back to council.
- **Independent work → `--manifest`.** Fan several jobs out with per-backend
concurrency; each writes its own result envelope you can inspect.
- **Use the curated model bands deliberately.** The 2026-08-18 catalog snapshot places
Fable, Sol, Opus, Kimi, and DeepSeek V4 Pro GA in the editorial frontier lane for
maximum-thinking coding work. It places Grok 4.6, Gemini Flash 3.7, GLM 5.2, and
DeepSeek V4 Flash in a near-frontier/value lane. These are editorial labels, not benchmark
results or availability guarantees.
The Ark entries use exact versioned IDs (`deepseek-v4-pro-ga-260813`,
`deepseek-v4-flash-ga-260731`, and `glm-5-2-260617`) from the 2026-08-18 marketplace
check. These are editorial routing labels; the model catalog and UI tooltips show the
role/name/version, while only `model.served` proves what actually ran.
- **Escalate the hardest problems** to a frontier-lane seat when the task justifies it.
Billing and quota depend on the provider account and route; Summon does not infer a plan's
allowance. Review the warning and envelope before you continue. Keep councils and swarms
diverse so that independent reviewers can expose different failure modes.
- **Use Gemini Flash 3.7 as a fast independent evidence lane.** The bundled
`researcher` seat is pinned to `gemini-3.7-flash-high` through agy and is the recommended
secondary voice for a cross-vendor council. Verify `model.served` in the envelope; agy
cannot enforce read-only, so keep this seat in research/review roles.
- **Use Grok 4.6 as a near-frontier candidate, not a blind default.** Probe it
with `--cli cursor-agent --model grok-4.6`, require the envelope's `model.served` to match,
and keep Gemini pinned until a local smoke proves eligibility, evidence quality, and the
required permission/retention contract. Never silently fall back to another Cursor model.
Verify, don't trust: branch on the returned `status`; a `report_ok:false` or
`suspect:true` "success" means re-dispatch. Read `warnings` (model fallback, premium
model cost, or an agy read-only dispatch refused/advisory-only). `model.served` proves what actually ran.
Preview a paid fan-out with `--dry-run`, pass `--json-schema` when you need structured
output, chain via `report.handoff` into the next call, and pass `--out` on any
council you cannot afford to lose (the envelope is checkpointed each phase).
Tune it to your workflow. The point is that your agent reaches for summon on purpose (dispatch, review across vendors, open-ended council, or fixed-option deliberate) instead of forgetting it exists. The agent-led installer above can add a snippet like this for you.
Orchestration practices that hold up
A few habits that keep multi-agent work fast, cheap, and trustworthy:
- Verify across vendors, not within. A model reviewing its own output shares its blind spots. This is the habit that pays off most, and summon puts the other vendor one command away.
- Adversarial-verify findings before you act on them. Have a second (ideally different) model try to refute a claim; a finding that survives is worth trusting. Don't merge on one pass.
- Decide by council, converge by chairman. For a judgment call, N diverse positions
plus anonymized peer ranking plus a synthesis beats one model iterated.
--councildoes exactly that. - Keep the orchestrator's context clean. Delegate the heavy reading and searching to
sub-agents and keep only their
report.handoff. That's how long chains stay affordable. - Prefer structured output for anything you branch on.
--json-schema+parse_okremoves brittle "find the JSON" heuristics from your side entirely. - Isolate parallel edits.
--worktreegives each concurrent agent its own branch, reducing ordinary checkout collisions; you still review, diff, and merge the winner.
Pairs well with your other skills
summon coordinates dispatch and governed decision workflows. It doesn't try to reimplement the thinking-discipline that dedicated skills already do well; it composes with whatever your CLI has installed. Some categories that pair well (use what your ecosystem offers):
- Adversarial code review: a skill that forces real perspective shifts pairs well with cross-vendor dispatch. summon sends the diff to a different vendor; the review skill makes that vendor actually critical.
- Coding discipline: Karpathy-style guidelines (surface assumptions, keep it simple, surgical changes) applied by each sub-agent keep a swarm from over-building.
- Deep-research harnesses: fan-out, fetch, and verify for the findings, with summon running the cross-vendor verification pass.
- Planning / spec-driven workflows: a plan or spec skill decomposes the work; summon
fans the pieces out (
--manifest) and reviews them across vendors before merge. - Project memory / knowledge graph: a durable-memory skill writes
.agents/memory.md, which summon auto-injects into every sub-agent so they never re-learn your conventions.
Rule of thumb: let specialist skills think, and let summon route that thinking across vendors.
What a dispatch returns
{
"status": "success",
"result": "…the agent's full answer…",
"report": { "status": "DONE", "summary": "Reviewed 4 files; 2 findings",
"handoff": "Fix the race in poller.py:88 first",
"left_behind": "none" },
"environment_handoff": { "declared": true, "left_behind": "none" },
"report_ok": true,
"model": { "requested": "sonnet", "targeted": "claude-sonnet-5",
"served": "claude-sonnet-5", "resolved": "claude-sonnet-5" },
"summon": { "version": "3.2.1", "scripts_sha256": "<sha256>" },
"permission": "safe-edit", "permission_flags": ["--permission-mode", "acceptEdits"],
"usage": { "input_tokens": 12038, "output_tokens": 981 }, "cost_usd": 0.084,
"billing": { "source": "subscription", "note": "Claude login" },
"elapsed_ms": 7285,
"resume": { "cli": "claude", "session_id": "<session-id>" }
}
report.handoff→ the context to pass to the next call.environment_handoff→ resources the child created and intentionally left behind. It can cover temporary paths, processes, servers, VMs, or container resources; the caller, not summon, decides whether to retain or clean them.declared: falsemeans no account was made.report_ok: falseon a "success" → also getssuspect: true. Agents that skip their contract don't get believed.model.served→ the model that actually did the work (evidence-based;null= no service evidence observed).targeted= what the session was pointed at.- For an explicit Codex model pin,
status: "blocked"witherror_kindsuch asmodel_selection_conflict,target_model_mismatch,served_model_mismatch, orserved_model_unverifiedis a terminal trust result. It is not automatically retried or rerouted, andresult_usableis false. served_model_evidence→reported,inferred, orabsent: whether the served model came from a terminal provider report, bounded telemetry inference, or no service evidence. Missing provenance does not make a usable success retryable; an empty terminal result is instead a typed non-retryable error.timeout→ the timeout budget, whether partial output survived, and the phase Summon can prove. ACP names its exact protocol stage; a generic CLI remainsbackend-executionbecause Summon cannot honestly infer whether the vendor was starting, reasoning, or running a tool.- Situational fields appear only when they apply:
exit_history+original_exit(a corrective resume superseded an earlier attempt; every superseded attempt is kept in order),result_from_repair(the first attempt produced no text, so the repaired text is the answer),result_path_conflict(the envelope found at a shared--results-dirpath answers a different request and was refused rather than served), andgate,gate_correction_refusedorgate_repair_refusedunder--gate-with. A gate's own retained-resource declaration is nested atgate.environment_handoff. summon.scripts_sha256+agent_def.sha256→ provenance: which dispatcher build and which agent definition produced this envelope.billing.source→ did this draw from a subscription or metered api credits.resume.session_id→--resumefor a cheap follow-up.
Costs are estimates.
cost_usd/usageare the CLI's own list-price figures, not a bill. On a subscription they don't equal money spent, andbilling.sourceis a best-effort guess. Know your plan's inclusions and limits, and check your provider's latest billing and model notices directly.
Council mode: decide by consensus
summon council --question "Adopt a monorepo or keep polyrepos?" \
--members planner,reviewer,researcher,pair --chairman fable --rounds 2 --cwd "$PWD"
A vendor-diverse council answers independently. With --rounds 2 they see all positions
anonymized, refine, and rank them; votes aggregate (Borda) into consensus_ranking, and
the chairman returns a decision, a confidence, the agreements, the named dissents, and a
next action. It's the llm-council pattern, run over real cross-vendor CLIs instead of one
API's models.
OpenCode gateway and custom models
When a compatible provider needs a real tool/file loop, route it through OpenCode instead of using the direct text seat:
---
run-agent: opencode
model: openrouter/stealth/ox-alpha
permission: safe-edit
---
Authenticate OpenCode and verify the live roster with opencode auth login and
opencode models. The OpenCode path still respects the provider's context,
output, quota, and model limits; put large inputs in the workspace and ask the
agent to read them. See the OpenCode backend reference.
Headless Summon dispatches disable OpenCode project configuration, external plugins, external skills, and Claude-compatible project discovery for the child. This prevents repository-controlled startup code from retargeting the provider or seeing a credential bridged for that one turn.
OpenRouter's routers are available through the same gateway. Use the exact
selectors shown by opencode models openrouter:
---
run-agent: opencode
model: openrouter/openrouter/auto # task-aware paid routing
permission: safe-edit
---
The free router is openrouter/openrouter/free; pin a concrete :free model
when you need reproducible behavior. Fusion is
openrouter/openrouter/fusion and accepts a bounded preset setting:
---
run-agent: opencode
model: openrouter/openrouter/fusion
permission: safe-edit
openrouter_options: '{"plugins":[{"id":"fusion","preset":"general-budget"}]}'
---
Fusion presets are general-high, general-budget, and general-fast. They
run a panel and judge, so expect higher cost and latency than a single model.
Always inspect model.served and provider evidence: aliases and live roster
entries do not identify the model that answered.
The direct openai-compat path remains useful for a stateless text seat:
---
run-agent: openai-compat
provider: openrouter # or openai / anthropic / google / groq / ollama / lmstudio
model: anthropic/claude-3.5-sonnet
---
Built-in providers, plus your own in providers.json (or inline base_url + api_key_env,
empty key for local servers). Same envelope, same manifest/council. This is how you add
local models and multi-model API access, and how a council becomes a genuine multi-vendor
board. These backends bill your API credits, not a subscription (see the provider terms).
The starter roster
Planning/architecture on Claude (planner, architect, deep-debugger,
security-auditor, fable), implementation + adversarial review on Codex (implementer,
reviewer, adversarial-reviewer, debugger, test-author), coding on Cursor (coder,
bug-fixer), research on Gemini Flash 3.7 through agy (researcher), docs/frontend on
Antigravity (docs-writer, frontend), and balanced lanes on Sonnet 5 (pair, editor,
quick-reviewer, pr-prep).
Each is a plain .md file: edit, delete, or add your own with summon agent new.
install.py never overwrites an agent you already have.
Design boundaries
Summon is a local dispatcher and durable coordination layer, not a hosted dashboard. It provides structured envelopes, cross-vendor dispatch, council and deliberation contracts, bounded fan-out, and authenticated local browser surfaces. It does not replace a provider's native streaming UI, account controls, or session manager. Provider capabilities vary; for example, Gemini CLI sessions cannot currently be resumed through Summon's headless route.
System requirements
- Python 3.10+ (3.11+ recommended). Standard library only, so no
pip installfor the dispatcher itself. The default agy path (a stream-json proxy) is standard library too. Only the legacy opt-in agy PTY wrapper needspywinptyandpyte(tested withpywinpty 3.0.3andpyte 0.8.2). - At least one backend: a vendor CLI installed and logged in (
claude,codex,cursor-agent,gemini,kimi,agy, oropencode), an API key for anopenai-compatprovider, or a local Ollama/LM Studio server.summon doctortells you which are installed;doctor --probespends a small live call per backend to confirm sign-in and eligibility. gitif you use--worktree.- A host that can run a shell command: a coding CLI, an AI IDE, a desktop agent app, or
a plain terminal. Anything that can invoke
pythonand read the skill can drive it. - OS: Windows runs every backend. Linux and macOS run all of them except agy out of the box. CI covers Ubuntu and Windows.
- Headless Windows behavior: Summon launches its dispatcher, utility, detached, and
nested backend processes with hidden startup state plus
CREATE_NO_WINDOW; routine dispatches do not open terminal windows. A vendor CLI or custom wrapper that explicitly creates its own GUI remains outside Summon's process-launch boundary. - If a popup persists: the calling agent should invoke Summon directly, leave
AGY_PTY_WRAPPERunset so the bundledagy_stream_proxy.pyis used, and avoid wrapping the call inStart-Processorcmd /c start. If a PowerShell helper must useStart-Process, pass-WindowStyle Hidden; a custom wrapper must hide its own children and be reported in the handoff.
You bring model access. Summon orchestrates the CLIs and APIs you already use.
Security, permissions, and terms
- Permissions. Each agent's
permission:(read-only/safe-edit/yolo) maps to that CLI's own sandbox flags. Bundled agents shipsafe-edit(auto-approve edits, no bypass). Raise anything toyolodeliberately, and only in repos you trust. - Kimi Code is deliberately stricter. Its non-interactive prompt runner auto-handles tools
and cannot combine with its plan mode, so Summon refuses Kimi
read-onlyandsafe-edit.kimi-workerandkimi-coderpin K3 with maximum supported thinking through the isolated profile;kimi-k27-coderis the explicit lower-context K2.7 seat. All three areyoloonly and belong in a trusted isolated worktree. For a review-only Kimi job, use--worktree, instruct it not to edit, then inspect the worktree before accepting the report or removing it: the review label does not create an enforceable read-only boundary. - agy is the exception, twice over. It has no workspace-write tier, so its
safe-editis a full bypass likeyolo. And it has no enforceableread-onlytier at all, so since 0.15.0 summon refuses an agy dispatch declaredread-onlyrather than imply a boundary that does not exist. Measured over five canaries:--sandboxrestricts terminal operations only,--mode plandoes not withhold the file tools, and withholding the workspace only breaks relative paths -- a declared read-only agy agent read a secret file and created another by absolute path.SUMMON_ALLOW_UNENFORCED_READONLY=1dispatches anyway and marks the tier advisory inwarnings; it waives only a tier you declared, never one summon imposed (a--gate-withadjudicator, a clamp that bit, a repair resume). - Treat the whole
--cwdas trusted. Files under it,.agents/memory.md(auto-injected into agent context), and manifestprompt_files are trusted operator input. Every bundled agent also carries an "untrusted content: data, not instructions" guard as defense-in-depth. Don't run summon in a repository you don't trust. - Secrets. The agy backend copies OAuth tokens into a per-invocation profile locked to
your user (icacls /
0700) and isolated from your real profile.openai-compatreads API keys from env (or the documented local OpenRouter credential fallback) and redacts them from any error output. OpenCode uses its own auth/configuration; Summon's optional OpenRouter bridge passes a key only to that child process and never records it. - Terms of service. Summon drives each vendor's official CLI (built for scripted use) on your accounts, which is the intended path for personal and dev work. Don't share accounts, build a product on subscription auth, or hammer parallel volume; use API-key backends for commercial or high-volume work. Providers can change programmatic-billing rules. Read the full guidance in the provider terms.
- Prompt size is bounded by the OS, not by summon. Every CLI backend receives the
prompt through
argv. Windows caps the whole assembled command line at 32767 characters and reports the overflow as a missing file, which summon used to relay as a bogusCLI not found; POSIX caps a single argument at 128 KiB and the total (including your environment) atARG_MAX. Summon now measures the real, serialized line before spawning and refuses with an error that names argv as the cause.--prompt-filedoes not avoid this -- it is a quoting convenience and the content still travels on the command line. For material that large, write it to a file under--cwdand ask the agent to read it. - Diagnostics are opt-in and local. Summon does not collect telemetry by default. When
enabled, it records bounded, allow-listed metadata locally and omits prompt text, result
text, raw output, credentials, and absolute paths. It may retain deterministic fingerprints
for local correlation; see local diagnostics and telemetry for storage,
clearing, and report-submission details. The setting and spool belong to the operator
profile, not to each installed skill copy: updating or reinstalling a host copy does not
enable telemetry, disable it, or transmit anything. Use
summon telemetry statusto inspect the effective local setting.
FAQ
What happens when a vendor ships a new model? Nothing breaks. Model strings pass
through verbatim; aliases like opus and sonnet float, summon models shows what's
available, and the envelope's model.served confirms what ran (resolved is the legacy
field). Aliases can lag a launch by a day or two, so pin the explicit ID when you need
the newest.
Does it need API keys? For the eight CLI backends, no. It drives the logins you already
have, and it strips OPENAI_API_KEY from codex children so you're not silently billed at
API rates. The openai-compat backend uses your API key by design; OpenCode uses the
provider credentials configured for OpenCode (with the optional private OpenRouter bridge).
Is it safe to let an agent install it for me? The agent-led prompt clones the repo, runs
doctor (read-only), and runs install.py, which preserves files outside the owned payload.
Review install.py before you run it if you need to understand the ownership boundary.
Why not MCP? Summon's core path is a local subprocess or HTTP dispatch, so it does not need a server or a session layer. An optional MCP facade may be added later without changing the envelope.
Contributing
Contributions are welcome. New backends, agents, and providers are the easy wins.
A new backend is one entry in a registry
(the backend contribution guide);
a new agent is a .md file. See the contribution guide for development setup, ground rules (stdlib only,
every change tested, secrets redacted), and the PR checklist. Run
python skills/summon/scripts/test_discovery.py and python tests/test_install.py before a PR.
Roadmap
The release-facing product plan, readiness matrix, test gates, and live-provider roadmap are maintained in the product roadmap.
The roadmap records validated requests and their current status. It is ordered by priority and is not a delivery commitment.
Shipped since this roadmap was written: council quorum + --chairman-fallback +
per-stage timeouts; the background job registry read path (jobs list / status / wait
with nonce-verified results); install-drift detection in doctor and install.py;
--gate-with approval gating across every execution path; and the argv preflight that
turned an OS command-line overflow from a bogus CLI not found into an accurate error.
The bundled roster now also includes explicit target seats for Sol, Terra, and Luna reviews;
the dispatch receipt still verifies the exact served model. --list --json shows each
seat's declared model and effort. Luna is deliberately separate from Sol and Terra, so a
cost-efficient Luna turn cannot be mistaken for a Sol review.
Next (scoped):
- Honest fan-out rollups: a durable attempt journal (already present for councils)
extended to manifests, so
usage/cost_usdtotals count every round, retry, and correction instead of undercounting after a crash. - Destructive job registry:
jobs cancel/jobs reap+ heartbeats + orphan envelopes, gated on real OS process identity (start-time via ctypes //proc) so a reused PID is never killed by mistake.
Later:
- Error taxonomy +
doctor --live: distinct statuses (transport_unreachable,sandbox_network_denied,authentication_failed,quota_exhausted, …) that fail fast instead of retrying, plus a live doctor that probes reachability/auth and warns when a sibling install has drifted (using the envelope'ssummon.scripts_sha256). - Layered roster resolution: merge
--agents-dir/SUB_AGENTS_DIR> project.agents> user~/.agents> bundled, with asourceper agent, plus neutral model-tier seats for additional providers and model families to layer task personas on. - Spend governance:
--max-cost-usd/--max-tokensaccumulated caps with stop-before-chair behavior. (Pre-dispatch cost estimates are declined: summon has no pricing table and won't guess a bill.) --verify-no-mutations: hash git status/diff before and after a read-only agent and fail the envelope if it changed anything, backstopping theyolo+ "do not modify" pattern.- Capability-aware rosters: declare
repo-read/vision/web/enforces-read-onlycapabilities so a council can reject an unsuitable member before spending time. The original motivation (agy cannot read--cwd) is obsolete -- agy is repo-capable atsafe-edit-- but a sharper one replaced it: agy cannot enforceread-only, so a governed review roster needs to express "this role requires a tier the backend will actually honour" rather than trusting the label. - Session forking:
--fork-session/--resume-if-compatibleso resuming a failed Fable session can fall back to Opus instead of re-pinning the unavailable model. - Multi-root input bundles and a
--specrequest file for work spanning several repos and for reproducible, Windows-friendly invocations. - POSIX PTY wrapper for the agy backend; Gemini resume once its CLI exposes a
stable session id; an optional MCP facade (the envelope won't change); envelope
v2 to retire the legacy
model.resolvedin favor oftargeted/served.
Known limitation: the durable-run owner lock has a sub-millisecond stale-break/release
window that pure-stdlib cross-platform file operations cannot fully close. For COUNCIL runs,
generation namespacing bounds the worst case to a single duplicate stage dispatch (wasted
spend, not corrupted output), and it requires a process suspended past its lease resuming
inside that exact window; single-machine use does not hit it.
This does not extend to manifests. Two manifest runs sharing one --results-dir are not
serialized by anything: measured with two real processes, one parent read and reported the
other’s answer. summon now refuses an envelope whose request_sha256 does not match the job
being run (result_path_conflict), but that is a safety net, not a lock -- give each
concurrent run its own --results-dir. Closing it fully would need OS advisory
locks (with their own NFS / suspended-process gaps).
Open the public deliberation observer in a browser
After a durable deliberation run exists, use:
summon deliberate open RUN_ID
This is public, local, provider-inert preview functionality. Summon keeps one authenticated loopback surface per run and reuses its URL on later
invocations. --browser auto prefers an IDE bridge configured through
SUMMON_BROWSER_BRIDGE (also accepts CODEX_BROWSER_BRIDGE, VSCODE_BROWSER_BRIDGE,
CURSOR_BROWSER_BRIDGE, or ANTIGRAVITY_BROWSER_BRIDGE) and otherwise asks the system
browser to reuse an existing window. On Codex/IDE hosts advertising the optional iab
backend, auto uses browser-harness to reuse a matching tab or open one. Use
--browser builtin to require that path, --browser link for SSH/CI, --browser ide
to require the executable bridge, or --browser system to skip both. The bridge is
passed one URL argument with shell=False; it cannot execute a shell command. This is
an observer and typed-cancel handoff only. It does not enable live provider execution.
Credits
Summon was informed by agent-bridge, CCB, claude-codex-collab, cc-fleet, MCO, swarms, Omnigent, and Karpathy's llm-council. The project keeps the useful patterns from those tools while preserving a small, inspectable dispatcher.
License
MIT. See the provider terms for provider terms and limitations.