Sandhop teleports a live local Claude Code or Codex session to a cloud sandbox and lets you continue it in an auth-gated browser terminal. It sends the dirty working tree, the active transcript, and the agent auth needed to resume the same session remotely — no commit, no context re-injection, native --resume.
Claude on the web and Codex cloud are good for clean repo tasks. Sandhop is for the messy local moment: uncommitted files, generated state, local slash commands, MCP config, and either Claude Code or Codex. The wedge is dirty-tree + cross-tool teleport, not another hosted agent UI.
Requires Node.js >=22.12.0. Older Node 22 builds such as 22.6.0 cannot load the current E2B SDK dependency chain and can fail with ERR_REQUIRE_ESM during sandhop setup.
npm install -g sandhop
sandhop setupsandhop setup is a short wizard: pick your sandbox provider, paste its API key, choose a transport, and it installs the sandhop trigger into whichever agents you have — a /sandhop slash command for Claude Code, and a $sandhop skill for Codex. Credentials are stored in ~/.config/sandhop/config.json. You are never asked for your Claude/Codex API key — that auth is captured from your existing local session at teleport time.
Then, from inside a project session:
/sandhop # Claude Code
$sandhop # Codex
It runs sandhop push for the current session and prints the web-terminal URL:
SANDHOP_URL https://<host>
SANDHOP_AUTH <user>:<password>
Open SANDHOP_URL and sign in with the SANDHOP_AUTH user/password to continue your session in the browser.
Sandhop is provider-agnostic. sandhop setup configures the default; override per-run with --provider.
| Provider | --provider |
Credentials (collected by sandhop setup) |
|---|---|---|
| E2B (default) | e2b |
E2B_API_KEY |
| Modal | modal |
MODAL_TOKEN_ID, MODAL_TOKEN_SECRET |
| Daytona | daytona |
DAYTONA_API_KEY (+ optional DAYTONA_TARGET) |
| Vercel Sandbox | vercel |
VERCEL_TOKEN, VERCEL_TEAM_ID, VERCEL_PROJECT_ID |
Each provider SDK is an optional dependency, loaded lazily — installing Sandhop does not pull all four. The CLI resolves credentials environment first, then the sandhop setup store, so CI/scripts can just export the env vars and skip setup.
sandhop push # teleport the latest session in $(pwd)
sandhop push --provider modal # choose a provider for this run
sandhop push --tunnel cloudflared # private/portable URL (see below)
sandhop push --agent codex --session <id> # pin the agent and a specific session
sandhop list # list running sandboxes
sandhop kill <sandbox-id> # destroy a sandbox--provider e2b|modal|daytona|vercel— sandbox provider (default: configured /e2b).--tunnel public|cloudflared— URL transport (default: configured /public).--agent claude-code|codex— force the agent (default: auto-detect from the cwd's sessions).--session <id>— resume a specific session instead of the newest for the cwd.--cwd <path>— operate on a directory other than the process cwd.--exclude <patterns>— comma-split archive excludes; repeatable.--include <absolute paths>— comma-split extra files/directories to recreate at the same absolute path; repeatable.--no-profile— skip inline profile/skill transfer; settings-script, MCP, and plugin enrichment still run.--no-ssh— skip transferring git SSH keys for the project's remotes (transferred hosts are listed in the push output).
--tunnel public(default): exposes ttyd through the provider's HTTPS preview, gated by Sandhop's per-teleport ttyd Basic Auth.(WIP) --tunnel cloudflared: binds ttyd to loopback and runs cloudflared inside the sandbox. Works through provider egress where native expose is token-gated (e.g. Daytona).- Quick tunnel (default): zero-config
*.trycloudflare.comURL + Basic Auth. - Named tunnel (Access-gated, private): set
CLOUDFLARE_TUNNEL_TOKEN+CLOUDFLARE_TUNNEL_HOSTNAME(or viasandhop setup); Sandhop returnshttps://<your-hostname>and Cloudflare Access enforces login.
- Quick tunnel (default): zero-config
- Working tree — full dirty/uncommitted state, restored at its original absolute path so the resumed session's recorded cwd matches.
- Transcript — the exact session file; resumed natively (
claude --resume/codex resume), not re-injected. - Agent auth — Claude/Codex credentials shipped as sandbox env/credential files over TLS, never inside the project tarball.
- Referenced secrets — env vars and credential files needed by the detected agent/MCP config.
- Explicit includes — each
--include <absolute path>is recreated at the same absolute path in the sandbox.
- Collect the working-tree root, transcript, auth, secrets, and local CLI version in parallel.
- Create a single-tenant ephemeral sandbox that preserves the local home path, prepares files as provider root, and starts services as the non-root local-username runtime.
- Upload the bundle, transcript, credential files, SSH files, project memory, and explicit includes.
- Install the matching agent CLI, restore the transcript, start the terminal service, and verify service readiness.
- Run inline enrichment for agent profile, settings scripts, MCP code/deps, plugins, marketplaces, and skills before printing
SANDHOP_URL/SANDHOP_AUTH. Enrichment steps fail soft: a failed step is reported (Environment ready · 6/7 steps ok) but never destroys the sandbox, and skipped MCP servers (e.g. localhost-bound) are listed with reasons.
npm ci
npm run build
npx vitest runMIT © Talking Computers