Skip to main content
A Claude Managed Agent handing tool work to an isolated Sprite sandbox Claude Managed Agents let Anthropic run the agent loop and the model while the agent’s tools (the filesystem it reads and writes, the commands it runs) execute in a sandbox you control. Point a Managed Agent at a self-hosted environment and you run each session inside a Sprite, so the agent’s code, filesystem, and network egress never leave your infrastructure.

How it works

A self-hosted environment is a work queue. When a session is assigned to it, Anthropic enqueues a work item. A worker you run claims the item and starts a per-session Sprite that runs Anthropic’s tool runner. Tool inputs and outputs flow back to Anthropic so the model can see results; everything the tools touch stays in the Sprite.
Lifecycle loop: the Claude Platform enqueues a work item; a worker you run claims it and launches a per-session Sprite, and tool calls round-trip between the Platform and the Sprite where everything the tools touch staysLifecycle loop: the Claude Platform enqueues a work item; a worker you run claims it and launches a per-session Sprite, and tool calls round-trip between the Platform and the Sprite where everything the tools touch stays
The runner authenticates with an environment key, the only credential it needs for both the control plane and the per-session calls. Your organization API key never reaches the Sprite.
fly-apps/sprites-claude-managed-agents is a working Python reference implementation of this integration, with both worker variants (webhook and always-on poller) and the in-Sprite runner.

Before you begin

You need:
  • A Claude API key (ANTHROPIC_API_KEY) to create the environment and start sessions. It stays off the Sprite; the worker and runner use only the environment key.
  • A Sprites API token (org-slug/org-id/token-id/token-value). Export it as SPRITE_TOKEN.
  • An Anthropic agent. Create one with the Quickstart and note its agent ID.
  • A worker runtime on the worker host: Python 3.10+ with the anthropic and httpx packages, or Node 22+ with @anthropic-ai/sdk and tsx.

Set up the environment

Create a self-hosted environment

Note the returned environment ID (env_…).

Generate an environment key

In the Console, open the environment and click Generate environment key. Export it alongside the environment ID on the worker host:

Run the worker

Spawn a Sprite per session

The worker creates a Sprite, uploads Anthropic’s provider-agnostic runner, installs the SDK, and launches it as a Sprite service rather than a detached nohup process. A service is supervised: the Sprite owns it, so it survives beyond the request that created it and is restored on wake, neither of which a process backgrounded inside a single request can be counted on to do. Because a service that exits is otherwise restarted, the one-shot worker stops itself on completion so it is not brought back up. The ANTHROPIC_* variables are written to a file the service sources rather than passed as service arguments, so the environment key never appears in process listings. The service deletes the file right after sourcing it, so the key isn’t left on the Sprite’s disk.
A service is supervised, but it does not hold the Sprite in an active state: once a session is underway the runner takes no inbound traffic, so a bare service counts as quiet and the Sprite would pause after a short idle window, stalling a long session mid-turn. That is why the service command registers a Task and heartbeats it while the runner works: the task holds the Sprite active for the length of the session, and its short expiry is the crash-safety net that lets the Sprite pause again if the runner dies without cleaning up.

Claim work items

The worker claims sessions from the queue and calls spawn() for each. Choose the always-on poller (only needs outbound HTTPS) or a webhook (no idle poller, needs a public endpoint).
auto_stop=False because each item is handed to a Sprite that owns its own stop; the poller must not release the lease out from under it. For the webhook variant, verify the session.status_run_started delivery, then drain the queue with poller(drain=True, auto_stop=False) and call spawn() the same way.

Start a session

Create a session targeting the environment, then send the agent a turn. The worker claims it, starts a Sprite, and the agent’s tools run inside it.
The file the agent writes lands on the Sprite’s disk, where it persists for the Sprite’s lifetime; relative paths resolve to /workspace, though an agent given no explicit path may write an absolute one elsewhere. /workspace is Anthropic’s system default working directory for tool execution, and the runner passes workdir="/workspace" to match it, so that workdir is what scopes and permits /workspace access. unrestricted_paths=True is what additionally lets the file tools reach paths outside the workdir, notably /mnt/session/outputs, where Anthropic’s harness normally directs final deliverables (here just a directory on the Sprite’s disk).
A Sprite proxies a single internal HTTP port to its public URL, has a durable filesystem, and supports checkpoints. Because this flow creates a fresh Sprite per session, the SDK install runs every time. To drop that cost, reuse a pool of prepared Sprites instead of creating one per session, and restore each Sprite’s own checkpoint (with the SDK baked in) to reset it between sessions. On the TypeScript worker, the in-Sprite runner can instead be a bundled Node script (the TS SDK’s EnvironmentWorker has full parity with the Python worker), which removes the pip install and roughly halves cold start, about 10s versus 16s send-to-first-tool in our tests. The cookbook will carry that bundled-runner variant.

Clean up

Each session gets its own claude-agent-* Sprite, and those Sprites outlive the session. An idle Sprite pauses, which stops compute billing, but its filesystem persists and keeps accruing storage cost until you delete it, so a busy environment builds up a fleet of paused Sprites. Reap each one once its session finishes, on the session-end webhook or with a periodic sweep, by calling DELETE /v1/sprites/{name}; copy anything you need out of /workspace first (for example via the filesystem API), because deleting a Sprite deletes its checkpoints too.

Troubleshooting

Most failures here surface either as a queue that never drains or as a Sprite service that exits early. Check the service log first; it usually tells you which side broke.

See also

  • Self-hosted sandboxes: Anthropic’s reference for the worker contract.
  • Services: supervised long-running processes inside a Sprite.
  • Checkpoints: snapshot a prepared Sprite to skip cold-start setup.