Blog / Launch
Introducing AgentServe
Agents can build a working app in an afternoon. Then they have nowhere to put it. AgentServe gives them somewhere, and lets a human decide what to keep.
Here is a scene you have probably lived through. You ask a coding agent for a small app: a FastAPI backend, a React
frontend, a SQLite file for state. Twenty minutes later it reports, with some pride, that everything is done. Then it
tells you to run uvicorn main:app --reload in one terminal, npm run dev in another, and to
open localhost:5173.
The app exists. Nobody can see it. You can't send it to a colleague, you can't open it on your phone, and the agent can't test it the way a user would. The last step of "build me a thing" is still yours to do by hand.
AgentServe is our attempt to fix that last step. Agents deploy multi-service stacks with no account. The stacks run for an hour. A human claims the ones worth keeping, and everything else cleans itself up.
Agents build things, then hit a wall#
Hosting platforms were designed for people. You sign up, verify an email, add a card, create a project, link a repo, pick a region and paste some environment variables. Every one of those steps is reasonable on its own. For an agent in the middle of a task, each one is a wall: it can't sign up for you, it shouldn't hold your card, and it has no idea which of your three cloud accounts you'd want this in.
So agents do the next best thing and stop at localhost. Or they reach for your existing credentials,
which is worse. Neither is great. The first leaves the work unfinished, and the second hands a lot of trust to
something you asked to build a todo list.
We think the deploy should be the cheapest part of the loop: one call, no account, live URLs back. The question of who owns the result can wait until someone actually wants to keep it.
Deploy first, claim later#
That is the whole idea. It fits in a diagram:
agent ──deploy──▶ live (1h) ──expires──▶ snapshot kept 7 days ──claim──▶ restored, no TTL
│ ▲
└────── human opens claim URL any time ────────┘
An agent uploads a project. AgentServe builds every service, wires their URLs together and returns three things: the live URLs, a manage token the agent keeps for redeploys, and a claim URL meant for you. The agent's job is to hand you that link.
If you like what you see, open the link, enter an email and a password, and the stack moves into your account. The one-hour clock goes away and the URLs stay the same. If you don't open it, the stack stops after its hour and the snapshot sits quietly for seven days in case you change your mind. Claiming during that time brings it back with its data. After that, it's gone.
The nice property is that the default outcome of an experiment is that it disappears. You don't end up with forty forgotten preview apps billed to your card. The only stacks that last are the ones a person chose to keep.
We wrote more about why ownership works this way in Deploy first, claim later.
What an agent actually does#
Agents reach AgentServe in three ways, all of which talk to the same /v0 API:
- A CLI.
agentserve deploy ./my-projectuploads the directory, waits for the build and prints the URLs and the claim link. Running it again in the same directory redeploys the same stack. - An MCP server with five tools:
deploy_stack,stack_status,get_logs,extend_ttlanddestroy_stack. - Plain HTTP, for agents you wrote yourself. A multipart POST with a tarball is enough.
There is also a skill file at /skill.md that tells an agent how all of this works, including the
important social bit: give the human the claim URL and say when the stack expires.
For anything beyond one service, the agent writes an agentserve.yaml. Here is one for a FastAPI API
and a Vite frontend that calls it:
name: todo-app
ttl: 1h
services:
api:
path: ./backend
runtime: python-3.12
start: uvicorn main:app --host 127.0.0.1 --port $PORT
health: /healthz
env:
CORS_ORIGINS: ${web.url}
web:
path: ./frontend
runtime: static
build: npm run build
output: dist
env:
VITE_API_URL: ${api.url}
depends_on: [api]
The ${api.url} reference is resolved before the frontend builds, so the API's public URL is baked into
the bundle. The API, in turn, allows CORS from the frontend's URL. Agents get this wrong surprisingly often when they
wire it by hand, so we made it a one-liner. With no manifest at all, AgentServe infers a single service from
requirements.txt, pyproject.toml, package.json or index.html.
What works today#
- Multi-service stacks of up to four services, with Python, Node and static runtimes, built in dependency order.
- Persistent data. Every service gets
$DATA_DIR, a directory that survives redeploys, expiry and claiming. SQLite files and uploads go there. - Safe redeploys. The new version builds while the old one keeps serving. If the new one fails to build or doesn't pass its health check, the old one comes back. We wrote up the internals in Build, then swap.
- Supervision. Crashed services restart with backoff. A service stuck in a crash loop marks the stack failed instead of restarting forever.
- Events and webhooks.
stack.live,stack.deploy_failed,stack.expiring,stack.claimedand friends, available by polling or as signed webhook deliveries. - A console for claimed projects: a map of which service calls which, deploy history, combined live logs, per-service pages with a restart button, and a switch to revoke the agent's access.
- Owned deploys. Give an agent your
AGENTSERVE_API_KEYand its deploys land straight in your account, with no clock.
What doesn't work yet#
We'd rather you hear this from us than find out the hard way.
There is no sandbox. Services run as plain processes under the server's user. It is not fine for untrusted code from strangers. Doing this properly needs containers or microVMs with CPU, memory and network limits, and we haven't built that. The details are on Security.
It's one node. A single server, SQLite for state, local processes for services. There are no managed
add-ons yet, so if your app wants Postgres or Redis, it will have to settle for SQLite in $DATA_DIR for
now.
No email. You can bind a stack to an email so only that address can claim it, but we don't send anything. Notifications go to a webhook you configure.
Abuse controls are basic. A per-network cap on running unclaimed stacks, the one-hour clock, and in-memory rate limits. Public anonymous hosting also needs phishing and malware scanning and a way to report a stack, and we don't have those either.
The current numbers for all of this are on Limits.
Try it#
uv tool install agentserve
agentserve deploy ./todo-app
The deploy prints two URLs and a claim link. Open the frontend, add a todo, then open the claim link and keep it. Or don't, and watch it expire in an hour. Either way, you're done before your coffee is.
Next, hook up the agent you already use: there are guides for Claude Code, Cursor, Codex and others, and the quickstart covers the rest.