Skip to content

Tutorial 4 · Sessions via MCP

Goal: give an agent (like Claude Code itself) pausable sandboxes as tools — one session_run call creates a worker if missing, wakes it if parked, and runs the command. Lifecycle is never the agent's job.

Prereq: the one-time setup (you need the API key; the CLI is optional here).

The control plane serves MCP at https://beta.barista.sh/mcp, bearer- authenticated with your API key. Tools:

Tool Args
session_run name, command (argv) — creates from template (or the platform default) if missing, wakes if parked
session_exec name, command (argv) — exec only, no create
session_create name (+ template, or image [+ digest], command)
sessions_list —
session_delete name
worker_invoke worker, command (argv) — runs a defined worker once and returns a handle instead of holding the connection; idempotency_key makes a retry resume rather than re-run
worker_invocation worker + either invocation (the id from the handle) or idempotency_key — reads an invocation; never starts one

There are deliberately no pause/resume tools: sessions auto-park when idle and session_run/session_exec wake them — parking is the platform's job, not the agent's.

Protocol revisions

Two are served, and the endpoint reads which one you want from MCP-Protocol-Version on each request:

  • 2025-06-18 — what you get if you send no version header. Unchanged.
  • 2026-07-28 — no handshake, no Mcp-Session-Id, and per-request carriage. Under it, every request must also carry Mcp-Method (the JSON-RPC method) and, where the call names an operation, Mcp-Name (the tool). Both are required: a request that omits them, or whose headers disagree with its body, is refused with 400 rather than routed from the body — a header that is optional in practice is a client that breaks against the next server it meets. tools/list also returns ttlMs, cacheScope and a cacheKey you can send back to be told your copy is still current without re-receiving it.

A revision the endpoint does not serve is refused by name, so you never silently get behaviour you did not ask for.

worker_invoke's handle is ours, not the revision's: 2026-07-28 defines no async task model on the core request path, so the handle travels inside an ordinary tool result and works under either revision.

Add it to Claude Code

claude mcp add --transport http barista https://beta.barista.sh/mcp \
  --header "Authorization: Bearer <your-api-key>"

Then just ask, in Claude Code:

Run cat /tmp/c in a session called demo (create it from the counter template if it doesn't exist), wait a bit, and read it again.

Claude calls session_run twice — the first call materialises the worker; if it idles and parks in between, the second call wakes it and the count has survived.

Or drive it directly with JSON-RPC

The same calls, over plain HTTP — useful for any MCP client or a quick check:

KEY=<your-api-key>
mcp() { curl -s https://beta.barista.sh/mcp \
  -H "Authorization: Bearer $KEY" -H 'content-type: application/json' \
  -d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":$1}"; }

# one call: create-if-missing (from a template — tutorial 7), wake-if-parked, run
mcp '{"name":"session_run","arguments":{"name":"demo","template":"counter",
      "command":["cat","/tmp/c"]}}'
# {"result":{"content":[{"type":"text","text":"{\"name\":\"demo\",\"exit_code\":0,\"stdout\":\"2\",…}"}],"isError":false}}

# …let it idle-park, then the same call again — it wakes and the count survived:
mcp '{"name":"session_run","arguments":{"name":"demo","command":["cat","/tmp/c"]}}'
# … "stdout":"17" …

mcp '{"name":"session_delete","arguments":{"name":"demo"}}'

A verified run (pre-session_run, with the then-manual pause/resume tools) went exec 17 → pause → resume → exec 22 — the same memory-preserving park, now automatic:

The full MCP lifecycle over JSON-RPC — the count survives the park

What this gives you

An agent (Claude Code, or anything speaking MCP) can now provision a real, hardware-isolated KVM sandbox, run commands in it, and freeze/thaw it with memory — its own pausable workspaces, as tools. Combine with the Claude Code session tutorial to have an agent that manages other agent sessions.