Skip to content
Rex St. John

Constructing Your Own Agent Host

Building a secure environment to host multiple agents, and making it simpler to manage security and access to all the APIs they need.

Agent Host diagram: dashboard, agent bank, permissions and security, API router, foundation (memory, search, web crawler, API vault), and the agent host itself

Lately I've been thinking a lot about why people are building their own personal data centers by buying Mac minis and stacking them in rows.

When I ran the costs, buying a pile of Mac minis didn't make much sense for me. They cost about $900 each. Most of what I actually do is put agents in a box somewhere, usually several of them, and have them call APIs. Even uncensored models, uncensored web scraping and uncensored search are available as APIs, through OpenRouter, DeepSeek, Together.ai and plenty of others.

So I skipped the Mac minis. What I wanted was closer to what I'd call an API router.

What an agent actually is, under the hood

Look under the hood and most of the work these agents do is running something like Claude Code or Hermes. That's a harness, maybe a GitHub repo, and some connections to outside APIs and storage. I didn't need a data center for that. I could lease a Hetzner box for about $25 a month, host all my projects on it, and reach them from anywhere.

The real problem is keys and permissions

What I really needed was a fix for one specific annoyance: managing permissions and API connections across every agent. I might have nine to twelve agents going at once, one per project, and keeping API keys straight across all of them is one of the biggest hassles.

So I wanted to put every agent in one box, add an API router and a single process for managing keys, and decide which APIs each agent is allowed to call. I also need to watch what the agents cost and how they perform.

There's one more reason. The ground keeps shifting under me. Every other week there seems to be a cheaper, faster or better model, or a less censored one. I want to run my agents as cheaply as I can, and that means changing the setup whenever something better shows up.

Why this is easier than ever

A year ago I would have spent weeks on this. This time I built it with Grok Bot, my AI assistant, which has its own computer. It researched the providers and their prices, signed up for the API keys, paid for them, and plugged them into the box. It rented the server from Hetzner, set up the private repo that describes the whole box, and tied all of it together.

Grok Bot plus Vercel has also changed how I build things. I now do almost all of my programming by voice. I describe what I want, Grok Bot does the work, and Vercel deploys it. Most of this agent host was built that way.

The agent host

That led me to the idea of an agent host. You run a box, and it has these parts.

  1. Dashboard. Where you control and manage the agent host. It tracks cost, sets spend caps, shows what each agent is doing, what it costs and which models it uses, and manages the connections to the outside APIs the agents are allowed to use.
  2. Agent bank. A list of agents, such as Claude Code or Hermes, each working on a different repository for a different purpose. Each one has its own permissions, but they all plug into the same shared APIs.
  3. Permissions and security. Sets what each agent may do and which APIs it may use, plus the runtime guardrails it has to follow: spending caps, allow-lists, and my approval for big actions.
  4. API router. One central, secure place the agents call when they need an outside API. The agents never see an API key. The router holds the keys and hands out access agent by agent.
  5. Foundation. Beyond connectors and routing, most agents need the same few things: a web crawler, search, memory and an API vault. I'd rather build those once and let every agent share them than have each agent roll its own. The API vault (or security vault) holds the API keys and other credentials somewhere the agents can never read them.
  6. The agent host itself. A dedicated cloud server or virtual machine, a Mac, or some other hardware. Just basic compute.

How I built mine

Here's how mine is put together.

The box. It's a Hetzner Cloud CAX31: 8 Arm vCPUs and 16 GB of RAM, running Ubuntu 24.04 in Hetzner's Falkenstein data center in Germany. It costs $24.99 a month. Everything runs in Docker. Germany is a long way from me, but latency to the box barely matters, because the models run at the providers anyway.

Locking it down. Nothing on the box is open to the public internet except SSH, and SSH only accepts keys. Every service listens on localhost. I reach the box over Tailscale, a private network between my own devices. The dashboard is only served on that private network, and it only lets in my Tailscale identity.

The agent bank. Each project gets its own agent. Right now there are eight Hermes agents running in Docker containers, one per project plus a web research agent, and seven always-on Claude Code agents. Each Claude Code agent runs as its own Linux user with its own working folder, inside a tmux session that systemd restarts if it ever dies. The design lets me drive any of these sessions from the Claude app on my phone through Claude Code's Remote Control.

GitHub, one repo per agent. This is my favorite part. An agent never holds a GitHub credential. Each repo has its own deploy key, and that key sits with a small gateway service that serves exactly one agent and one repo. The agent can read its repo and push to branches named after itself. It can't touch main, can't force-push, can't delete anything, and can't open pull requests. I review and merge. Three projects are hooked up this way so far: my family history app, my book, and this website. Every request and every refusal goes into an audit log.

The API router. For models I use LiteLLM, an open-source proxy. It's the only thing on the box that holds the model providers' keys. Each agent gets its own LiteLLM virtual key with a list of models it may use and a spending budget. If a key leaks, I can revoke it, and it can only spend what its budget allows.

Models. DeepSeek is the cheap default for the Hermes agents. If DeepSeek fails, the router falls back to Fireworks, which hosts open-weight models, and then to OpenRouter. The web research agent also gets a separate "unfiltered" group of open-weight models through Venice and OpenRouter. I don't jailbreak closed models. That breaks their terms, so when I want fewer restrictions I use an open-weight model. The Claude Code agents default to Claude Haiku 5.5.

