agent platform for domain operators
a platform where people who are good at a kind of work turn their method into agents, tools and automations that do the work the way they would, and share them with anyone. it covers any kind of knowledge work.
fastapi backend, modal sandboxes, redis streams, nango-held oauth
python · fastapi · postgres · asyncpg · redis · modal · claude-agent-sdk · mcp · nango · oauth2 · websockets · nextjs · react · docker
A professional services firm sells its judgment, like how a particular recruiter screens candidates or how a contractor prices a bid. If every firm in a category buys the same AI tool, they all produce the same output and lose that edge.
The obvious build is a system prompt and a few API keys. That breaks in three places, and none of them can be fixed with a better prompt, so very little of this repo is the model call itself.
The main design decision is that an agent is an object that persists between conversations, and each turn wakes it once. A turn can start from a websocket message, a trigger, a schedule, an email to the agent's own address, or a Slack channel it has joined.
Skills are the operator's method stored as files on the agent's volume, and the Claude Agent SDK finds them on disk instead of having them pasted into a prompt. That mattered more than any prompt engineering I did, because a change to the operator's method is now a change to a file.
FastAPI on eight workers on one machine, deployed blue-green behind Caddy. It never runs an agent itself. It authenticates and authorises requests, writes a JSON line to a sandbox's stdin, and forwards whatever comes back.
That puts all state shared between workers in Redis, which is the right constraint, because with no sticky sessions a deploy can switch slots in the middle of a live turn. A cold Modal sandbox takes five to eight seconds to boot, so new sessions take a pre-booted one in about 200ms instead.
The sandbox runs code an operator wrote and a model extended, so it's the least trusted process in the system. It gets one HMAC session token, naming a session, a user and a scope, plus three proxy URLs. A credentialed call goes through the backend, which verifies the token, checks again that the connection belongs to that user, and only then has Nango supply the access token.
One detail I like: a 429 with none of Anthropic's rate-limit reset headers is probably the load balancer throttling, so in that case it retries the same credential once instead of locking a healthy key out of the pool.
| keys in the sandbox | a token in the sandbox |
|---|---|
| the model key in env | an hmac token as the api key |
| vendor keys in env | the base url points at the proxy |
| the user's oauth token in env | no oauth token, ever |
| one escape leaks everything | one escape leaks one session |
The eight tenancy bugs were the same mistake made eight times. In four of the five worst cases, the correct check already existed elsewhere in the repo for the same value. Code review kept missing it because each diff looked exactly like the code around it.
The second was billing. The Claude Agent SDK reports cost as a running total for the life of a client, not the cost of the turn that just ended, and every code path that saved it added that total to the session. So the charged cost grew with the square of the number of turns.
It works. Operators build agents, attach skills and connections, and publish them, and other people clone them. A clone copies the volume, then deletes every reference folder not marked as a template, so the operator's personal material isn't copied. An agent can reach 102 platform tools, 28 MCP servers, 151 Nango action scripts and 61 mapped providers.
Production has been on emergency infrastructure since a billing lockout, and the runbook I wrote has gone out of date in an expensive way. Two VMs are billing, DNS points at the clone, and their disks have diverged for three months. Getting back means a migration, and changing DNS alone won't do it.