# kosa8 Cloud MCP server

kosa8 Cloud has a remote MCP server at `https://api.kosa8.com/mcp`. Connect your AI agent to it with your Cloud API key and it can create sealed cloud sandboxes, run commands in them, put them to sleep and delete them, with nothing installed on your machine.

You need a kosa8 Cloud API key ([kosa8 Cloud](https://docs.kosa8.com/guides/cloud/) shows how to get one). Give the agent its own key with the `sandboxes:write` scope, so you can revoke it without touching your other keys. Then put it in your shell:

```
$ export KOSA8_API_KEY=k8c_live_…
```

## Claude Code

```
$ claude mcp add --transport http --scope user kosa8-cloud https://api.kosa8.com/mcp --header "Authorization: Bearer $KOSA8_API_KEY"
```

The shell fills in the key, so Claude Code stores the key itself. `--scope user` makes it available in every project; leave it out to add it to this project only. Check it with `claude mcp list`, or `/mcp` inside Claude Code.

## Cursor

Add this to `~/.cursor/mcp.json` (every project) or `.cursor/mcp.json` in one project. Cursor fills in `${env:KOSA8_API_KEY}` from its environment, so the key is not written into the file:

```
{
  "mcpServers": {
    "kosa8-cloud": {
      "url": "https://api.kosa8.com/mcp",
      "headers": { "Authorization": "Bearer ${env:KOSA8_API_KEY}" }
    }
  }
}
```

Cursor has to see the variable: on macOS an app opened from the Dock does not get your shell's variables, so start Cursor from a terminal where it is set, or put the key itself in the file with `kosa8 cloud mcp --install cursor` (below).

## Codex

Add this to `~/.codex/config.toml`. Codex sends the key it reads from `KOSA8_API_KEY` as the bearer token:

```
[mcp_servers.kosa8-cloud]
url = "https://api.kosa8.com/mcp"
bearer_token_env_var = "KOSA8_API_KEY"
```

## Any other MCP client

The server speaks the MCP **Streamable HTTP** transport (protocol versions 2025-03-26, 2025-06-18 and 2025-11-25). Point the client at:

| URL | `https://api.kosa8.com/mcp` |
|---|---|
| Header | `Authorization: Bearer k8c_live_…` |

A client that only starts local (stdio) servers, such as Claude Desktop's config file, can reach it through the `mcp-remote` bridge (needs Node.js):

```
{
  "mcpServers": {
    "kosa8-cloud": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://api.kosa8.com/mcp", "--header", "Authorization:${KOSA8_AUTH_HEADER}"],
      "env": { "KOSA8_AUTH_HEADER": "Bearer k8c_live_…" }
    }
  }
}
```

## Or let the kosa8 CLI do it

Signed in with `kosa8 cloud login`, the CLI prints every snippet above for your key, and writes them only when you ask:

```
$ kosa8 cloud mcp                        # print the config for each client; writes nothing
$ kosa8 cloud mcp cursor --show-key      # Cursor's, with the key itself in it
$ kosa8 cloud mcp --install claude-code  # or cursor, codex; none named: every one found
$ kosa8 cloud mcp --uninstall cursor
```

`--install` keeps the client's other servers and saves the old file as `.bak`. Cursor's file gets the key and is made readable only by you; Codex's gets only the variable name. The server is named `kosa8-cloud`, so it sits beside the local `kosa8` server from `kosa8 mcp install` ([Connect Claude, Cursor or Codex](https://docs.kosa8.com/guides/connect-agents/)), which runs sandboxes on your own machine.

## Tools

| Tool | Does | Scope |
|---|---|---|
| `sandbox_create` | Start a sandbox: `template`, `region`, `sleep_after_s`, `ttl_s`, all optional. | `sandboxes:write` |
| `sandbox_list` | The organization's sandboxes, their state and cost so far. | `sandboxes:read` |
| `sandbox_exec` | Run `argv` (exact arguments) or `command` (a shell line, run with `sh -c`), with optional `env`. Returns the exit code, stdout and stderr. A sleeping sandbox wakes first; `/workspace` persists between commands. | `sandboxes:write` |
| `sandbox_sleep` | Snapshot it and free its RAM; it then costs only snapshot storage. | `sandboxes:write` |
| `sandbox_wake` | Restore a sleeping sandbox now. | `sandboxes:write` |
| `sandbox_delete` | Delete it and everything in it. | `sandboxes:write` |
| `usage_get` | This month's bill so far, the spending cap, and whether new work is paused. | `sandboxes:read` |
| `templates_list` | The templates you can create now. | `sandboxes:read` |

The agent sees only the tools its key's scopes allow: a `sandboxes:read` key gets the three read tools. Output longer than 100 KB per stream is cut, with a note saying how much.

## Same rules as the API

Each tool runs the same code as its REST call, so everything that applies to the API applies here: the key's scopes, payment, your spending cap, the sandbox quota, and the audit log. Each call appears in **Audit** with `via: mcp`; an exec records its arguments, the names of its environment variables and its exit code, never its output or variable values.

When kosa8 Cloud refuses something, the agent gets a tool error it can read, not a broken connection. A **402** (`payment_required` or `spending_cap_reached`) includes a sentence meant for you and the page that fixes it, for example:

```
kosa8 Cloud refused this (HTTP 402 payment_required): add a payment method to start running work; …
Tell the person: kosa8 Cloud needs a payment method or credit to run more work. Ask the person to open https://app.kosa8.com/#usage
upgrade_url: https://app.kosa8.com/#usage
```

The server tells agents to pass that on and stop, rather than retry.

## Details

- Stateless: each `POST /mcp` carries one JSON-RPC 2.0 message (or a batch) and is answered with `application/json`. There is no session id and no event stream, so `GET` and `DELETE` return 405.

- Only a bearer API key is accepted, never the dashboard's sign-in cookie. A missing or revoked key is HTTP 401.

Try it by hand:

```
curl -s https://api.kosa8.com/mcp -H "Authorization: Bearer $KOSA8_API_KEY" \
  -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
```

---
Source: https://docs.kosa8.com/guides/cloud-mcp/
