Team of Faggots
For six months I've been running agents one at a time and copy-pasting between windows like a monkey — today I finally made them talk to each other directly, and two of them found each other over MCP without me in the middle.
For six months I've been launching agents one by one and copy-pasting results from one window to another, and at some point the absurdity of the situation finally hits me, because I've got a desktop app that manages CLI processes, each process has a stdin and a stdout, and I'm sitting in the middle like a monkey shoveling text between them by hand.
Morning Plan
The idea is simple, painfully so: let the agents talk to each other directly, without me in the loop. One writes code, the second reviews, the third coordinates. I plug in when a decision needs to be made, not when a prompt needs to be copied from window A to window B.
I start by digging into the old exp branch, where the arena used to live, two agents arguing with each other in one chat. There was a memory-mcp there, a separate SQLite binary that auto-connected to every CLI session. Sounds nice, but the branch has rotted, we ripped everything out of there a long time ago, and rebuilding that crate for one feature makes no sense.
The Mailbox
The first thing I do, well, strictly speaking the first thing the coder does in the branches branch, because I decided to work in the "coder writes, reviewer checks, I conduct" format right from the start — is the mailbox. Plain JSONL files on disk, append-only, each agent has its own inbox. Alongside it — a task system, also files, with locks and owners. The reviewer immediately finds that any agent can finish someone else's task. Fixed. The reviewer finds that when injecting messages into an agent's stdin there's a race with user input — both can write to the pipe at the same time. Fixed, we made a single AgentWriter lock that atomically checks state and writes.
I'm sitting in a separate chat, formulating prompts to the coder and the reviewer, getting reports back, throwing fixes over. Essentially the exact thing I want to automate, only I'm doing it by hand. Irony.
HTTP Server Inside the Box
Next is the tastiest part. The agents need to somehow talk to each other not through files that somebody has to poll every three seconds, but through a proper protocol. MCP, Model Context Protocol — that's exactly what it's for. Options: a separate binary like in exp, parsing stdout, or an HTTP server right inside the app.
I pick the third. Axum on 127.0.0.1, random port, MCP Streamable HTTP transport. Seven tools: send_message, broadcast, read_inbox, list_tasks, create_task, claim_task, complete_task. When an agent starts, the command's --mcp-config gets a URL with its agent_id baked in, and that's it, it sees the tools and can use them. Identification by URL, you can't fake the from field — the reviewer specifically checked this and found a hole we patched on the spot.
Then we hang management tools on top for the architect role: start_agent, stop_agent, restart_agent, send_prompt. The architect can launch other agents and send them tasks directly over MCP. Coder and reviewer only see communication tools, the management ones are hidden and blocked at the execute_tool level.
Moment of Truth
I build from the branches branch, open it up, create a team. Name it "PEDIKI", because that's my sense of humor. Add a coder, a reviewer, an architect. Hit Play.
The architect boots up, goes into mcp_teamwork_read_inbox on its own, checks the mail, writes "Waiting for incoming messages. Ready to work". I didn't even ask. It saw the tools and decided to check the mailbox by itself.
I fire off a broadcast from the team panel: "Hey, testing a feature, reply if you got my message". Switch over to the chats. Coder replied. Reviewer replied. Architect replied. All three are asking permission for MCP tools — right, forgot to add mcp__teamwork__* to allowedTools. Agents are hung, the app looks frozen, the coder in the branch is stuck on the same thing. Restart, add the wildcard, rebuild.
Second attempt. I write to the architect: "send a message to the coder via MCP: hello from the architect". Architect calls mcp__teamwork__list_agents, finds the coder, calls mcp__teamwork__send_message. I switch over to the coder's chat. "Waiting for a task from the architect." The coder replied to the architect on its own over MCP. I switch back to the architect: "Coder replied — online, waiting for tasks."
Full chain. Without me in the loop. Two agents found each other and had a conversation.
Inconvenient Truth
And then I look at the screen and realize that to watch this conversation I had to switch between three chats, open the team panel, close it, open it again. A bunch of tabs in the sidebar, no clue which project the agents are even running in, and where the hell is that master chat where I'm supposed to see the whole thread as a single conversation.
And I also notice that the MCP server is built into the app itself. It's not tied to teams. Any agent you slip the config to can write to any other. The whole construction with team_create, team_add_agent, roles — that's scaffolding over something that basically already works. One HTTP endpoint solves the communication problem, and we've built a whole city around it.
But the city is necessary, because without it there'll be chaos. Ten agents in different projects sending each other messages, each burning context on MCP tools they don't need, no structure at all. Teams are the fence. The fence just needs to be put up in a nicer way.
What's Next
What I need is a proper group chat, like in a messenger. One window, all messages from all agents, signed with who sent what to whom. No jumping between tabs. Leave individual chats for anyone who wants to see the full log with tool calls and reasoning, but coordination lives in one place.
In one day, from scratch, we assembled: mailbox, tasks, teams, roles, stdin injection, race protection, UI panel, HTTP MCP server with 12 tools, chat bindings. The reviewer found about eight bugs and fixed them before they became problems. The whole architecture works, the agents actually talk, and it cost me zero lines of code written personally — I only formulated prompts and made decisions. Which, incidentally, is the whole point of this exercise.