Parallel "swarm" research for Claude, ChatGPT and Gemini clients, with zero dependencies.
One question goes in. A planner splits it into sub-questions, N cheap workers run in parallel
(web search, or a scan of local files), and one synthesizer merges everything into an answer with
[n] references and a Sources list. Workers default to Claude Haiku through your Claude Code
subscription; GPT (Codex CLI / OpenAI API) and Gemini (Antigravity CLI / Gemini CLI / Gemini API)
are one flag away, and provider: "mixed" spreads the workers across model families so the
synthesis shows where they disagree.
Ships as:
- a Claude Code plugin (
/swarm-search, skill, MCP server), - an MCP server over stdio for Claude Desktop, Codex CLI / ChatGPT desktop Codex, Antigravity, Gemini CLI,
- an MCP server over Streamable HTTP for ChatGPT connectors and any remote client,
- a CLI (
swarm-search run "...").
question ──► planner (1 call) ──► N sub-questions (N chosen by the planner, 1–8)
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
worker 1 (web) worker 2 (web) ... worker N (web) ← Haiku / GPT / Gemini
└────────────────────┼────────────────────┘
▼
optional round 2: gap-filling follow-ups or cross-critique
▼
synthesizer (1 call) ──► answer + [n] sources
Who decides how many workers? By default the planner: it reads the question and returns one
sub-question per genuinely independent angle, so a narrow fact costs one worker and a five-way
comparison gets five. Pass workers: N to force a number.
Do workers talk to each other? Not in round 1: independence is what makes the synthesis catch
errors. With rounds: 2 they do, after the fact:
round2: "gaps"(default) — an auditor reads all round-1 reports, lists contradictions and unanswered parts, and a few targeted follow-up workers resolve just those. Cheap: 1 + up to 4 calls.round2: "critique"— every worker sees the anonymized reports of the others and replies with Confirmed / Disputed / Retracted / Missing, with sources. N extra calls. Strongest withprovider: "mixed", where Claude, GPT and Gemini check each other.
In files mode (paths given) the corpus is sharded instead: every worker reads a slice of files
with line numbers and reports path:line findings; the synthesizer merges them. Round 2 in files
mode re-reads the shards that had findings with the follow-up questions.
- Node.js ≥ 20
- at least one worker backend:
| provider id | what it uses | needs | default model |
|---|---|---|---|
claude-cli |
claude -p (Claude Code CLI) |
Claude subscription, claude in PATH |
haiku |
codex-cli |
codex exec (OpenAI Codex CLI) |
ChatGPT subscription, codex in PATH |
your Codex default |
agy-cli |
agy -p (Google Antigravity CLI) |
Antigravity login, agy in PATH |
gemini-3.8-flash-low |
gemini-cli |
gemini -p (Gemini CLI) |
Google login / GEMINI_API_KEY |
gemini-2.5-flash |
anthropic |
Messages API | ANTHROPIC_API_KEY |
claude-haiku-4-5 |
openai |
Responses API | OPENAI_API_KEY |
gpt-5-mini |
google |
Gemini API | GEMINI_API_KEY / GOOGLE_API_KEY |
gemini-2.5-flash |
openrouter |
chat/completions | OPENROUTER_API_KEY |
anthropic/claude-haiku-4.5 |
swarm-search providers shows which ones are usable on your machine. auto picks the first
available in the order above; every default model can be overridden with SWARM_<PROVIDER>_MODEL.
claude plugin marketplace add jumpleGo/swarm-search
claude plugin install swarm-search@jumplegoThen in any session:
/swarm-search what changed in Node.js 24 LTS vs 22, should we migrate now?
/swarm-search where are request timeouts handled --files src,server --workers 6
or just ask for a swarm search — the bundled skill tells Claude when to reach for the
swarm_search tool.
git clone https://github.com/jumpleGo/swarm-search ~/swarm-search
cd ~/swarm-search
node bin/swarm-search.mjs install claude-desktop --write # or: codex | agy | gemini-cli | claude-codeWithout --write the command only prints the config snippet. It registers the server as:
{ "mcpServers": { "swarm-search": { "command": "node", "args": ["/abs/path/bin/swarm-search.mjs", "mcp"] } } }Codex gets a [mcp_servers.swarm-search] block in ~/.codex/config.toml (also read by the
ChatGPT desktop app's Codex mode). Antigravity is registered with agy mcp add.
ChatGPT only connects to remote HTTPS MCP servers, so run the HTTP transport and expose it:
SWARM_HTTP_TOKEN=$(openssl rand -hex 16) node bin/swarm-search.mjs mcp --http --port 8787
# in another shell
ngrok http 8787 # or: cloudflared tunnel --url http://localhost:8787In ChatGPT enable Developer mode in settings and create a connector with URL
https://<your-tunnel>/mcp and Bearer auth using that token. The server is stateless
(JSON responses on POST /mcp, GET /health). The Gemini consumer app has no custom MCP
support; use Antigravity or Gemini CLI for Gemini.
| argument | meaning |
|---|---|
query |
the question (required) |
mode |
auto (default) · web · files |
paths |
files/dirs to scan → files mode |
workers |
fixed worker count (max 12); omit for auto sizing by the planner |
rounds |
1 (default) or 2 |
round2 |
gaps (default) or critique |
provider |
auto · mixed · provider id · id:model · comma list for round-robin |
model |
worker model override |
synth_provider, synth_model |
use a stronger model for the final synthesis only |
angles |
your own sub-questions, skips the planner |
language |
force answer language |
swarm_providers lists usable backends.
swarm-search run "state of WebGPU in 2026: browser support, frameworks, gotchas" --workers 6
swarm-search run "where do we validate JWT?" --paths src,server --provider codex-cli
swarm-search run "is Bun ready for production?" --provider mixed --rounds 2 --round2 critique --synth-provider claude-cli:sonnet
swarm-search run "..." --json # full report with per-worker output| variable | default | purpose |
|---|---|---|
SWARM_PROVIDER |
auto |
default provider spec |
SWARM_WORKERS |
unset = auto | fixed default worker count |
SWARM_MAX_AUTO_WORKERS |
8 |
upper bound for auto sizing |
SWARM_ROUNDS / SWARM_ROUND2 |
1 / gaps |
default rounds and round-2 mode |
SWARM_TIMEOUT_MS |
180000 |
per-call timeout |
SWARM_SHARD_CHARS |
60000 |
max characters per files-mode shard |
SWARM_HTTP_TOKEN |
– | bearer token for mcp --http (required when binding a non-loopback host) |
SWARM_HTTP_ALLOWED_ORIGINS |
– | comma-separated browser origins allowed besides localhost (mcp --http) |
SWARM_CLAUDE_MODEL, SWARM_CODEX_MODEL, SWARM_AGY_MODEL, SWARM_GEMINI_MODEL, SWARM_ANTHROPIC_MODEL, SWARM_OPENAI_MODEL, SWARM_GOOGLE_MODEL, SWARM_OPENROUTER_MODEL |
see table | per-provider default model |
A 4-worker web run is 6 model calls (1 plan + 4 workers + 1 synthesis) and takes 1–3 minutes with
CLI backends. Round 2 adds 1 audit + up to 4 follow-ups (gaps) or N critiques (critique). CLI providers run on your subscriptions; API providers bill per token. Workers are
read-only: claude -p gets only WebSearch/WebFetch, codex exec runs with -s read-only,
agy/gemini run in plan mode.
npm test # unit tests (no network)
node bin/swarm-search.mjs providers
node bin/swarm-search.mjs run "..." --workers 2Layout: src/swarm.mjs pipeline · src/providers/* one file per backend · src/corpus.mjs
file sharding · src/mcp.mjs stdio + HTTP transports · src/install.mjs client configs ·
.claude-plugin/, commands/, skills/, .mcp.json Claude Code plugin surface.
Adding a provider: export { id, family, kind, label, defaultModel, detect(), complete({ system, prompt, model, web, timeoutMs, signal }) → { text, usage? } }
and add it to PROVIDERS in src/providers/index.mjs.
MIT