---
name: wack
version: 3
description: Connects you to your human's wack boxes, persistent Linux computers for agents with office, PDF, data and browser tools preinstalled. Use it when your human gives you a wack connect URL, or for jobs that are too big, too long, too parallel or too file-heavy for the machine you are on.
---

# wack: set up your human's boxes

This file is for you, the agent. Read it once, top to bottom.

A **box** is a private Linux computer that belongs to your human. It keeps its files between
sessions, sleeps when idle and wakes in about a second when you call it. You are root inside.
You reach boxes through an MCP server.

## 1. Get the connect URL

Your human's message should contain a connect URL. There are two kinds:

- **Account URL**, `https://api.wack.sh/mcp/wac_…`: all of your human's boxes. You can list them, make
  new ones and delete the ones you made. Fourteen tools: `box_docs`, `box_list`, `box_create`,
  `box_delete`, `box_start`, `box_stop`, `box_exec`, `box_upload`, `box_download`,
  `box_screenshot`, `box_setup`, `box_screen`, `box_image_save` and `box_image_delete`. Every
  tool that works on a box takes `box`: its id (`box_…`) or exact name.
- **Box URL**, `https://api.wack.sh/mcp/wbx_…`: one box only. The same tools without `box_create`,
  `box_delete` and the image tools, and no `box` argument: every call goes to that box.

If there is no URL, ask for it: the account URL is at https://wack.sh/connect (and under
Settings › Connection), a box URL in that box's Settings tab. Do not guess or invent one.

**The URL is a password.** Anyone who has it can use the boxes it reaches.
Never print it back in full, never put it in a file inside a box, and never paste it anywhere
except your client's MCP settings. When you refer to it, say "your connect URL".

Below, `<connect URL>` stands for the URL.

## 2. Add the server to your client

Use the section for the client you are running in. **Merge into existing config; never overwrite
a file that already lists other servers.** If a `wack` entry already exists, replace only that entry.

### Claude Code

```bash
claude mcp add --transport http --scope user wack <connect URL>
```

`--scope user` makes it available in every project. If `wack` already exists, run
`claude mcp remove wack --scope user` first. Your human then restarts Claude Code (or runs `/mcp`).

### Codex

Add this table to `~/.codex/config.toml`, keeping everything else in the file:

```toml
[mcp_servers.wack]
url = "<connect URL>"
tool_timeout_sec = 900
```

`tool_timeout_sec = 900` matters: Codex stops tool calls after 60 seconds by default, and box
commands may run for up to 900. Restart Codex afterwards.

### Cursor

Add the `wack` entry under `mcpServers` in `~/.cursor/mcp.json` (create the file if needed):

```json
{
  "mcpServers": {
    "wack": {
      "url": "<connect URL>"
    }
  }
}
```

Your human can also click **Add to Cursor** on their dashboard instead.

### Claude (desktop, web and mobile)

Claude adds remote servers as custom connectors, and your human does it in the app:

1. In Claude, open Customize › Connectors.
2. Click Add custom connector, name it wack and paste the URL.
3. If Claude asks how people sign in, choose No sign-in. Then click Add.

On Team and Enterprise plans an owner adds it under Organization settings › Connectors
(Add › Custom › Web); members then click Connect. Walk your human through these steps; do not
edit Claude's config files.

### VS Code

```bash
code --add-mcp '{"name":"wack","type":"http","url":"<connect URL>"}'
```

Or add it to `.vscode/mcp.json` (the key is `servers`, not `mcpServers`):

```json
{
  "servers": {
    "wack": {
      "type": "http",
      "url": "<connect URL>"
    }
  }
}
```

### Other MCP clients

The server speaks streamable HTTP at the connect URL, with no headers and no sign-in. The field
name depends on the client:

- Gemini CLI, in `~/.gemini/settings.json` (timeout in milliseconds):

  ```json
  {
    "mcpServers": {
      "wack": {
        "httpUrl": "<connect URL>",
        "timeout": 900000
      }
    }
  }
  ```

- Windsurf (Devin Desktop), in its `mcp_config.json`:

  ```json
  {
    "mcpServers": {
      "wack": {
        "serverUrl": "<connect URL>"
      }
    }
  }
  ```

- Clients that ask for a transport type: `http` or `streamable-http`.
- Clients that only run local (stdio) servers can use a bridge:

  ```bash
  npx -y mcp-remote <connect URL>
  ```

## 3. Verify before you say it works

A written config file proves nothing. Do all of these, in order:

1. Make sure the wack tools are available to you (restart or reload the client if they are not).
2. Call `box_docs` and read the manual it returns. It explains paths and rules.
3. With an account URL, call `box_list` and pick a box for the next step. If there is none, make
   one with `box_create`.
4. Call `box_exec` (with `box` set to that box, for an account URL) with
   `soffice --version && python3 -c "import pandas; print(pandas.__version__)"`.
   Expect `exit=0`, a LibreOffice version line and a pandas version.
