claude mcp add agent-pool -- npx -y github:Sceat/agent-poolSPAWNED AGENTS RUN WITH ALL PERMISSIONS BYPASSED
Agents are spawned with --dangerously-skip-permissions, meaning they can:
- Execute any shell command without approval
- Read/write any file on your system
- Access network resources freely
- Inherit your full environment (env vars, credentials, SSH keys)
This is intentionalβorchestration requires agents to work autonomously. However:
- β Only use trusted agent definitions from sources you control
- β
Review agent prompts in
agents/*.mdbefore running - β Never run untrusted agents or agent definitions from unknown sources
You are responsible for what your agents do.
Claude Code's native Task tool has critical memory leak issues that cause processes to grow from hundreds of MB to tens of GB, eventually crashing:
| Issue | Description |
|---|---|
| #7020 | Sub-agent orchestration: 450MB β 30GB, then crashes |
| #4953 | Process grows to 120GB+ RAM, OOM killed |
| #11315 | 129GB virtual memory consumption |
| #11155 | Bash output stored in memory forever, 90GB+ usage |
| #8382 | v2.0.0: 26GB per process |
The root cause: Every Task tool call spawns a fresh subprocess. The memory accumulates and is never released.
agent-pool's solution: Keep Claude CLI subprocesses alive and use /clear to reset context while preserving the warm prompt cache. No new processes = no memory leak.
Native Task Tool (leaky): agent-pool (stable):
ββββββββββββββββββββββββββ ββββββββββββββββββββββ
Task 1 β spawn β 450MB Warmup β spawn β 450MB
Task 2 β spawn β 900MB β Task 1 β /clear β 450MB (cached)
Task 3 β spawn β 1.3GB β Task 2 β /clear β 450MB (cached)
Task 4 β spawn β 1.7GB β Task 3 β /clear β 450MB (cached)
... ...
Task N β OOM KILLED π Task N β still 450MB β
Bonus: Same process = same system prompt = prompt cache hits = ~90% token savings.
claude mcp add agent-pool -- npx -y github:Sceat/agent-pool// Warm up agent (optional, creates prompt cache)
mcp__agent-pool__warmup({ agent: "code-reviewer" })
// Send tasks - all reuse the same process
mcp__agent-pool__invoke({ agent: "code-reviewer", task: "Review src/auth.js" })
mcp__agent-pool__invoke({ agent: "code-reviewer", task: "Review src/api.ts" })
mcp__agent-pool__invoke({ agent: "code-reviewer", task: "Review src/db.js" })
// Check active agents
mcp__agent-pool__list()| Tool | Description |
|---|---|
invoke(agent, task) |
Send task to agent, get result, auto-reset context with /clear |
warmup(agent) |
Pre-spawn agent to warm up prompt cache (optional) |
list() |
Show active agents with PIDs |
reset(agent) |
Kill agent process (respawns on next invoke) |
| Tasks | Native Task | agent-pool | Savings |
|---|---|---|---|
| 1 | 2,000 | 2,000 | 0% |
| 3 | 6,000 | 2,600 | 57% |
| 5 | 10,000 | 3,200 | 68% |
| 10 | 20,000 | 4,700 | 76% |
System prompt (~1,500 tokens) is cached after first call. Subsequent calls only pay for task content.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Claude Code β
ββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββ
β MCP Protocol
ββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββ
β agent-pool MCP Server (Node.js) β
β invoke() β warmup() β list() β reset() β
βββββββ¬ββββββββββββ¬ββββββββββββ¬ββββββββββββ¬ββββββββββββββββββββ
β β β β
ββββ΄βββ ββββ΄βββ ββββ΄βββ ββββ΄βββ
βAgentβ βAgentβ βAgentβ βAgentβ β Persistent processes
β PID β β PID β β PID β β PID β (not respawned)
βββββββ βββββββ βββββββ βββββββ
β β β β
/clear /clear /clear /clear β Context reset
(cache) (cache) (cache) (cache) (cache preserved)
Create agents/my-agent.md with YAML frontmatter:
---
name: my-agent
description: What this agent does
skills:
- skill-name
expertise:
- expertise-name
---| Header | Description |
|---|---|
name |
Agent identifier (used in invoke({ agent: "name" })) |
description |
What the agent does (shown in list() output) |
skills |
List of skill modules to inject (loaded from SKILLS_DIR) |
expertise |
List of expertise modules to inject (loaded from EXPERTISE_DIR) |
Skills & Expertise Injection: Content from referenced skill/expertise files gets injected into the agent's system prompt at spawn time. This allows modular composition of agent capabilities.
Then invoke: mcp__agent-pool__invoke({ agent: "my-agent", task: "..." })
When using an orchestrator pattern, the main Claude instance doesn't need direct tool accessβit should only delegate to specialized agents.
Why this matters:
- Reduces context pollution - Main instance focuses on orchestration, not tool outputs
- Enforces the pattern - Prevents accidental direct tool use
- Cleaner separation - Orchestrator thinks, subagents act
Tool access pattern:
| Instance | Tools |
|---|---|
| Main orchestrator | mcp__agent-pool__invoke, Task, AskUserQuestion, TodoWrite |
| Subagents | Full MCP access (Bash, Read, Write, Grep, etc.) |
How to configure:
-
CLAUDE.md approach - Forbid direct tool use in your orchestrator's instructions:
# Orchestrator Rules - NEVER use Bash, Read, Write, Edit, or Grep directly - ALWAYS delegate work to specialized agents via mcp__agent-pool__invoke - Only use AskUserQuestion for user clarification
-
Selective MCP registration - Only register agent-pool for the main instance, not file/shell MCPs
-
Hooks - Use Claude Code hooks to block certain tools for the main instance
This pattern keeps your orchestrator clean and forces proper delegation.
| Issue | Solution |
|---|---|
| Agent not found | Check agents/name.md exists and name: in frontmatter matches |
| Task timeout | Run reset({ agent: "name" }) to kill stuck process |
| Plugin not loading | Verify plugin.json exists, restart Claude Code completely |
| High memory usage | Check you're using agent-pool, not native Task tool |
Full guide: docs/TROUBLESHOOTING.md
- Installation Guide - Prerequisites and setup
- Usage & API - Full API reference and examples
- Architecture - How it works internally
- Troubleshooting - Common issues and fixes
- Contributing - How to contribute
- Claude CLI 2.0+ with
--input-format stream-jsonsupport - Node.js 18+
Made for Claude Code developers tired of OOM kills
