what runs
An ad-hoc python script.py or a hand-written FastAPI stub that only resembles the deployed agent.
The exact agent runtime — a2a dev --local runs the same image and code that deploys.
a2a dev --local runs your agent right on your laptop — Docker by default, running the same container image that deploys, or a direct Python process with --host-runtime when you want a debugger. Wire in .env.local, mount a workspace, get hot reload on every save, and drive it all from the /_dev console at 127.0.0.1:8000. The same runtime you ship, just local — and offline-capable when you need it.
a2a dev --local · Docker or host runtime · .env.local · hot reload
The usual way to iterate on an agent locally is a throwaway python script.py or a hand-rolled FastAPI stub — something that resembles the deployed agent but isn't it. Secrets get pasted inline, the file contract drifts, the local Postgres is a different version from the cloud, and the moment someone else needs to run it you're rewriting the whole thing into a 'real' service. What you tested locally was never quite what shipped.
a2a dev --local starts the agent on your machine — Docker running its container image by default, or a raw uvicorn process with --host-runtime. Load .env.local with --env-file, mount a directory with --workspace, keep hot reload on, and drive it from the /_dev console. It's the same runtime that deploys, and it runs offline when you need it to.
One command starts the agent on localhost. Docker is the default — it runs your agent inside its own container image, the same image that ships to production. No cloud round-trip, no public URL: the agent serves at 127.0.0.1 and you own the process.
Skip the container when you want speed and a debugger. --host-runtime runs a direct uvicorn process against your local Python env, so breakpoints, profilers, and print statements all land in your terminal. Same agent, no Docker layer in the way.
Point --env-file at .env.local to load your dev keys and config, and --workspace mounts a real directory as .a2a/workspace/{inputs,outputs}. The agent reads and writes files on your disk during a run — inspect the outputs the moment they land.
Reload is on by default (toggle with --reload/--no-reload). Edit a tool, save, and the local runtime restarts against your new code — no rebuild, no redeploy. --port (8000) and --host let you place it exactly where the rest of your stack expects it.
http://127.0.0.1:8000/_dev is a full dev console: invoke tools by hand, set env vars, upload test files, and stream results as they run. The agent card is served at /.well-known/agent-card, so any A2A client can point straight at your local box.
Because --local runs entirely on your machine, it works with no network at all — on a plane, behind a firewall, or in an air-gapped environment. Develop and exercise the agent against local resources without a single call leaving the laptop.
An ad-hoc python script.py or a hand-written FastAPI stub that only resembles the deployed agent.
The exact agent runtime — a2a dev --local runs the same image and code that deploys.
Whatever happens to be in your shell; secrets pasted inline or exported by hand.
.env.local via --env-file, loaded the same way the platform loads config in production.
Files scattered wherever the script writes them; no consistent inputs/outputs contract.
--workspace mounts .a2a/workspace/{inputs,outputs} — the same file contract prod uses.
A Postgres you installed yourself, or none — versions drift from what runs in the cloud.
a2a chat spins up Postgres 16 and Qdrant via Compose from a2a.yaml — dev↔prod parity.
Rewrite the script into a 'real' service before anyone else can run it.
No rewrite — the agent that ran locally is the artifact that deploys.
Run a2a dev --local from your agent directory. It starts the agent on your machine — Docker by default, running your agent's container image — and serves it at http://127.0.0.1:8000 with the /_dev console at /_dev and the agent card at /.well-known/agent-card. Point --env-file at .env.local for your dev config and --workspace at a directory to mount as the agent's workspace. Edit code, save, and hot reload restarts the runtime against your changes.
By default a2a dev --local runs the agent inside its container image — the same image that deploys, so what you test is what ships. Add --host-runtime to instead run a direct Python (uvicorn) process against your local environment. The host runtime is faster to start and lets you attach a debugger, set breakpoints, and use profilers directly; the Docker path gives you the closest parity to production.
Yes. a2a dev --local runs entirely on your machine and is offline and air-gapped capable — no network call is required to start or exercise the agent. If your agent declares resources in a2a.yaml, a2a chat provisions them locally with Docker Compose: Postgres 16 when you declare resources.databases, and Qdrant when resources.memory.tiers includes vector. That gives you the same Postgres and vector store locally that you'd have in the cloud.
No. The same agent code and runtime that runs under a2a dev --local is exactly what deploys — there's no rewrite and no separate 'production' entrypoint. Local dev, the cloud dev box, and production all run the same artifact, so behavior you see on your machine is the behavior you ship. The .env.local, mounted workspace, and inputs/outputs contract mirror what production uses.
Use a2a dev --local when you want the agent on your own machine — offline work, fast iteration with --host-runtime and a debugger, or when you don't want a public URL. Use a2a dev (without --local) when you want a scale-to-zero cloud dev box with a public URL you can share or point a remote client at — that's the /cloud-dev path. Both run the same runtime; the only difference is where the process lives.
All guides live in the guides index.
a2a dev --local runs your agent on your machine — Docker or --host-runtime — with .env.local, a mounted workspace, hot reload, and the /_dev console at 127.0.0.1:8000. a2a chat provisions local Postgres 16 and Qdrant from a2a.yaml for dev↔prod parity. When you want a public URL and a scale-to-zero cloud dev box instead, reach for the cloud path — but either way, the runtime you exercise is the runtime you ship. No rewrite.