Agent Sessions
Drive managed Claude Code and Codex conversations over REST or MCP
An agent session is a managed conversation inside a running Firecracker sandbox. You can send work, read replies, answer tool approval requests, and interrupt a turn through the API or MCP server.
Creating a managed session starts a separate conversation. It does not attach to
the agent already running in the native terminal or import that agent's history.
Newly provisioned Codex terminals use a registered session shared with these
APIs; discovery identifies it with surface: "terminal". Existing standalone
terminals and native Claude conversations are not automatically attached. A stopped
managed bridge can be recovered while its sandbox storage survives; host storage
loss is not recoverable.
Authentication and permissions
Use your Remotehost bearer token. API keys stay within one organization and the creator's project permissions. Delegate only the permissions the client needs:
For access across your organizations, remote mcp setup --personal creates an
expiring read/send token and prints the MCP configuration. Add --approve or
--wake for those capabilities; --read-only restricts it to observation.
remote mcp tokens lists these tokens and remote mcp revoke <id> revokes one.
Personal tokens grant session orchestration and optional waking, without general
shell/file access, sandbox deletion or account administration. Signed-in users can
also create, list, and revoke them with POST /v1/me/agent-tokens,
GET /v1/me/agent-tokens, and DELETE /v1/me/agent-tokens/:tokenId.
API keys and personal agent tokens cannot mint another personal token.
| Permission | Capability |
|---|---|
agent_session.read | Discover sessions, inspect state, read replies |
agent_session.send | Create and recover sessions, send messages, interrupt turns |
agent_session.approve | Answer a pending tool approval |
The sandbox uses its connected Claude or Codex account. The caller does not send model credentials through these endpoints. Finish sandbox provisioning and agent sign-in before starting a conversation. Claude sessions require a sandbox created from a template with the Claude Agent SDK installed.
Start and send work
curl -X POST "https://api.remotehost.ai/v1/sandboxes/$SANDBOX_ID/agent-sessions" \
-H "Authorization: Bearer $REMOTEHOST_TOKEN"The 201 response includes the session's id and bridgeState: "ready".
A fresh host may take longer to load the agent runtime. Allow a 90-second client
timeout for session creation or recovery; the API waits up to 60 seconds for
bridge readiness after launching it.
curl -X POST "https://api.remotehost.ai/v1/agent-sessions/$SESSION_ID/messages" \
-H "Authorization: Bearer $REMOTEHOST_TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Inspect this project and summarize its test setup."}'Sending returns 202 with a turnId immediately. Poll
GET /v1/agent-sessions/:sessionId for turnState. The terminal states are
completed, failed, and canceled. A second message while a turn is active
returns 409; it is not silently queued.
Retry a message safely
Choose a requestKey before sending and keep it with the exact message text:
{
"text": "Inspect this project and summarize its test setup.",
"requestKey": "inspect-project-20260921"
}If the response is lost, resend the same body with the same credential. Keys are
scoped to the session and caller, must be 8–128 characters, and accept letters,
digits, ., _, :, and -. A retry returns the original turnId, its recorded
state, and replayed: true; it may already be completed. Reusing a key with
different text returns 409 request_key_conflict. Use a new key for new work.
MCP uses request_key on send_agent_message.
A 503 message_delivery_uncertain includes the original turnId. Retry with the
same key and text, or inspect that turn; a new key could submit the work again.
Without a key, inspect the turn before sending another message. This prevents
repeated command dispatch within retained session history; it does not guarantee
exactly-once tool effects or survival after sandbox-storage loss.
Keyed messages require bridge version 7. 409 session_retry_upgrade_required
means the session needs an upgrade through explicit recovery after its bridge
has stopped, or a new managed session. Recovery of an already-ready bridge does
not replace or upgrade it.
TypeScript SDK
SDK 0.3.0 exposes these operations through its typed raw client:
import RemoteHost from "@remotehost/sdk";
const client = new RemoteHost({
apiKey: process.env.REMOTEHOST_API_KEY,
timeoutMs: 90_000,
});
const sessionId = process.env.REMOTEHOST_SESSION_ID!;
// Persist this key with the message so retries reuse both values.
const requestKey = "inspect-project-20260921";
const { data, error } = await client.raw.POST(
"/agent-sessions/{sessionId}/messages",
{
params: { path: { sessionId } },
body: { text: "Summarize this project's tests.", requestKey },
},
);
if (error) throw new Error(error.error.message);
console.log(data.turnId, data.state, data.replayed);The SDK does not automatically retry message POSTs. The caller retains the key
and decides when to retry. raw returns HTTP errors in error; transport errors
reject the promise.
Discover and read replies
GET /v1/agent-sessions discovers registered sessions across projects you can
access. Optional orgId, projectId, and sandboxId filters narrow the result.
Pages contain sessions, nextCursor, and hasMore. Pass nextCursor as after
for the next page. The default limit is 50; the maximum is 100. Discovery returns
last-known state without waking sandboxes; read a session to refresh its state.
Session records identify surface as managed or terminal, include an
agentLabel, and report communication.status, communication.capabilities,
and setup/restart requirements. Check the capabilities before offering messages,
output, approvals, interruption, or recovery. Adapter support and caller
permissions are separate checks. Agent IDs are extensible strings; clients should
handle an unknown agent or an unsupported communication status.
Output is polled, with completed replies rather than token deltas. Neither REST nor the stateless HTTP MCP endpoint provides a persistent SSE event feed.
GET /v1/agent-sessions/:sessionId/output?after=0&limit=50 returns replies in
messages, with an independent nextCursor and hasMore. Save the output cursor
for your next read. Each caller owns its cursor; status polling does not consume
replies. Individual messages include seq, turnId, at, text, and truncated.
Output stays inside the sandbox. Pages are bounded to 128 Ki UTF-16 code units;
an oversized reply is marked truncated. Wake a sleeping sandbox to read output.
Destroyed sandbox output cannot be recovered through this API.
Approvals and interruption
When needsYou is true, inspect waitingOn and pendingInput. To answer:
{
"requestId": "the exact pendingInput.requestId",
"decision": "accept"
}POST that body to /v1/agent-sessions/:sessionId/answer. The alternatives are
decline and cancel. Accepting can execute the requested tool action. Missing or
stale request IDs are rejected. Numeric request IDs should be sent as numbers.
POST /v1/agent-sessions/:sessionId/interrupt requests cancellation. Poll until
the turn reaches a terminal state before submitting more work.
The corresponding MCP tools are create_agent_session, list_agent_sessions,
get_agent_session, get_agent_output, send_agent_message, answer_agent_prompt,
and interrupt_agent_turn. MCP uses request_id where REST uses requestId.
Recover a stopped bridge
Wake the sandbox, then call POST /v1/agent-sessions/:sessionId/recover or the MCP
recover_agent_session tool. Recovery resumes the saved vendor conversation and
keeps existing output cursors valid. Calling it on an already-ready session leaves
that process running.
A turn interrupted by a bridge crash is marked failed with an unknown execution
outcome. Pending work and approvals are discarded, never replayed automatically.
Read the output and inspect any affected files before deciding whether to retry.
Recovery requires the saved conversation and credentials in the original sandbox;
it does not recover a destroyed sandbox or lost host storage.
Managed Claude and Codex recovery remain supported. Registered native Codex sessions require bridge version 4 process-ownership metadata and a saved transcript. Recovery refuses to restart while a recorded prior process is alive. Older managed sessions retain recovery support but lack the newer child-process ownership check.
Native Claude communication is an opt-in development integration for newly registered terminal sessions. Follow the session's setup/restart requirements; Claude Channels account policy and explicit development opt-in still apply. Messages, output, and approvals become usable after the readiness probe succeeds. Native Claude API interruption and recovery are unsupported, and staging end-to-end acceptance of this native surface remains unverified. These limits do not apply to managed Claude conversations created through the API.