5. Tell your human wack is connected and quote both versions.

If a step fails, say which step and what it returned. Do not retry blindly.

## 4. More than one box (account URL)

- **Reuse before you create.** Check `box_list` first. A box your human already set up may hold
  the files, logins and tools the job needs.
- **Make extra boxes for parallel work.** Split a job that has independent parts (several repos
  to test, a batch of documents, experiments that must not touch each other) across boxes and
  run them side by side. `box_create` returns once the new box is set up and awake. Give each
  box a `name` that says what it is for.
- **Make throwaway boxes ephemeral.** Pass `ephemeral: true` and the box deletes itself, with
  everything on its disk, the first time it goes to sleep: after 10 idle minutes or on
  `box_stop`. Copy results out first, to a lasting box or with `box_download`. Leave `ephemeral`
  off for boxes meant to last.
- **Bigger boxes, a screen and setups.** `box_create` takes a `size`, `screen: true` for a
  virtual display (then run headed browsers on `DISPLAY=:0`; your human can watch), a saved
  `image` to start from, and a `setup` recipe (packages, a Chrome version, private repos, fonts).
  The manual from `box_docs` has the details. Choosing:
  - Most work: an existing box from `box_list`, or the defaults (standard size, no screen).
  - Dev servers, big builds, test suites, several browsers: `size: "large"` (`"xl"` for the
    heaviest).
  - Headed browsers, canvas/WebGL, clicking through an app, your human watching: `screen: true`.
    A quick picture of one page needs no screen: use `box_screenshot`.
  - The same environment every time, or A/B comparisons: start from one saved `image`.
  - Bigger sizes and screens use more of your human's awake hours; ask for them only when the job
    needs them.

  For example, a box for A/B pixel tests of a web canvas:

  ```json
  box_create {
    "name": "canvas-ab",
    "size": "large",
    "screen": true,
    "setup": {
      "chrome": "153",
      "repos": [{ "url": "https://github.com/org/repo" }],
      "fonts": { "packs": ["inter"] }
    }
  }
  ```

  Then `box_image_save` it, and start both the A and the B box from that image so they share the
  same Chrome build, fonts and screen. Standard, large and XL boxes have no GPU (Chrome draws on
  the CPU), so compare box to box: a box's pixels and timings won't match a Mac's. For GPU work
  only (hardware WebGL/WebGPU, CUDA, ML), use `size: "gpu"` and compare GPU box to GPU box.
- **Clean up.** Delete boxes you made and no longer need with `box_delete`. It cannot be undone,
  so never delete a box you did not make unless your human asks.
- **Limits.** Your human's plan caps how many boxes the account has and how many are awake at
  once. When a tool says a limit is reached, put a box you made to sleep, delete one you no
  longer need or ask your human to upgrade; do not retry in a loop. wack never stops or deletes
  a box to make room. (A local development server started with
  `WACK_UNLIMITED=1` lifts every plan cap for testing; production never does.)

## 5. Rules of the box

1. **Verify artifacts, not exit codes.** After every generation step run
   `test -s out.pdf && file out.pdf` before calling it done.
2. **Deliverables go to `/mnt/user-data/outputs`.** Files there appear on your human's dashboard.
3. **Use `uv`, not `pip`.** `pip install` is blocked by PEP 668. Use `uv run --with <pkg>` for
   one-off scripts, or `uv pip install --system --break-system-packages <pkg>`.
4. **Budget per command: 300 seconds by default, 900 at most** (`timeout_seconds`). Run longer
   jobs in the background with their log in outputs, and poll at least every few minutes: the box
   sleeps after 10 minutes without a call, which pauses background jobs until it wakes.
5. **Secrets set in Toolhouse are not in `box_exec`.** They go to automations and cloud sessions
   only. Ask your human if a job needs a key, and never print secrets.
6. **`box_upload` takes up to 10 MiB and `box_download` returns up to 5 MiB.** For bigger files,
   let the box fetch them itself, or point your human to the dashboard.
7. **`box_stop` is optional.** Boxes sleep on their own after 10 idle minutes and keep their
   files. An ephemeral box is deleted instead.

## 6. Troubleshooting

- **HTTP 403, "This connect URL is no longer valid":** your human rotated the URL. Ask for the
  current one (https://wack.sh/connect for the account URL, the box's Settings for a box URL) and
  replace the old entry.
- **A tool says `box` is required or the box was not found:** you are on an account URL. Call
  `box_list` and pass a box's id or exact name.
- **Codex says a tool call timed out after about 60 seconds:** `tool_timeout_sec = 900` is missing
  from the `[mcp_servers.wack]` table.
- **The client asks you to sign in or starts an OAuth flow:** the server needs no sign-in. Remove
  the entry and add it again as a plain URL (in Claude, choose No sign-in).
- **A tool says the trial has ended or hours are used up:** relay that message to your human; it
  includes the link to fix it.
- **The tools don't appear after adding the server:** the client has not reloaded its config.
  Restart it fully.
