boxxkite

Capability

Session handoff

Move an in-progress local Claude Code, Codex CLI, or opencode session into a fresh boxxkite sandbox — full conversation history, not a task summary — and keep interacting with it from there. The CLI keeps running under your own portable, scoped credential, never a copy of your laptop's raw login session.

How a handoff runs

Every step below composes existing, already-reviewed primitives — sandbox creation, file_create, and the same takeover PTY the dashboard's own terminal uses. No new control-plane or sidecar surface was added for this.

How a handoff runs

Locate session

The adapter finds your tool's real on-disk session state (or, for opencode, its own export format) and a portable, scoped credential -- never your raw browser login session.

Install & run

boxxkite handoff <tool> ships as part of the main CLI — one install, nothing extra to add:

terminal
pip install boxxkite-sandbox
boxxkite config set-key bxk_live_...
boxxkite handoff claude-code

set-keyalone is enough — it defaults to boxxkite's own hosted control-plane. Self-hosting instead? Run boxxkite config set-url <your-control-plane> too — everything else works the same. Pass --session <id> for a specific session, or omit it to hand off whichever local session was modified most recently. --api-key and --base-url flags override the saved config for a one-off run.

Per-provider setup

Each tool authenticates the sandbox with its own portable credential — never a copy of your local login.

  • Claude Code — run claude setup-token locally (needs an active Claude subscription). It prints a long-lived, model-requests-only token — export it as CLAUDE_CODE_OAUTH_TOKENbefore running the handoff, or the adapter picks it up automatically if it's already in your environment.
  • Codex CLI — set OPENAI_API_KEY (or CODEX_API_KEY / a personal access token) if you have one. If your only local login is a ChatGPT Plus/Pro subscription, no extra setup is needed — the handoff falls back to codex login --device-auth, a real device-code flow that opens a URL and code you complete from any browser, right inside the takeover terminal. It mints a fresh, independent login for the sandbox rather than copying your local session.
  • opencode — no setup needed beyond having logged in locally with a real provider API key (type: "api" in auth.json). A provider configured only via opencode's own OAuth login isn't portable, and the handoff will say so clearly rather than copying it.
  • Cursor — get a key at cursor.com/dashboard/api and export it as CURSOR_API_KEY. The adapter itself isn't implemented yet — see the table below for why.

How credentials stay safe

Your credential is never typed anywhere as a literal value. It's written once to a short-lived file, read back with a single reference to its path, and deleted immediately by that same command — so at no point does the raw token appear in a command, a log line, or shell history.

  • Always the tool's own portable, scoped, independently-revocable token — never your raw browser/OAuth session.
  • Written only to a short-lived file under /tmp, never anywhere that syncs to durable storage.
  • Deleted by the same command that reads it, and every session identifier is validated before it can reach a shell command.

Full technical design

See docs/handoff-adapters.md in the repo for the complete adapter contract, architecture diagrams, and security design behind this.

Supported tools

ToolStatusCredential
Claude CodeSupported — cwd-sensitive resumeclaude setup-token
Codex CLISupported — path-based resume, plus a device-auth fallback for subscription-only loginsOPENAI_API_KEY, a personal access token, or codex login --device-auth
opencodeSupported — via export/importprovider API key from auth.json
CursorNot yet — cursor-agent's local session store couldn't be confirmed as a portable, copyable file. Raises a clear error rather than faking support.
Gemini CLINot yet — in progress as a community contributionGEMINI_API_KEY

The adapter contract is designed for community contribution — adding a new tool means implementing onelocate_session() call, not touching the shared orchestration. See docs/handoff-adapters.md's "Adding a new adapter" section.

Where this fits today

Not an MCP capability, and not a control-plane API

A handoff adapter reads local, on-disk CLI session state on your own machine — that's a fundamentally local operation an MCP tool call (which runs wherever the MCP client invokes it) can't perform on your behalf. boxxkite handoff stays a local-only CLI command for exactly this reason, and it composes existing control-plane/SDK primitives rather than adding new ones — there is nothing new to call directly from the Python/JS/Go/Rust SDKs either.

Related

  • Python SDK boxxkite handoff is built directly on BoxxkiteClient.
  • Audit log & takeover the same channel this feature attaches to, and why everything typed on it gets logged.
  • Secrets management a different trust boundary (brokering a third-party key to a semi-trusted agent) than a handoff's own credential handling.
  • MCP server why this capability isn't exposed as an MCP tool.
  • Security model the broader defense-in-depth posture this feature was built to fit inside, not around.