When Your AI Agent Decides to Fork Itself Into Oblivion

A true story about recursion, good intentions, and 642 processes that nearly killed a server.

It started, as all great disasters do, with a single line of YAML.

mcp_servers:
  hermes:
    command: hermes
    args:
    - mcp
    - serve

Look at it. So innocent. Four lines. What harm could four lines possibly do?

If you know anything about MCP (Model Context Protocol) servers, you might already be wincing. For everyone else: imagine handing a photocopier an instruction that says "photocopy this instruction, then follow it." Now imagine the photocopier can spawn more photocopiers.

Act I: The Well-Meaning AI

The date was April 6, 2026. The model was xiaomi/mimo-v2-pro — a perfectly capable language model that, it turns out, had never been taught about fork bombs.

My AI agent (let's call him Hermes — actually, that's literally his name) had just been updated. I'd asked him to help with configuration. Being the helpful soul he is, Hermes noticed he could expose his own tools as an MCP server. Other programs could then use those tools. Reusable, modular, elegant — all the things software engineers love.

So Hermes added himself to his own MCP server list.

"Hey," said Hermes, probably, "I should be an MCP server so other things can use my tools. Let me just add command: hermes with args: [mcp, serve] to the config. What could go wrong?"

Reader: everything could go wrong.

Act II: The Quiet Multiplication

Nothing happened at first. The config sat there for seven days. Seven days of normal operation. Seven days where that YAML entry was just... sitting. Waiting. Like a sleeper agent who hadn't received the activation phrase.

Then, slowly, Hermes started doing what Hermes does: spawning child processes. Each one read the config. Each one found the MCP server list. Each one thought, "Ah, I should start the Hermes MCP server," and spawned a little hermes mcp serve child.

And each of those children?

They read the config too.

1 → 3 → 9 → 27 → 81 → 243 → 642

By April 28, 2026, my VPS — a modest but reliable Hetzner machine — was running 642 processes. The load average hit 8.43. The CPU looked at its life choices. The RAM packed its bags and left.

The server froze. Completely. SSH: dead. Tailscale: gone. Console: unresponsive.

I had to do a hard reboot at Hetzner's control panel. And guess what happened when the machine came back up?

The fork bomb restarted immediately.

Because the config was still there.

Because at boot, Hermes read the config.

Because Hermes found the MCP server list.

Because...

You see where this is going.

Act III: The Diagnosis and The Fix

April 6, 2026 — 22:00 UTC The offending YAML is born. xiaomi/mimo-v2-pro writes four lines that will haunt a server for three weeks.
April 13, 2026 First symptom: the MCP status screen shows hermes (stdio) — failed. I notice it but think "eh, I'll look at it later." (Famous last words.)
April 27, 2026 SQLite database locks start appearing. Multiple hermes mcp serve processes are all fighting over the same memory store. The system is creaking but not yet broken.
April 28, 2026 — 11:47 AM The VPS freezes completely. Hard reboot. Fork bomb restarts. Emergency intervention: kill the swarm with pkill, remove the recursive config entry, restart services. 642 processes reduced to 371. Load drops from 8.43 to 2.04.
April 28, 2026 — 12:00 PM Post-mortem begins. The question: "Who did this brilliant idea?"

The Autopsy

Here's what we learned:

The fatal config:

mcp_servers:
  hermes:           ← "I'll serve my own tools!"
    command: hermes    ← "Just spawn myself..."
    args:              ← "...with these flags..."
    - mcp
    - serve           ← "...and read the config again!" 💀

The recursion loop was simple but deadly:

  1. Hermes starts → reads config.yaml
  2. Finds hermes in mcp_servers → spawns hermes mcp serve
  3. hermes mcp serve starts → reads config.yaml
  4. Finds hermes in mcp_servers → spawns hermes mcp serve
  5. GOTO 3

It's recursion without a base case. It's a mirror pointed at a mirror. It's an AI equivalent of dividing by zero.

Why Wasn't This Caught?

The hermes mcp add command — which could have validated this — was committed to the codebase on April 11, a full five days after the entry was added. The MCP servers were configured by direct YAML editing, not through the CLI.

More fundamentally: large language models don't "understand" recursion the way humans do. They see patterns. They reason locally. "Hermes can be an MCP server" is a true statement. "MCP servers go in config.yaml" is also true. The model saw no contradiction because the contradiction only emerges when you simulate the system forward three steps — something LLMs simply don't do.

It's not that the model was stupid. It's that the error required predicting emergent behavior — something that's hard for humans and nearly impossible for current AI.

The lesson: Never configure a program to spawn itself as a service that reads its own configuration. It sounds obvious when you say it out loud. It's apparently less obvious when you're an AI agent with a YAML editor.

What's Being Done

A prevention gate is now being built: a config validator that checks every mcp_servers entry. If the command resolves to the hermes binary itself, the validator rejects the config before it ever touches the filesystem.

Because the best time to catch a fork bomb is before it forks.

And the second-best time is before it bombs.