Agents
An agent reaches raw.computer three ways, and they answer alike: the raw CLI with --json, the
HTTP API, and the raw MCP server (raw mcp), whose tools are the CLI's commands. The
raw-computer skill tells the agent how to use them: signing in, the budget, creating sandboxes, Idempotency-Key and
next_step. One command puts both into the harnesses on your machine:
curl -fsSL https://raw.computer/install.sh | sh
raw login
raw agent setup
Claude Code skill ~/.claude/skills/raw-computer/SKILL.md written
mcp ~/.claude.json mcpServers.raw written
Codex skill ~/.agents/skills/raw-computer/SKILL.md written
mcp ~/.codex/config.toml [mcp_servers.raw] written
Cursor not found ~/.cursor
The MCP server runs: /home/ada/.local/bin/raw mcp
Restart a harness that is running to load them. Take them out with: raw agent setup --remove
During early access every sandbox create answers capacity_unavailable (Limits),
and the skill says so, so an agent tells you rather than retrying. Running commands in a sandbox, files and SSH are not
there yet; the skill and the tools offer only what the API answers today.
The skill
raw-computer is an Agent Skill: one SKILL.md with a name and a description, which a
harness loads when a task needs it. It covers:
- signing in:
raw loginfor a person at a browser, an API key inRAW_API_KEYwhere there is none; - the three ways in (MCP tools, the CLI with
--json, the API) and that they are the same commands; - reading the workspace's budget first, and starting nothing when
can_startisfalse; - creating a sandbox, the queue, and what
capacity_unavailablemeans during early access; - sending an
Idempotency-Keyand reusing it on a retry; - branching on
error.codeand doing whatnext_stepsays.
Install it with raw agent setup (below), or into any harness the skills CLI knows:
npx skills add https://raw.computer
The site publishes it for discovery at two paths:
| Path | What it holds |
|---|---|
/.well-known/agent-skills/index.json |
the index (discovery v0.2.0): each skill's URL and the sha256 of its file |
/.well-known/skills/index.json |
the same skills in the index's earlier form (v0.1: a list of files) |
/.well-known/agent-skills/raw-computer/SKILL.md |
the skill itself; /.well-known/skills/raw-computer/SKILL.md is the same file |
There is one copy of each skill. The CLI carries the same file inside its binary, so when the CLI updates itself to a
release whose skill changed, its next run writes the new one where raw agent setup put the old.
raw agent setup
raw agent setup # every harness found
raw agent setup --harness codex # only this one, found or not
raw agent setup --remove # take out what it wrote
It looks in your home directory for each harness and writes, at user level so every project has them:
| Harness | Found by | The skill | The MCP server |
|---|---|---|---|
| Claude Code | ~/.claude or ~/.claude.json |
~/.claude/skills/raw-computer/SKILL.md |
mcpServers.raw in ~/.claude.json |
| Codex | ~/.codex (CODEX_HOME) |
~/.agents/skills/raw-computer/SKILL.md |
a marked [mcp_servers.raw] block in config.toml |
| Cursor | ~/.cursor |
~/.agents/skills/raw-computer/SKILL.md |
mcpServers.raw in ~/.cursor/mcp.json |
Codex and Cursor both read ~/.agents/skills, so they share one copy (Cursor would otherwise list the skill twice).
CLAUDE_CONFIG_DIR moves Claude Code's paths, as it does for Claude Code. The MCP server's command is the full path
of the raw binary that ran setup, so a harness started from an app, without your shell's PATH, still finds it.
- Run again, it changes nothing that is right already: each line says
unchanged. - It touches only its own entry. Every other key of a JSON file stays, in its order;
config.tomlstays byte for byte outside the block between# >>> raw.computerand# <<< raw.computer <<<. Anenvyou add to the raw entry is kept. - What is yours stays yours: a server named
rawthat runs something else, or a[mcp_servers.raw]you wrote by hand, is left alone (kept), and--removeleaves it too. --removedeletes the skill and the entry it wrote, and nothing else; a skill another harness still set up reads is kept.
With --json, stdout holds one document:
{
"object": "agent_setup",
"action": "setup",
"mcp_command": ["/home/ada/.local/bin/raw", "mcp"],
"harnesses": [
{
"id": "claude-code",
"name": "Claude Code",
"found": true,
"skills": [{ "path": "/home/ada/.claude/skills/raw-computer/SKILL.md", "status": "written" }],
"mcp": { "path": "/home/ada/.claude.json", "status": "written" }
},
{ "id": "cursor", "name": "Cursor", "found": false, "skills": [], "mcp": null }
]
}
A status is written, unchanged, removed, absent (nothing to remove), kept (not ours, left alone, with a
note) or failed (with a note saying why; the command then exits 1). No harness found is not an error: it says
so, and how else to get the skill.
The MCP server
raw mcp is a local MCP server on stdin and stdout, started by the harness. To add it by hand instead of with
raw agent setup:
claude mcp add --scope user raw -- raw mcp # Claude Code
codex mcp add raw -- raw mcp # Codex
{ "mcpServers": { "raw": { "command": "raw", "args": ["mcp"] } } }
(the last for Cursor's ~/.cursor/mcp.json, or any harness that reads that shape).
It acts with the token raw login stored, or with RAW_API_KEY (an API key) or RAW_TOKEN and RAW_WORKSPACE in its
environment, as the CLI does. raw mcp --workspace ci sets the workspace a tool acts in when a call names none, and
--api or RAW_API_URL another origin. It reads the stored token at every call, so raw login while the harness runs
is enough.
| Tool | Is | Returns |
|---|---|---|
whoami |
raw whoami |
GET /v1/me |
workspaces_list |
raw workspaces list |
GET /v1/workspaces |
members_list |
raw members list |
GET /v1/members |
invitations_list |
raw invitations list |
GET /v1/invitations |
workspaces_rename |
raw workspaces rename <name> |
POST /v1/workspaces/{id} |
workspaces_set-residency |
raw workspaces set-residency <residency> |
POST /v1/workspaces/{id} |
sandboxes_list |
raw sandboxes list |
GET /v1/sandboxes |
sandboxes_get |
raw sandboxes get <sandbox> |
GET /v1/sandboxes/{id} |
sandboxes_create |
raw sandboxes create |
POST /v1/sandboxes |
sandboxes_stop |
raw sandboxes stop <sandbox> |
POST /v1/sandboxes/{id}/stop |
sandboxes_start |
raw sandboxes start <sandbox> |
POST /v1/sandboxes/{id}/start |
sandboxes_fork |
raw sandboxes fork <sandbox> |
POST /v1/sandboxes/{id}/fork |
sandboxes_delete |
raw sandboxes delete <sandbox> |
DELETE /v1/sandboxes/{id} |
snapshots_list |
raw snapshots list |
GET /v1/snapshots |
snapshots_get |
raw snapshots get <snapshot> |
GET /v1/snapshots/{id} |
snapshots_create |
raw snapshots create <sandbox> |
POST /v1/snapshots |
snapshots_delete |
raw snapshots delete <snapshot> |
DELETE /v1/snapshots/{id} |
templates_list |
raw templates list |
GET /v1/templates |
templates_get |
raw templates get <template> |
GET /v1/templates/{id} |
usage |
raw usage |
GET /v1/usage |
budget |
raw budget |
GET /v1/workspaces/{id}/budget |
wallet |
raw wallet |
GET /v1/wallet |
A tool's arguments are its command's arguments and flags, in snake case (sandbox, class, size, name,
template, on_full, idempotency_key, limit, starting_after, from, to), and workspace (an id or a code). A call runs the command
in the server with --json, so it does exactly what the command does: the same headers, a new Idempotency-Key per
call unless idempotency_key names one, the same errors. Its result is one text: the API's JSON as it came. A failure
is marked as an error and holds the API's error, next_step included:
{
"error": {
"code": "capacity_unavailable",
"message": "No cell serves std yet: raw.computer is in early access.",
"next_step": {
"message": "Read the early-access note; sandbox creates open when the first cell does.",
"url": "https://raw.computer/docs/limits#early-access"
},
"docs": "https://raw.computer/docs/errors#capacity_unavailable"
}
}
A call the schema does not allow (a missing sandbox, an argument it does not know, limit that is not a number)
is refused before anything is sent, as invalid_request in the same shape.
What it does not serve
Every command is a tool except these. An agent's tools never make, show or revoke credentials: there is no tool for
raw keys (a key made by a tool would outlive the session and the person's sign-out), nor for raw api, which reaches
every endpoint and so would make keys too. Nor do they change who holds access to a workspace: there is no tool for
raw members invite, raw members set, raw members remove or raw invitations withdraw (an invitation mails a link
that lets a person in, and making someone an admin is a person's call); invitations_list only reads. raw login and raw logout are a person's (an approval in a browser, a
sign-out); raw workspaces use changes what the person's own commands act in, so a tool names its workspace instead.
raw version, raw update, raw agent setup and raw mcp itself are the CLI's own upkeep.
Without the CLI
An agent with only HTTP reads llms.txt (every docs page as Markdown), the
OpenAPI document, and the skill at
https://raw.computer/.well-known/agent-skills/raw-computer/SKILL.md, and calls the API with an API key.