Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here

Summary

Slash commands that delegate to pi-subagents: /pi:agent, /pi:status, /pi:result, /pi:cancel, /pi:setup.

Install to Claude Code

/plugin install pi@pi-cc-plugin

Run in Claude Code. Add the marketplace first with /plugin marketplace add RazvanRotaru/pi-cc-plugin if you haven't already.

README.md

pi-cc-plugin

> Run subagents on any model from inside Claude Code.

pi-cc-plugin is a Claude Code plugin that delegates work to pi-subagents (nicobailon's fork of pi-coding-agent). Pi already speaks Claude, OpenAI, Google, OpenRouter, DeepSeek, Groq, xAI, Mistral, Cerebras, Hugging Face, Bedrock, and friends — this plugin gives Claude Code a clean slash-command surface to dispatch into that model zoo, while keeping the orchestrator session itself snappy and non-blocking.

┌─ Claude Code (orchestrator, Claude) ──────────────────────────────┐
│                                                                    │
│  /pi:agent worker "fix the auth bug" --model openrouter/...        │
│       │                                                            │
│       ▼                                                            │
│   pi-broker  ──►  pi --mode rpc  ──►  pi-subagents  ──►  child pi  │
│       │                                    │                │      │
│       ▼                                    ▼                ▼      │
│   .pi-cc-plugin/state.json    /tmp/.../async-subagent-runs/<id>/   │
│   (job ledger)                  status.json + events.jsonl + log   │
│                                                                    │
│       ▲                                    │                       │
│       └────  /pi:status reads both ◄───────┘                       │
│              (events stream forwarded raw to the orchestrator)     │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘
  • Foreground by default. /pi:agent waits for the subagent to finish

and prints its output, just like any normal tool call. Add --bg for long jobs you want to fire and forget — and pick up later via

/pi:status and /pi:result.

  • Live progress with --verbose. Stream step transitions to the

terminal as they happen. Off by default to keep the orchestrator's context tight.

  • Heterogeneous models. Use --model openrouter/google/gemini-3-pro-preview,

--model anthropic/claude-opus-4-7, anything pi knows about.

  • Worktree isolation. --worktree runs the subagent in its own

git worktree for safe edits when several dispatches share a repo.

  • MCP tools per agent or per dispatch. Static via the agent file,

dynamic via --mcp foo/bar.

  • Auto-reconcile. state.json syncs against pi's view on every

read — finished jobs always show as completed.

  • Raw event stream in /pi:status. Pi-subagents' events.jsonl

is forwarded verbatim — step transitions, child tool calls, errors — so the orchestrator sees what's actually happening, not just running.

---

Quick start

1. Install pi (Node ≥ 20)

# Need Node 20+ in the shell. nvm is the easiest path:
nvm install --lts && nvm use --lts

# Pi itself:
npm i -g @mariozechner/pi-coding-agent

# pi-subagents (the extension that gives pi the `subagent` tool):
pi install npm:pi-subagents

2. Configure a provider

OpenRouter is the lowest-friction path (one key → all models):

export OPENROUTER_API_KEY=sk-or-...
echo 'export OPENROUTER_API_KEY=sk-or-...' >> ~/.bashrc

Or, for OAuth providers (Claude Pro/Max, ChatGPT Plus, Gemini CLI):

pi    # then /login → pick a provider

See Provider matrix below for direct API-key env vars.

3. Install this plugin

/plugin marketplace add /path/to/pi-cc-plugin
/plugin install pi@pi-cc-plugin
/reload-plugins

4. Wire up your project

/pi:setup --yes

That checks pi/pi-subagents are installed, validates auth, copies six default specialist seeds into .pi/agents/, and gitignores

.pi-cc-plugin/.

5. First run

/pi:agent scout "how many .mjs files are in this repo?"

The broker waits for scout to finish and prints its output. For long jobs you'd rather background, add --bg:

/pi:agent worker "rewrite the auth module" --bg

Output (within ~1s):

Started job-001 (pi-run-id 0f214ec0-…) — agent=worker
Use /pi:status job-001 to inspect.

Then /pi:status job-001 shows live progress; /pi:result job-001 prints the final output once worker is done.

---

Slash command reference

| Command | What it does | |---|---| | /pi:setup [--yes] | Verify pi + pi-subagents + provider auth, scaffold .pi/agents/, gitignore .pi-cc-plugin/. Idempotent. | | /pi:agent <agent> <task…> [flags] | Dispatch one task to one pi agent. Need to fan out? Call /pi:agent multiple times in one assistant turn — Claude Code runs tool calls in parallel. | | /pi:status [id] | Without id: list every tracked job. With id: inspect one. Auto-reconciles state.json against pi and forwards the raw event stream (subagent.run.started, subagent.step.started, child tool calls, subagent.run.completed, …) so the orchestrator sees more than just running. | | /pi:result <id> | Print the final markdown output. | | /pi:cancel <id> | SIGTERM pi-subagents' parent + every detached worker carrying the runId; SIGKILL after 5s. |

Flags

| Flag | Where | Effect | |---|---|---| | --wait (default) | run | Wait for the subagent to finish; print its output when done. Redundant — same as omitting both flags. | | --bg | run | Detach. Returns the run id immediately; pick up via /pi:status and /pi:result. Use this for long runs or when you want to keep the orchestrator session free. In Claude Code you can also Ctrl+B Ctrl+B a running /pi:agent to background it manually. | | --verbose | run | While waiting in foreground, stream step-transition lines (· agent: running· agent: complete) to stdout. Off by default to keep the parent agent's context small. | | --model <id> | run | Override the agent's default model (e.g. openrouter/google/gemini-3-pro-preview). Always use provider/model form to avoid registry resolution surprises. | | --fork | run | Run the subagent in a forked context (pi-subagents context: "fork"). | | --worktree | run | Run the subagent in an isolated git worktree. Requires a clean working tree. Dispatches via the tool-call path (adds ~3-5s of latency). | | --mcp <list> | run | Attach MCP tools to this dispatch (comma-separated server/tool). See MCP tools. | | --cwd <path> | run | Run pi in a different working directory. | | --yes | setup | Auto-apply scaffold/gitignore fixes. |

Identifiers

Every job has two IDs:

  • internal_id — short, stable: job-001, job-002. For humans.
  • pi run id — the long uuid pi gives back. Canonical.

/pi:status, /pi:result, /pi:cancel accept either, plus any unambiguous prefix of the pi run id.

What /pi:status shows you

Two files on disk back every status query, and both get reflected in the output:

                    ┌──────────────── /pi:status job-001 ────────────────┐
                    │                                                     │
       state.json   │   .pi-cc-plugin/state.json   ← broker ledger        │
       per-job ─────┤        (id, agent, task, started, completed)        │
                    │                                                     │
                    │   /tmp/pi-subagents-uid-<uid>/async-subagent-runs/  │
       pi-subagents │     <runId>/                                        │
       per-run ─────┤        ├─ status.json     ← per-step state          │
                    │        └─ events.jsonl    ← raw event stream        │
                    │                                                     │
                    └─────────────────────────────────────────────────────┘

Sample output (single-job inspect):

**job-001** · single · running
  pi-run-id: `8f3a2c1b-9e7d-4a6b-8c1d-2e3f4a5b6c7d`
  agents: worker
  task: summarize the auth module
  started: 2026-04-29T19:00:12.503Z
  steps:
    - worker: running
  events:
    {"type":"subagent.run.started","ts":1777834812,"runId":"8f3a..."}
    {"type":"subagent.step.started","ts":1777834813,"runId":"8f3a...","stepIndex":0,"agent":"worker"}
    {"type":"tool_call","name":"read","args":{"path":"src/auth.ts"},"subagentSource":"child","subagentAgent":"worker"}
    {"type":"tool_call","name":"grep","args":{"pattern":"export"},"subagentSource":"child","subagentAgent":"worker"}

The events block is raw pass-through — no summarization, no filtering. The orchestrator (Claude) parses it and decides what to surface to you. Common event types pi-subagents emits:

| Type | Source | Carries | |---|---|---| | subagent.run.started / .completed | pi-subagents | runId, success | | subagent.step.started | pi-subagents | stepIndex, agent | | subagent.parallel.started / .completed | pi-subagents | step group + agent list | | subagent.control | pi-subagents | steering / cancel notices | | tool_call, message_*, usage, … | child pi (re-emitted) | tagged subagentSource: "child" | | subagent.child.stdout / .stderr | child pi (raw lines) | unstructured fallback |

---

Agent configuration

Agents live in .pi/agents/<name>.md (project) or

~/.pi/agent/agents/<name>.md (user). Project wins. Pi-subagents also ships a built-in set (scout, worker, planner, reviewer,

context-builder, researcher, delegate, oracle,

oracle-executor) that any user/project agent can override by name.

Frontmatter shape

---
name: scout                                    # required, must match filename
description: Fast codebase recon              # required
model: openrouter/moonshotai/kimi-k2.6        # any pi-known model
fallbackModels: anthropic/claude-haiku-4-5    # optional ordered fallbacks
thinking: medium                               # off | minimal | low | medium | high | xhigh
tools: read, bash, grep, find                  # builtin tool allowlist + mcp:* entries
skills: clean-code                             # comma-separated, injected into prompt
maxSubagentDepth: 1                            # how many layers of nested delegation
inheritProjectContext: true                    # keep AGENTS.md/CLAUDE.md in the prompt
inheritSkills: false                           # surface pi's full skills catalog?
systemPromptMode: replace                      # replace | append (vs pi's base prompt)
output: context.md                             # default file the agent writes
defaultReads: brief.md                         # files the agent reads on start
---

You are a scout. Your job is …

Attaching MCP tools (the most common ask)

Pi-subagents reads mcp:server/tool entries from the same tools: line and forwards them to the child pi via MCP_DIRECT_TOOLS. So the canonical place to wire MCP tools is the agent's tools: line:

---
name: implementer
description: Write production code that makes the test suite green
model: openrouter/anthropic/claude-sonnet-4-7
tools: read, write, edit, bash, grep, find,
  mcp:filesystem/read_file, mcp:filesystem/write_file,
  mcp:test-runner/run_suite, mcp:linter/check
skills: clean-code
---

Any /pi:agent implementer … then has those MCP tools available without extra flags.

If you want a per-dispatch MCP override (one-off experimentation, or attaching tools to a builtin like scout without committing changes to your seed), use the --mcp flag. The broker writes a temporary agent file with the extra tools, dispatches under that name, and cleans up after asyncId capture:

/pi:agent scout "find auth bugs" --mcp memory/store,memory/read --bg

Source resolution order for --mcp: project seed (.pi/agents/) → user seed (~/.pi/agent/agents/) → pi-subagents builtin. Settings overrides (.pi/settings.json#subagents.agentOverrides) are merged into the temp file, so model/thinking/skills overrides keep applying.

Scaffolding

/pi:setup --yes copies six seeds into .pi/agents/:

| Seed | Role | |---|---| | architect | Shape contracts, surface integration points, write a brief | | test-writer | Author the failing test suite that pins desired behavior | | test-reviewer | Adversarial review of the test suite | | implementer | Make the suite green | | code-reviewer | Adversarial review of the implementer's diff | | ci-triage | Bisect a CI failure; classify flake/regression/infra |

Edit them freely — the plugin never overwrites once they exist.

---

Recipes

Cheap recon → expensive deep dive

Two /pi:agent calls. The orchestrator (Claude) reads scout's result, decides whether to keep going, then dispatches the deeper agent with that context embedded in the brief:

/pi:agent scout "map the affected modules"
# (foreground: scout's output is printed; orchestrator reads it)
/pi:agent oracle "Given scout's summary above, critique the plan and surface risks"

This replaces the old /pi:chain form. Sequential agents almost always benefit from the orchestrator validating the previous step's output before deciding what to do next.

Fan out with isolation

Multiple /pi:agent --bg calls from the same assistant turn — Claude Code runs tool calls in parallel, and --bg lets all three start without any one of them blocking the others:

/pi:agent scout "audit frontend" --worktree --bg
/pi:agent scout "audit backend"  --worktree --bg
/pi:agent scout "audit infra"    --worktree --bg

Each scout gets its own worktree under /tmp/pi-worktree-<runId>-<n>, torn down at run end. Requires a clean git working tree. Pick the results up later via /pi:result job-001, /pi:result job-002, etc.

Lightweight test harness

/pi:agent test-writer "pin the contract for src/auth.ts"
# orchestrator reads the test-writer brief from stdout, then:
/pi:agent implementer "make the suite at tests/auth.test.mjs green"
# review the diff, then:
/pi:agent code-reviewer "adversarial review of the implementer diff"

Foreground by default keeps the orchestrator in the loop between steps.

Attach MCP tools just for this dispatch

/pi:agent worker "implement the planned migration using the test-runner MCP" --mcp test-runner/run_suite,test-runner/diff

---

How it works

Dispatch (/pi:agent)

┌─ Claude Code session ────────────────────────────────────────────┐
│                                                                   │
│  /pi:agent worker "task"                                          │
│       │                                                           │
│       ▼                                                           │
│  plugins/pi/scripts/pi-broker.mjs run worker "task" [--bg|--wait] │
│       │                                                           │
│       ▼                                                           │
│  args.mjs (parse) → pi-cli.mjs (spawn pi --mode rpc) ──┐          │
│                                                         │          │
│  ┌──────────────────────────────────────────────────────┴───┐      │
│  │ pi (Node ≥20) loads pi-subagents extension              │      │
│  │   handles /run slash command                            │      │
│  │   OR direct subagent tool_call (--worktree path)        │      │
│  │   spawns child pi → writes status.json + events.jsonl   │      │
│  │   emits subagent-slash-result {asyncId, asyncDir}       │      │
│  └──────────────────────────────────────────────────────┬───┘      │
│                                                         │          │
│       ◀─ broker captures asyncId, closes stdin ──────── ┘          │
│       │                                                           │
│       ▼                                                           │
│  state.json patch (job-NNN ↔ runId ↔ asyncDir)                    │
│       │                                                           │
│       ├──── --wait ────► poll status.json until terminal,         │
│       │                  print final output, return               │
│       └──── --bg   ────► return immediately with job id           │
│                                                                   │
└───────────────────────────────────────────────────────────────────┘

Status / result (/pi:status, /pi:result)

┌─ Claude Code session ─────────────────────────────────────────┐
│                                                                │
│  /pi:status [job-id]                                           │
│       │                                                        │
│       ▼                                                        │
│  pi-broker.mjs status [id]                                     │
│       │                                                        │
│       │   reconcile.mjs                                        │
│       │      ├── read .pi-cc-plugin/state.json                 │
│       │      └── read /tmp/.../async-subagent-runs/<id>/       │
│       │           ├── status.json    → state, steps, errors    │
│       │           └── events.jsonl   → raw event stream        │
│       ▼                                                        │
│  render.mjs → markdown block per job                           │
│       │      header · pi-run-id · steps · errors · events:     │
│       ▼                                                        │
│  Claude reads, decides what to surface                         │
│                                                                │
└────────────────────────────────────────────────────────────────┘

State on disk

| Path | Purpose | Owner | |---|---|---| | ./.pi-cc-plugin/state.json | Broker's job ledger: internal_id, pi-run-id, agents, task, status, pi_status_dir | pi-cc-plugin | | /tmp/pi-subagents-uid-<uid>/async-subagent-runs/<runId>/status.json | Per-run state: state, per-step status / model / error, timing | pi-subagents | | /tmp/pi-subagents-uid-<uid>/async-subagent-runs/<runId>/events.jsonl | One JSON event per line: subagent.* lifecycle events + child pi tool calls (re-emitted with subagentSource: "child") | pi-subagents | | /tmp/pi-subagents-uid-<uid>/async-subagent-runs/<runId>/output-N.log | Per-step stdout (concatenated for /pi:result) | pi-subagents | | /tmp/pi-subagents-uid-<uid>/async-subagent-runs/<runId>/subagent-log-<runId>.md | Human-readable transcript | pi-subagents | | ~/.pi/agent/auth.json | Provider credentials (0600) | pi | | ~/.pi/agent/extensions/, <npm-global>/pi-subagents/ | Extension code | pi |

The plugin never writes pi's state; it only reads. The broker's

state.json auto-reconciles with pi's status.json on every

/pi:status and /pi:result. events.jsonl is read in full each call (readPiEvents accepts an optional byte cursor for incremental tails — currently unused since /pi:status is happy to dump the full stream and let the orchestrator interpret).

Provider matrix

Pi recognizes these env vars in addition to OAuth and auth.json:

| Provider | Env var | |---|---| | Anthropic | ANTHROPIC_API_KEY | | OpenAI | OPENAI_API_KEY | | OpenRouter | OPENROUTER_API_KEY | | Google Gemini | GEMINI_API_KEY | | DeepSeek | DEEPSEEK_API_KEY | | Groq | GROQ_API_KEY | | xAI | XAI_API_KEY | | Mistral | MISTRAL_API_KEY | | Cerebras | CEREBRAS_API_KEY | | AWS Bedrock | (uses standard AWS creds) | | Vercel AI Gateway | AI_GATEWAY_API_KEY | | Hugging Face | HF_TOKEN |

Full list lives in pi's docs/providers.md.

Listing model prices

This plugin ships a companion /pi-prices slash command (and a

pi-prices shell binary at ~/.local/bin/) that dumps pi's bundled pricing table — no network calls:

pi-prices                    # all models
pi-prices openrouter         # filter by substring
pi-prices --json             # machine-readable

---

Troubleshooting

| Symptom | Cause | Fix | |---|---|---| | pi-broker: pi requires Node >= 20 | System node is 18 (Claude Code's subprocess env) and no nvm Node 20+ found | nvm install --lts && nvm use --lts, restart Claude Code | | pi-broker: pi exited (code N) before emitting subagent-slash-result | pi crashed at startup; usually missing extension or auth | Run /pi:setup --yes; check pi list \| grep pi-subagents; verify auth | | pi-broker: timed out after Nms waiting for subagent-slash-result | Pi is loading slowly (first run) or stuck on auth/rate-limit | Bump PI_BROKER_DISPATCH_TIMEOUT_MS=120000, or attach a debugger to pi | | step (error) in /pi:status despite state: complete | Pi-subagents marks the run complete even when a step's API call fails (e.g. invalid model id, missing auth) | Read step-errors: block; the broker auto-suggests a hint | | Unknown agent: <name> | Project seed missing a name: line, or wrong path | Project seeds must be at .pi/agents/<name>.md with name: <name> in frontmatter | | worktree isolation requires a clean git working tree | Local tree dirty | git stash or commit, retry | | --mcp couldn't find a source for agent "<name>" | No project, user, or builtin source for that agent | Scaffold one (/pi:setup) or pick a different agent |

---

Configuration knobs (env vars)

| Var | Default | Purpose | |---|---|---| | PI_BROKER_PI_BIN | (auto-resolved) | Override pi launcher (script or binary) | | PI_BROKER_PI_ARGS | (none) | Comma-separated args prepended after PI_BROKER_PI_BIN | | PI_BROKER_DISPATCH_TIMEOUT_MS | 60000 | How long to wait for pi to ack the slash command | | PI_BROKER_POLL_INTERVAL_MS | 1500 | Foreground poll interval against pi-subagents' status.json | | PI_BROKER_SIGTERM_GRACE_MS | 5000 | Cancel grace before SIGKILL | | PI_BROKER_NO_NODE_VERSION_CHECK | 0 | Skip the Node-≥20 fail-fast (for fixtures) | | PI_BROKER_DEBUG | 0 | Print stack traces on broker errors |

These are subprocess vars — set them where you launch Claude Code.

---

Development

npm install
npm test                            # 129+ offline tests against the fake-pi fixture
npm run lint                        # biome
PI_SMOKE=1 npm run test:smoke       # only when a real pi is installed

Tests use a fake-pi fixture (tests/fixtures/fake-pi.mjs) that mimics pi's RPC protocol — JSONL prompts on stdin, subagent-slash-result custom messages, status.json shape, the works. No real pi needed for the offline suite. Real-pi smoke tests live in docs/DOGFOOD.md and are runnable manually.

Code layout:

plugins/pi/
  scripts/
    pi-broker.mjs                  # entry point invoked by every slash command
    lib/
      args.mjs                     # parse the slash grammar
      pi-spawn.mjs                 # locate pi (npm-global, nvm, /usr/local) + pick Node ≥20
      pi-cli.mjs                   # JSON-RPC client; slash and tool_call dispatch paths
      pi-status-reader.mjs         # read pi's status.json / output-N.log
      reconcile.mjs                # sync state.json from pi on every read
      ephemeral-agents.mjs         # write per-dispatch agent files for --mcp
      process-tree.mjs             # find + kill detached subagent workers
      tracked-jobs.mjs             # state.json CRUD
      state.mjs                    # atomic JSON I/O with mkdir-based locking
      gitignore.mjs                # ensure .pi-cc-plugin/ is ignored
      render.mjs                   # markdown for /pi:status and /pi:result
      setup-checks.mjs             # /pi:setup checks
      actions/{run,status,result,cancel,setup}.mjs
  agents-seed/                     # six default specialists
  commands/                        # one .md per slash command
  skills/{pi-cc-usage,pi-cc-harness}/SKILL.md
docs/
  PI_INVOCATION.md                 # verified contract with real pi
  DOGFOOD.md                       # manual QA script

Run /pi:setup --yes against a freshly-cloned repo to confirm everything works end-to-end before dogfooding model dispatches.

---

Status

Stable — broker dispatch (/pi:agent) with foreground polling and optional --verbose step streaming, --bg for detached runs, status, result, cancel, worktree (via tool_call path), --mcp, auto-reconcile,

raw events.jsonl forwarding through /pi:status so the orchestrator gets per-step transitions and child tool calls (not just

running).

Removed/pi:chain and /pi:parallel. Use multiple /pi:agent calls from the orchestrator instead: parallel falls out naturally (Claude Code runs tool calls concurrently), and sequencing benefits from the orchestrator validating each step before deciding the next.

Out of scope (v1)/pi:steer (pi-subagents has no steering API), pi-intercom bridge, integrated MCP server (state lives elsewhere).

---

Related

the underlying multi-provider CLI.

that provides the subagent tool + the /run slash command inside pi. (pi-subagents also exposes /chain and /parallel; this plugin no longer surfaces them — see Status above.)

License: MIT.

Related plugins

Browse all →