# Claude Code

Give Claude Code a computer by adding the Sai MCP server.

The `@simular-ai/sai-mcp` server exposes Sai as MCP tools. Claude Code starts it over stdio and calls it like any other tool.

## Install

```bash
claude mcp add sai -e SAI_API_KEY=sapi_... -- npx -y @simular-ai/sai-mcp
```

Add `-s user` to make it available in every project. Requires Node.js 22.12 or newer.

## Verify

```bash
claude mcp list
```

`sai` should be listed as connected. Then, in a Claude Code session:

```
Use Sai to open Notepad, type hello, and save it to the desktop as hello.txt.
```

## Environment

| Variable         | Required | Notes                                                                                                   |
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `SAI_API_KEY`    | yes      | An `sapi_` key from [platform.simular.ai](https://platform.simular.ai).                                 |
| `SAI_API_URL`    | no       | Defaults to production. Set it to point at staging.                                                     |
| `SAI_PUSH`       | no       | Only for channels. See [Channels](/documentation/coding-agents/channels).                               |
| `SAI_LOCAL_VIEW` | no       | `0` turns off the local `watch_url` page. See [Watch Sai work](/documentation/coding-agents/live-view). |

## Tools

| Tool               | Input                                                    | Output                                                                   |
| ------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------ |
| `sai_machines`     | none                                                     | `{ machines: [{ machineId, name, kind, online }], default }`             |
| `sai_models`       | none                                                     | `{ models: [{ id, name, provider, tier, costTier, allowed }], default }` |
| `sai_task_start`   | `{ task, machine_id?, file_ids?, new_session?, model? }` | `{ session_id, machine_id, queued, push, task_id, watch_url? }`          |
| `sai_task_wait`    | `{ session_id, timeout_s?, cursor? }`                    | `{ status, events, text, approval?, usage?, sessionUsage?, cursor }`     |
| `sai_task_approve` | `{ approval_id, decision, selections? }`                 | `{ ok }`, or `{ ok: false, approval_url, reason: "link_only" }`          |
| `sai_task_abort`   | `{ session_id }`                                         | `{ ok }`                                                                 |
| `sai_upload`       | `{ path }`                                               | `{ file_id, name, mime, size }`                                          |

`usage` and `sessionUsage` are the task's and the session's model tokens and cost so far; see [Token usage](/documentation/api-reference/events#token-usage). `decision` is `approve`, `approve_for_task` or `deny`. `timeout_s` defaults to 90 and is capped at 110, under Claude Code's two-minute tool timeout. `model` is an id from `sai_models` or `auto`; it sticks to the session until changed, and the model only calls `sai_models` when you ask for a specific model.

## What the model does

The server's instructions describe the loop, so you do not have to prompt for it:

1. `sai_task_start` with the task.
2. `sai_task_wait` until `status` is not `running`.
3. On `needs_approval`: `sai_task_approve` when the approval can be answered, otherwise show `approval_url` to you and wait again.
4. On `idle`: report `text`.

There is no screenshot tool. Sai describes what it sees in `text` and progress events. To watch the screen yourself, open the `watch_url` link the agent gives you: see [Watch Sai work](/documentation/coding-agents/live-view).

## Gotchas

- One conversation per computer. Pass `new_session: true` to start clean.
- Files go through `sai_upload` first; then pass the returned `file_id` in `file_ids`.
- A free account's first task of the day can sit in `running` for about two minutes while the computer starts.
- If `sai_task_wait` times out, call it again with the returned `cursor`. The task keeps running.
- `sai_task_wait` retries a gateway `502`, `503` or `504` on its own, three times with a growing pause, before reporting an error. Other statuses come back at once.

## Optional: the sai skill

The package also ships a Claude Code skill that teaches the loop, and falls back to plain HTTP in a session where the MCP server is not loaded. Install it with:

```bash
npx -y @simular-ai/sai-mcp init-claude            # for you: ~/.claude/skills/sai
npx -y @simular-ai/sai-mcp init-claude --project  # for this repo: ./.claude/skills/sai
```

Re-run it after upgrading to refresh the skill. It never overwrites a `SKILL.md` you edited unless you pass `--force`.
