👥 mcp-agent-crew · project #4

One agent that
hires help

Project #3's agent is a very good cook working alone. Give it a job with 60 pieces and it does fine. Give it four times that and it runs out of room mid-way through, having achieved nothing.

A head chef doesn't cook faster. They split the work and keep only the plan in their own head.

We measured it first

Sub-agents are impressive to watch, and impressive to watch is not the same as better. So the eval suite ran the same job twice — once with the spawn_agent tool withheld, once with it offered — and compared both the answer and the bill.

at 60 jars

It genuinely doesn't matter

Both modes inspected all 60, found all 9 tampered jars, and flagged nothing innocent — 100% across three attempts each. The cost gap is inside run-to-run variance.

one agent
100% · ~99k tokens
a crew
100% · ~83k tokens

A wash — and worth knowing before you spend a week building an orchestrator.

at 240 jars

The single agent falls off a cliff

It hit the ten-iteration cap having inspected 180 of 240, emptied nothing, and spent 440k tokens getting there. The crew inspected all 240 and found all 36.

one agent
0 of 36 found · 439k tokens
a crew
36 of 36 found · 248k tokens

Correct and cheaper. The failing agent is expensive precisely because it fails slowly.

And the mechanism matters more than the numbers. A lone agent re-sends its entire conversation on every iteration — and by jar 200 that conversation contains two hundred inspection reports. Its cost grows with the square of the job while its capacity stays fixed. Three workers each carry eighty reports, finish, and hand back a paragraph. Splitting the work is how you stop paying to re-read what you already read.

An earlier version of this page claimed the crew cost 1.7× at 60 jars. That was a measurement bug — the two modes were running different numbers of runs and the totals were being divided anyway. Every individual number was right; the division was the lie. It is written up honestly in the repo, because it is a better lesson than the result.

The whole mechanism is one tool

“Multi-agent orchestration” sounds like a framework — a message bus, a scheduler, a supervisor tree. Here is all of it:

The model gets one extra tool called spawn_agent. The implementation of that tool is runAgentLoop — the same function that is calling it.

A sub-agent is a tool that happens to think.

The loop already took messages in and yielded events out. That is what a sub-agent is. There was never anything to build — only something to notice.

🧠

The orchestrator

Reads the job, splits it by data — “jars 1–20”, not “help with the pantry” — and holds only the plan.

👷

The workers

A fresh context each, the same toolbox, one instruction. They hand back a paragraph — not a transcript. The compression is the point.

One human

Every gated call in the tree bubbles to a single queue, carrying the worker's own reasoning. Five agents asking separately is unusable.

Watch it split the work

A real orchestrator against real MCP servers — this repo's pantry of 60 jars, this repo's cookie jar, and project #1's live server. Every sub-agent gets its own lane and its own token meter.

The first example splits the pantry, gets short reports back, and then asks you once, with a list, before emptying anything. Untick Let it hire help to run the same prompt as project #3's lone agent and compare.

Pick one, or ask your own.

Start with the first one. It splits the pantry across sub-agents, gets short reports back, and then asks you once, with a list, before emptying anything.

Five seatbelts, and why five

Every limit project #3 had was scoped to one loop. Recursion multiplies per-loop limits instead of adding them: an orchestrator allowed ten iterations that hires three workers allowed ten each has quietly authorised forty API calls. Each of these catches something the others let through.

🔁10 iterationsproject #2

Per agent. Kept at ten on purpose — it is a real constraint at this size, and part of what a crew buys you is that each worker gets its own ten.

👥3 at oncenew

A rate limit. The model can ask for more; they queue. A parallel loop with a bug is not a hang, it is a bill times N.

🎫8 per runnew

A quantity limit. Without it, an orchestrator that decides it wants one agent per jar hires sixty of them, three at a time, politely.

💸600k tokensnew

A money limit, shared by the whole tree. Every seatbelt before this one was per-loop — and per-loop limits multiply down a tree instead of adding.

🚫no recursionnew

Sub-agents are started without spawn_agent in their tool list, so the tree is two levels deep structurally. Not a depth counter that could be off by one — an absence.

The last one is the one worth stealing: prefer a design where the bad thing is unreachable over a check that catches it. A sub-agent cannot recurse because it was never given the tool, not because a counter says no.

Rewind any of it, including the workers

Every run above was written to Postgres as it happened, one row per event — and so was every sub-agent, because a sub-agent is not a special kind of thing. It is a run with a parent. So “expand this worker and see what it actually did” is the same select as replaying anything else.

loading past runs…

This project ships servers too

The pantry is a real MCP server: 60 jars, each needing its own inspection, one jar per call. That last detail is the whole difficulty of this project expressed as a function signature. Plug it into Claude Code like any other server:

claude mcp add --transport http pantry https://learn-mcp-agent-crew.vercel.app/api/pantry

It offers list_jars, inspect_jar, pantry_log and empty_jar — that last one genuinely destroys data, which is exactly why the gate exists. Both this server and the cookie jar ship unlocked, deliberately: projects #2 and #3 both locked theirs in production and both times it broke the next project in the series.