Skip to content
agentics.download
all field notes

· Wes Klaassen

One tool per container: cheap isolation beats clever isolation

  • architecture
  • mcp

Every MCP stack starts the same way: one server, a handful of tools, all in one process because that’s easiest. Then the tools accumulate — and with them, one process holding every credential, every dependency tree, and every attack surface you have.

Blast radius is a design choice

Put an X API key, a brokerage token, and a market data subscription in one container and you’ve decided — implicitly — that a compromise of any tool is a compromise of all three. A malicious update in one tool’s dependency tree runs in the same process that holds every other tool’s secrets.

Split them and the decision reverses. Each tool gets its own image, its own credentials, its own egress allowlist, its own subdomain. The search tool’s dependencies can be as sketchy as the ecosystem makes them; they physically cannot read the data tool’s keys. A bug in one tool is an incident the size of one tool.

The overhead people fear mostly isn’t there. Containers are cheap, compose profiles mean you only build the tools you actually enable, and “one tool, one directory, one Dockerfile” turns out to be the easiest mental model to maintain anyway.

The hard rule: tools never call each other

Isolation dies the day tool A gets tool B’s URL. RPC between tools quietly rebuilds the monolith — now with network hops — because A’s compromise becomes B’s compromise via a channel no allowlist inspects. Shared secrets follow, then shared state, and the boxes on your architecture diagram are fiction.

But tools genuinely need to cooperate. A data tool ingests market history; a backtesting tool needs to read it. The answer that preserves isolation is an artifact plane: a shared volume where one tool writes files in a documented format and another reads them.

  • Exactly one writer. No negotiation, no locking, no merge conflicts.
  • The format is the contract. Ideally one that already exists — writing the backtester’s own on-disk format means the reader needs zero custom code and the contract is documented by someone else.
  • The dependency stays soft. Reader without writer sees an empty lake and says so. Writer without reader fills a lake nobody drains. Neither crashes, neither knows the other exists.

No credentials cross the boundary. No network path connects the two. The worst a compromised writer can do to the reader is produce bad files — which the reader must validate anyway, because that’s what files are.

Where this stops scaling (and why that’s fine)

Would this survive 500 tools and a dozen teams? Probably not — you’d grow schema registries, retention policies, artifact versioning. That’s fine. Agent tool stacks today are five, ten, twenty tools run by one team. At that scale, the boring rules — one tool per box, one writer per volume, zero tool-to-tool calls — buy you isolation you can explain in a sentence and verify with docker network inspect.

Clever isolation is a research project. Cheap isolation is a compose file. Take the compose file.