Skip to main content

What is a Session?

A Session is a live, stateful instance of an Agent Profile. When you submit a run, Orca creates (or reuses) a session on a runner that supports the profile’s runtime. Sessions are:
  • Stateful: owned by a specific runner
  • Profile-scoped: inherit tool access from their profile at creation time
  • MCP-enabled: each session gets its own MCP HTTP endpoint
  • Persistent across runs: a session can process multiple tasks sequentially

Session Lifecycle


Session ID Format

Session IDs encode which runner owns them: Example: sess-a1b2c3d4-e5f6a7b8 Any conductor can extract a1b2c3d4, look up the runner in remote.Pool, and route to it, without a shared registry.

Session State


Session-Scoped MCP Endpoint

Every active session has a Model Context Protocol tool interface managed by Orca. This endpoint serves:
  1. Platform tools allowed by the session’s profile (toolkit registry, scoped at creation time)
  2. Session context injected into tool calls (sessionId, profileName, runId, delegation depth)
The runner sends sessionMcpUrl in the run envelope to the sidecar. The sidecar connects its MCP client to this URL to discover and invoke platform tools. External MCP servers from the profile are opened by the sidecar alongside the runner MCP client.
The MCP endpoint is only available while the session is idle or running. It is torn down on shutdown.

Managing Sessions

List Sessions

Get a Specific Session

Terminate a Session


Session Reuse

Orca reuses a session when a new run explicitly supplies sessionId and:
  1. The session was created with the same profile
  2. The session is not already running
  3. The runner that owns the session is healthy
When sessionId is omitted, POST /api/runs creates a fresh session for that run. You can see session placement and counts with the topology endpoint whenever the conductor has a runner pool, including a single-runner deployment:

Session Persistence

Runner-resident resources are still live state. A runner restart tears down the MCP endpoint, toolkit snapshot, and attached sandbox/VFS handles for that process until the conductor hydrates the session on a runner again.
When Postgres is configured, the conductor persists tenant-scoped session rows. The status lives in a flat column; flexible session metadata is stored in metadata JSONB: For resumable runtimes, the conductor can export the sidecar’s opaque state bundle and later hydrate a runner session with the same Orca session id, runtime-native session id, and bundle content. Hydration is best-effort: if no bundle exists or a sidecar cannot restore it, the runner still recreates the session record so the next run can proceed. In production, callers should still be prepared for state recovery to degrade. The default behavior is:
  • Conductor creates a new session automatically when a run is submitted without sessionId
  • Runs should contain enough context in their task prompt to tolerate a missing or stale runtime-local state bundle

Toolkit Scoping

When a session is created, the runner takes a snapshot of the profile’s tools list and intersects it with the runner’s registry. This view is immutable for the session’s lifetime:
If the profile is edited after session creation, existing sessions are not affected. Calling a tool outside the session toolkit returns HTTP 403.

Multi-Session Topology

The Runtime page in the dashboard shows the sandbox workers leased to the current workspace, from GET /api/worker/leases: one row per leased worker, its substrate, state, and lease age. It is tenant-scoped, so it does not show runner assignment, runner health, or capacity belonging to other tenants. For an at-a-glance runner-pool summary, the Stats page shows a one-line count such as “N/M runners healthy, X active sessions” (or “Runner topology unavailable in single-runner mode”). The fleet-wide runner and session topology is still available as a published API and SDK surface via GET /api/topology, even though the dashboard no longer renders it:

Public Chat Sessions

When a profile is published through the Chat Gateway, public callers never see a session id. Each conv_... row in conversations pins one stable conversation_id to a runtime session_id, so threading conversation_id across requests reuses the same backing session. See Publishing for the conversation-to-session mapping.
Last modified on September 6, 2026