Infrastructure for cloud agents that survive anything: a dropped connection, a dead node, a control-plane restart, a revoked key. Pause, move, resume, reattach, on machines you own.
Quick start · Harnesses · Why Remount · Docs · Protocol · Website
Remount is the open-source infrastructure for cloud agents. You bring the harness, whether that is Claude Code, Codex, OpenCode, Pi, Gemini CLI, Aider, Goose, Cline, OpenHands, or the loop your product runs in Go, Python or TypeScript. Remount gives it a computer: a workspace that runs on your laptop, a VM, a GPU box, Kubernetes, Modal or Fly, moves between them with its files, policy and saved state, replays its sessions, sleeps and wakes on events, and never holds an API key. One static Go binary, one open protocol, Apache-2.0, nothing hosted.
- Move between local and cloud. Start an agent on your laptop and hand it
to a cloud node with
remount handoff; pull it back withremount resumefrom any machine. Claude Code and Codex conversations travel by transcript id; every other harness carries its state directory. - Run agents overnight. A task queue runs in one workspace, sleeps on a control-plane timer between tasks and continues on whichever node wakes it. A durable Agent sleeps when idle, wakes on a message or a merged PR, forks children, and parks for approval before an egress you marked sensitive.
- Never lose output. Sessions belong to the node. Close the terminal,
come back,
attach, and the output replays from where you left off. - Move mid-task.
ws movesnapshots the filesystem and a node in the zone you asked for restores it; files and policy follow. - Keys the agent never sees. The workspace holds a placeholder; the node's broker substitutes the real credential only for allowed hosts, audits every use, and a revocation reaches a live workspace within one renewal.
- A browser in the workspace. Navigate, screenshot, click, type, download files that become artifacts, under the same egress policy as everything else.
- Isolation you can check. A node declares a runtime profile and refuses
to start unless its backends can prove it;
remount conformance --profilegives a reviewer a report where every check is pass, fail or unavailable. - Go, Python and TypeScript SDKs, a CLI, and an MCP server, with the same typed errors everywhere.
An agent runtime is the machine an agent works on, plus the control that keeps that work alive across machines, connections and restarts. You use it to run agents where the compute is, keep them running when nothing is watching, pause them where they stand, and get a record of everything they did.
Most sandboxes tie the agent's work to one container and one connection: when either goes away, so does the work. Remount separates the two things that usually get fused. The workspace (files, processes, policy) is separate from the machine that happens to run it, so it can be snapshotted and restored somewhere else. The session (a command and its output) is separate from the socket carrying it, so a client can disconnect and reattach without losing a byte. Everything that decides what happens next, from credentials to deadlines, lives in a small control plane rather than in the workspace or in your process.
- An agent that lives in both places. Start it locally where the checkout
is, move it to a cloud node when it needs hours or a GPU, and bring it back
to inspect.
remount handoffandremount resumedo the move; a task queue runs a backlog on a durable timer wherever the workspace happens to be. - A team shipping an agent product. Every customer's agent is a durable Agent resource with a transcript, a sleep and wake policy, approvals for sensitive egress, and children it can fork. Provider keys are bound once and brokered at the node; the workspace never sees them and revocation is a single call. Every action lands in an event log you can stream to customers or auditors.
- A platform team hosting other people's agents. Nodes declare a runtime
profile and refuse to start unless they can prove it. gVisor and Firecracker
backends enforce deny-first egress and sibling isolation.
remount conformance --profileproduces the evidence a security review wants, and quotas, leases and idle policy bound what any tenant can hold. - Anything that needs a browser, a shell and time. Research agents, data-collection agents, operations agents: a workspace with a browser, files that become artifacts, egress policy on every request, and a deadline that outlives the process that started it.
go install remount.dev/remount/cmd/remount@main # or: git clone && make buildEverything below runs on your laptop with no account, token or API key.
remount standalone --data ./data & # control plane and one node
export REMOUNT_SERVER=http://127.0.0.1:7443
WS=$(remount ws create --name hello)
remount exec $WS -- sh -c 'echo hello from $(hostname)'
remount sh $WS # interactive shell, real ptyStart something long, press Ctrl-C, and pick it up again later:
remount exec $WS -- sh -c 'for i in $(seq 1 100); do echo line $i; sleep 1; done'
remount ws ls
remount attach $WS <session-id> --from 0With a provider key in your environment, one command runs a coding agent
against a key it never sees; remount run starts the standalone for you if
nothing is listening:
export ANTHROPIC_API_KEY=...
remount run claude --dir . -- 'add integration tests for the payments module'Hand that conversation to a cloud machine and leave, then resume it tomorrow from anywhere:
remount handoff --recipe claude --binding b_anthropic --task 'finish the refactor and open a PR'
remount resume $WSRun a queue of tasks overnight, sleeping between them on a durable timer, and wake a workspace when the PR merges:
remount run codex --queue tasks.txt --sleep-after 30m
remount ws sleep $WS --on github.pr.mergedCreate a durable Agent that pauses when idle, asks before risky egress, and forks a helper:
AGENT=$(remount agent create opencode --dir . --sleep-after 10m --approve on-request --detach -- 'migrate to pnpm')
remount agent watch $AGENT
remount agent fork $AGENT -- 'update the docs to match'The guided version of all of this is docs/tutorial.md. Deploying a real control plane and nodes is docs/operations.md.
A recipe is a small YAML file embedded in the binary; adding a harness is a
YAML pull request, not Go. remount run RECIPE, remount agent create RECIPE
and remount handoff --recipe RECIPE all take these:
| Recipe | Harness | Auth | Conversation travels on hand-off |
|---|---|---|---|
claude |
Claude Code | key or login | yes, by transcript id |
codex |
Codex CLI | key or login | yes, by transcript id |
opencode |
OpenCode | key or login | state directory |
pi |
Pi | key | state directory |
gemini |
Gemini CLI | key or login | state directory |
aider |
Aider | key | state directory |
goose |
Goose | key | state directory |
cline |
Cline | key or login | state directory |
openhands |
OpenHands | key | state directory |
custom |
anything after -- |
key or login | none |
Provider keys become brokered bindings through presets (OpenAI, Anthropic, Google, OpenRouter, Groq, DeepSeek, xAI, Mistral, Together, Fireworks, Bedrock, Vertex, Azure OpenAI). The full table, including sandbox modes and what state each harness carries, is in docs/harness-integration.md.
Sandbox APIs give you a container in someone else's cloud for the length of a request, and they compete on how many milliseconds it takes to start one. Remount is built for what happens after the first hour: agents whose work lasts longer than a request, longer than a connection, and longer than the process that started it. Self-hosting is the only mode, not the enterprise tier, and it sits underneath the harness you already use instead of replacing it.
| Remount | Hosted sandbox APIs (E2B, Daytona, Modal) | Coder | OpenSandbox | |
|---|---|---|---|---|
| Runs on | your machines, or Modal, Fly, Kubernetes | their cloud | your infrastructure, Terraform-defined | your Docker or Kubernetes |
| Shape | one static binary, one protocol | SDK over an HTTP API | server plus PostgreSQL, Wireguard tunnels | multi-component platform, Python server |
| Session output | replayable log; reattach after a disconnect | request/response | terminal in the workspace | request/response |
| Workspace lifecycle | snapshot, move between machines, sleep, wake on events, durable leases | per-sandbox timeouts, snapshots on some | idle shutdown | per-sandbox timeouts |
| Live harness hand-off and resume | yes, by transcript id for Claude Code and Codex | no | no | no |
| Credentials | brokered at the node; workspace holds a placeholder; revocable | API key in the sandbox, or a vault on some | no LLM keys in workspaces, gateway | credential vault |
| Isolation | process, Docker, gVisor, Firecracker; profiles verified at node start; conformance judge | provider-managed | your infrastructure | gVisor, Kata, Firecracker |
| License | Apache-2.0 | proprietary service | AGPL-3.0 with premium | Apache-2.0 |
Every row about Remount is backed by a test or a recorded live run in docs/engineering/; the other columns are from those projects' own READMEs and may lag.
Some of this borrows from tools you already know: sessions that survive a dropped connection, as in tmux and mosh; a claim queue with leases and generation fencing, as in Kubernetes; microVM and syscall-filtered isolation from Firecracker and gVisor; secrets substituted at a proxy rather than handed to the workload. The ideas Remount adds on top have names, because they show up everywhere in the protocol:
- Sessions are logs. Every session's output is an append-only log with sequence numbers, and a client reads from an offset. Reconnecting is a read, not a reconnection; a range that retention dropped is an explicit gap, never silence.
- The workspace is a value. It has a generation. Snapshot, move, sleep and wake produce a new generation, and every grant a client holds is bound to one, so a stale client cannot act on a workspace that has moved.
- Secret-blind execution. The workspace holds placeholders. The node's broker swaps them for real credentials only on requests to the hosts a binding allows, and records who used which credential where.
- Lifecycle belongs to the control plane. Sleep, wake, leases and idle policy are durable timers that survive the client, the node and a control-plane restart.
- Runtime profiles fail closed. A node claims a profile at startup and is refused unless its backends can prove it; a check that cannot run is reported unavailable, never healthy.
- Hand-off of a live conversation. A harness's saved transcript is a first-class thing that travels with the checkout and resumes by id.
- Everything is an event, committed in the same transaction as the state it describes.
your laptop control plane a GPU box
┌────────────┐ outbound ┌──────────────┐ outbound ┌────────────┐
│ remount │──────────────▶│ claim queue │◀─────────────│ remount │
│ up │ wss:443 │ event log │ wss:443 │ up │
└────────────┘ │ policy │ └────────────┘
│ bindings │
┌────────────┐ └──────────────┘
│ remount │──────────────────────▲
│ exec/sh │ frames relayed, never interpreted
└────────────┘
Every machine that runs workspaces is a node. Nodes and clients both dial the control plane, so nothing needs a public inbound port. The control plane owns the queue of workspaces waiting for a node, the event log, policy and credential bindings; session traffic passes through it as opaque frames. The same binary is the server, the node and the client.
Go:
import (
"remount.dev/remount/api"
"remount.dev/remount/client"
)
c, err := client.New(client.Options{Server: "https://remount.example", Token: os.Getenv("REMOUNT_TOKEN")})
ws, err := c.CreateWorkspace(ctx, api.WorkspaceSpec{Name: "agent"})
ws, err = c.WaitClaimed(ctx, ws.ID)
stdout, stderr, exit, err := c.Run(ctx, ws.ID, "sh", "-c", "make test")
if api.Is(err, api.CodeDenied, api.ReasonEgressDenied) { /* bind a credential for that host */ }Python (pip install ./sdk/python until the first release is published):
from remount import Client
async with Client("https://remount.example", token=os.environ["REMOUNT_TOKEN"]) as remount:
ws = await remount.create_workspace({"name": "agent"})
session = await remount.exec(ws["id"], ["sh", "-c", "make test"])TypeScript (npm install ./sdk/typescript until the first release is published):
import { Client } from "@remount/sdk";
const remount = new Client("https://remount.example", process.env.REMOUNT_TOKEN!);
const ws = await remount.createWorkspace({ name: "agent" });
const session = await remount.exec(ws.id, ["sh", "-c", "make test"]);Errors carry a stable code and reason in all three languages, and Python
and TypeScript raise one class per reason. There is also an
MCP server that exposes workspaces to any MCP client, and an
agent HTTP API for building products on top.
remount standalone is for one machine. For a fleet, run remount server
somewhere reachable, enroll nodes with remount node enroll and
remount up --enrollment-file, and choose a runtime profile per node:
remount up --server https://your-server --profile multi-tenant-isolated --label zone=gpu
remount doctor --profile multi-tenant-isolated
remount conformance --profile multi-tenant-isolated --markdown review.mdReference deployments for Docker Compose, Helm, Modal and Fly are under deploy/. Which backend satisfies which profile on which operating system is the generated support matrix.
- docs/using-remount.md: using a deployment, from a first workspace to a moved one.
- docs/harness-integration.md: every recipe, hand-off, resume, queues, and writing your own loop.
- docs/tutorial.md: a guided walkthrough.
- docs/design.md: data model, failure model, threat model, performance budget.
- spec/PROTOCOL.md: the wire protocol.
- docs/adr/: every design decision, indexed by number.
- docs/credentials.md: bindings, substitution, rotation, revocation, session principals, audit.
- docs/operations.md: deploying, hardening and running it for real.
- docs/security-profiles.md: the support matrix by operating system, backend and runtime profile.
- docs/observability.md: status, inspect, doctor, metrics, traces.
- docs/api.md, docs/mcp.md, docs/console.md, docs/images.md, docs/compatibility-policy.md, docs/releases.md, docs/benchmarks.md, CHANGELOG.md.
- docs/engineering/: dated audits, verification evidence, and the notes kept while building it, including MISTAKES.md.
| Directory | What it holds |
|---|---|
cmd/remount |
the binary: server, node, standalone and the CLI |
api/, client/ |
the public Go packages |
sdk/python, sdk/typescript |
the Python and TypeScript clients |
internal/ |
control plane, node, session log, broker, backends, simulator |
spec/ |
the wire protocol and its JSON Schema |
examples/ |
runnable programs against the public packages only |
images/ |
the default workspace image and the browser image |
deploy/ |
Compose, Helm, Modal, Fly, and the static site behind remount.dev |
web/ |
the embedded operator console |
docs/ |
everything above, plus one ADR per decision |
Everything in this README is implemented and tested, including under the race detector and in a one-process simulator with fault injection. The rows marked live were also exercised against real servers, real providers and a real browser; the runs are in the verification ledger.
| Area | Status |
|---|---|
| Exec and pty sessions with replayable reconnect | ✅ |
| Snapshots, cross-node move, sleep and wake on timers and events | ✅ |
| Durable leases and idle policy in the control plane | ✅ live |
| Brokered credentials with runtime create, rotate and revoke | ✅ live, real OpenAI and Anthropic |
| Hand-off and resume of Claude Code and Codex conversations | ✅ |
| Durable Agents: transcripts, approvals, fork, task queues | ✅ |
| Computer sessions with brokered browsing | ✅ live, Chromium in Docker |
Runtime profiles, drift detection, doctor and conformance --profile |
✅ live, gVisor passed multi-tenant-isolated |
Firecracker microvm profile |
|
| Go, Python and TypeScript SDKs with typed errors | ✅ |
| OpenTelemetry traces, Prometheus metrics, operator console | ✅ |
| Tagged release and published packages | ❌ not yet; install with go install or from source |
| Apple Virtualization, peer-to-peer transport, a hosted service | ❌ not planned |
Two limits to plan around: moving a workspace moves files and policy, not running processes (harnesses resume from their own saved state), and a browser profile does not survive a sleep or a move, on purpose.
Read CONTRIBUTING.md and AGENTS.md before a
change; make verify runs every CI gate locally. Report vulnerabilities
through SECURITY.md, never in a public issue.
Apache-2.0. Implement the protocol however you like; replace this implementation if you can do better.