Jeremy Badder
← All work
My own tool · October 2026

Hub, my control room for AI agents

One window to start, watch and approve AI agents across my four Linux servers, from a Mac, an iPad or a phone.

4servers, each running its own agents
~1 weekto build the core, while using it
0terminals needed to run an agent
Narrated walkthrough coming soonStarting an agent, approving what it asks, and watching it work.

The problem

I run AI agents on four servers: one for my own product, one for a client, one for a church sound board, and one that ties it all together. Each agent lived in its own terminal window. Keeping track of which one was working, which one was stuck waiting for me, and what each was doing meant constant switching.

What I built

  • Every conversation in one sidebar, across all four servers, with a dot that shows working, waiting, finished or blocked.
  • Agents without terminals. Each server runs a small background service built on Anthropic's Agent SDK, so an agent can start, sleep and wake up without a terminal window.
  • Buttons instead of keystrokes. When an agent asks permission, Hub shows Yes and No. Claude Code's own menus (model, usage, resume) become clickable screens.
  • Look over its shoulder. A live feed shows every command an agent runs and what came back.
  • Server health at a glance, notes for each conversation, and one-click updates of Claude Code on every server.

How I directed the agents

I built Hub with the agents, often from inside Hub itself. Several of its safety rules came from real mistakes along the way:

  • A test once typed into a settings menu that was still open and quietly changed a real setting. Now Hub refuses to send a message while a menu is open.
  • Restarting the service would have cut off agents mid-task, so restarts now wait until no agent is working.
  • Once, a conversation got moved to the wrong place because two processes shared a label. Now Hub checks which conversation is really running before it moves or restarts anything.

What I learned

A status flag isn't the truth. The terminal manager kept reporting agents as "working" long after they had stopped. Hub now decides working or idle from the conversation record itself.

Built with

Claude CodeClaude Agent SDKNode.jssystemdTailscaleBlender (for the gauges)