Private data. Some agents work with private data. They run on Claude only, through a second private router that has no other provider wired into it at all, so DeepSeek, Fireworks, OpenRouter and the rest can't be reached. Their containers sit on internal Docker networks with no internet access, and the only thing they can reach is that private router. The strictest one has no GitHub access at all, and its Claude Code session can only talk to Anthropic. The rules are enforced in four places: the network, the router, Claude Code hooks, and the dashboard, which refuses to attach a blocked provider's key to one of these agents. A test script checks all of it.

Guardrails. Both routers refuse certain requests before they ever reach a provider: sexual content involving minors, and sexual content of real people without their consent. The media service also refuses to clone a voice without a record of consent.

The foundation. Search runs on SearXNG, a self-hosted metasearch engine, plus DeepSeek's paid search and fetch APIs. The web crawler is a headless Playwright browser inside the research agent's container. The research agent treats every fetched page as untrusted, so nothing on a web page can tell it to do something.

The vault. The principle is simple: the agents can never read the credentials. Keys live in the vault, only the routers and gateways can use them, and an agent only ever gets scoped access through them.

The dashboard. It shows every agent's state, health, restarts and 30-day spend, and every connection's status, with a Check button and a reconnect option. Pasting a key is write-only. I paste it into a box and click Save, and from then on the dashboard shows only the last four characters. A Clear button revokes it in one click. Every change goes into an audit log that never records a key's value. Where a provider reports it, the dashboard also shows how much credit I have left. Otherwise it shows spend.

What it costs

The fixed cost is the server: $24.99 a month.

Everything else is pay-per-use, and every agent has a cap. Right now each agent's model budget is $5 per 30 days, with separate $5 caps for media and for paid search. When an agent hits its cap, it gets blocked.

Here's what the models cost per million tokens, per the providers' published prices as of late October 2026:

ModelInputOutput
DeepSeek Flash (default for Hermes agents)$0.14 ($0.0028 if cached)$0.28
Claude Haiku 5.5 (Claude Code and private-data agents)$0.10$0.50
DeepSeek Search or Fetch$0.75 per 1,000 successful calls

Haiku's price goes up to $0.50 in and $2.50 out once a prompt passes 100,000 tokens, which a long Claude Code session can hit.

At those prices, $5 buys a little over 35 million input tokens on DeepSeek Flash. Real spend depends on how hard the agents work, but with every agent capped, model spend can't run away.

Jev. Jev is a special model that works as a decision engine to lower the cost of agents. It plugs into the same router as every other model, so I can measure what it saves against my normal spend.

Buying small boxes vs renting on Hetzner

10 Mac minis at home1 Mac mini at homeHetzner CAX31 (what I rent)
Upfront cost$8,990$899$0
Monthly cost~$20 power~$2 power$24.99
Specs120 CPU cores, 160 GB RAM total12-core M6, 16 GB RAM, 256 GB SSD8 Arm vCPUs, 16 GB RAM
PowerIncluded above (assumes ~15 W average each)~11 kWh/month, about $2Included
Network and public IPYour home internet. A static IP is extra or not offered, depending on your ISPSamePublic IPv4 and 20 TB/month of traffic included
Remote accessYou set it up (I'd use Tailscale either way)SameSame; the box is never on my home network
ScalingBuy another boxBuy another boxResize the server in place, or add another
Failure or replacementYou fix it or buy a new oneSameHetzner's problem; rebuild from the repo
Noise and spaceA shelf, cables, a UPS if you're carefulFits anywhere, basically silentNone
Break-even vs Hetzner~360 months (30 years) on hardware alone~36 months on hardware; ~39 counting powern/a
What it's good forLocal model inference, private data, macOS and iOS buildsSame, at small scaleAgents that mostly call APIs

Sources and assumptions.

  • Mac mini price and specs: Apple's newsroom, August and September 2026. The M6 Mac mini starts at $899 with 16 GB of memory and 256 GB of storage.
  • Power draw: Apple Support's Mac mini power page, published September 21, 2026, lists the M6 at 4 W idle and 70 W at full CPU load. I assumed 15 W average for an always-on agent box. That's my guess, not Apple's number. 15 W × 730 hours = 10.95 kWh a month.
  • Electricity: U.S. Energy Information Administration, average residential price of 18.16¢ per kWh in August 2026. 10.95 kWh × $0.1816 ≈ $1.99 a month per Mac mini. The range is about $0.53 at idle to $9.28 flat out.
  • Hetzner: my actual bill for the CAX31, $24.99 a month. Hetzner's cloud page (hetzner.com/cloud) lists 20 TB of included traffic in the EU.
  • Break-even: $899 ÷ $24.99 ≈ 36 months. Counting power, $899 ÷ ($24.99 − $1.99) ≈ 39 months. Ten Mac minis: $8,990 ÷ $24.99 ≈ 360 months.
  • Not counted: resale value, AppleCare, a UPS, and your time. I didn't find reliable numbers for these, so I left them out rather than guess.

To be fair to the Mac mini crowd, ten Mac minis give you ten times my RAM and real Apple silicon. If you want to run models locally, keep data off anyone else's servers, or build for macOS and iOS, local hardware makes sense. My agents mostly sit there calling APIs. For that, one rented box is plenty, and I'd have to run it for 30 years before ten Mac minis paid for themselves.

Caveats

This setup has trade-offs. If you have private data, or agents that shouldn't reach certain APIs or share certain data, you have to set that up per agent with runtime rules. That's what the permissions and security layer is for.

Putting every key behind one box also means that box is the thing to protect. That's why nothing on it is open to the internet except key-only SSH, the agents hold no raw keys, and each agent can only write to its own branches.

Final thoughts

The hardest thing about agents is that they have to keep evolving, because the technology keeps changing under them. I don't have an answer to that yet, but I'll keep working on it.