Google's Fly.io example
The same setup as a quick start, from the
gemini-api CLI repository.How it works
You create a self-hosted environment in the Gemini API. Inside a Sprite, thegemini-api CLI runs environments connect, a worker that polls Gemini for work over outbound HTTPS. When you send the agent an interaction that targets your environment, the worker picks it up, runs the agent’s tool calls inside the Sprite, and sends the results back.
The worker authenticates with the environment key only. Your Gemini API key stays on your own machine and never reaches the Sprite.
Because the worker polls, it only receives work while it is running. The Run the worker as a service step keeps it running and keeps the Sprite awake.
Before you begin
You need:-
A Gemini API key, exported as
GEMINI_API_KEY. The agent’s default model, Gemini 3.8 Flash, works on the free tier. To use Gemini 4 Argon or Carbon, the key’s project needs billing turned on. -
The
gemini-apiCLI on your local machine, to send interactions:
~/.local/bin isn’t in your PATH, add it as the warning suggests, or run the CLI as ~/.local/bin/gemini-api.
- The
spriteCLI, installed and logged in:
sprite CLI, run sprite upgrade. This guide uses sprite exec --no-stdin, which needs version 2026-09-02 or later.
Create a self-hosted environment
Connect a Sprite
Create the Sprite and install the CLI
Store the environment key
Write the key to a file only your user can read. The worker reads it from there, so the key never appears in a command line or process listing.Run the worker as a service
You can rungemini-api environments connect directly with sprite exec, but it stops when that command ends. The Sprite also pauses when it goes idle, and outbound polling doesn’t count as activity, so a paused Sprite stops picking up work. Run the worker as a Sprite service instead, so it restarts if it crashes, and have it hold a Task so the Sprite stays active while the worker runs.
Write the start script. It gives the agent ~/workspace as its working directory; without --root-dir and --workdir, the worker uses whatever directory it starts in.
/.sprite/logs/services/gemini-connect.log.
A connected Sprite stays active the whole time the worker runs, including while it waits for work, and an active Sprite is billed for compute. To stop billing between uses, stop the service with
sprite-env services stop gemini-connect (the Sprite then pauses) and start it again with sprite-env services start gemini-connect when you need it. If the worker crashes without cleaning up, the task expires within five minutes and the Sprite can pause.Run an interaction
From your local machine, send the agent an interaction that targets your environment:hello.txt lands in ~/workspace on the Sprite’s disk.
An interaction can take several minutes, most of it spent waiting on the model between tool calls. gemini-api agent run streams the reply as it arrives. To watch the agent’s tool calls on the Sprite side, follow the service log:
The file tools are confined to
--root-dir, but execute_bash is not: shell commands can reach anything the Sprite’s user can. The Sprite itself is the isolation boundary, so give each environment its own Sprite.Use a Fly Machine instead
To use a plain Fly Machine instead of a Sprite, store the key as an app secret rather than passing it with-e. That keeps it out of the Machine’s config:
Clean up
Deleting a Sprite deletes its disk and checkpoints, so copy out anything in~/workspace you want to keep first.
Troubleshooting
Most failures here show up as interactions that never complete. Check the worker’s service log first; it usually tells you whether the worker, the key, or the CLI install is at fault.See also
- Self-hosted environments: Google’s reference for the worker, its flags, and its tools.
- Claude Managed Agents: the same idea for Anthropic’s Managed Agents.
- Services: supervised long-running processes inside a Sprite.
- Keeping Sprites running: the Tasks API and the heartbeat pattern.