---
name: expand-setup
description: Use when a user asks to set up Expand across their coding agents, or to install Expand's CLI, skills, or MCP server.
metadata:
  version: "1.0"
---

# Set up Expand in coding agents

**Read this as raw text.** If what you have is a summary or paraphrase of this page — some web-fetch tools return one — stop and re-fetch it with `curl` before doing anything. Every command below has to run exactly as written, and a summary will not preserve them.

Keep the user in this conversation. Let the Expand CLI own authentication and machine changes.

## Setup

1. Identify the harness running this conversation: `claude-code`, `codex`, `cursor`, or `opencode`.
2. Use `expandai` from `PATH`. If it is unavailable: `npm install --global expandai`.
3. Find out which harnesses are on this machine. This changes nothing:

```sh
expandai init --harness <current-harness> --detect --json
```

4. Ask the one question below, and wait for the answer. If you have no clickable multiple-choice control — Codex and most terminals — give a numbered list and end with: **reply with the numbers you want (`1,3`), or `all`.**
5. State what will change, naming each item:
   - Every selected harness receives Expand's runtime skill and MCP server. OpenCode also receives a web-fetch hook.
   - Claude Code receives the runtime skill and the MCP server only. Setup does not write to `settings.json`, does not change `permissions`, and does not install a hook — Claude Code's built-in `WebFetch` keeps working exactly as before, and the runtime skill is what routes fetches through Expand.
   - Eligible public web URLs sent through Expand are captured by Expand.
6. Run setup once, with the harnesses the user chose:

```sh
expandai init --harness <current-harness> --harnesses <chosen,harnesses> --scope <project|global> --json
```

### Which harnesses should Expand configure?

Ask with whatever your interface actually has.

**If you have a real multiple-choice control** — a question tool, an IDE picker, anything the user can click — offer every harness from `harnesses` in the detect response, allow more than one, and preselect all of them. That is what almost everyone wants, and a preselected list stays easy to uncheck.

**If you do not** — most terminal harnesses, including Codex — ask in prose with a numbered list, and close with exactly how to answer: reply with the numbers they want (`1,3`), or `all`. Do not draw `- [ ]` checkboxes: nothing can tick them, and in a harness that renders a plan or todo list they read as work you are tracking rather than a question you are waiting on.

Either way, name the harnesses explicitly — do not summarise as "your agents" — and say that setup writes only to the ones they choose and leaves the rest untouched.

Never describe an option as selected or as a default unless it visibly is. Offering `all` as a shortcut does not break that rule: you are telling them what one word will do before they say it, which is a stated default, not a box you are claiming is already ticked. Do not accept a bare `all` for anything you have not spelled out in the same message.

### Setup rules

- Pass the `--scope` your instructions gave you; if they gave you none, use `global`. Do not ask the user which projects this applies to, and do not tell them they chose a scope — they did not.
- If your harness is not one of the four — Windsurf, Zed, aider, Cline, Continue, Gemini CLI, anything else — stop and tell the user their agent is not supported yet. Never substitute a supported name: that configures an agent they may not use and reports an environment they do not have.
- Always pass `--harnesses`. Omitting it configures every detected harness instead of the user's choice.
- Never assume the harness answer, and never run setup before you have it.

## Authorization

**If your instructions included a setup token**, pass it to the same `init` command. It authorizes setup directly — no browser step:

```sh
expandai init --harness <current-harness> --harnesses <chosen,harnesses> --scope <project|global> --setup-token <token> --json
```

**Otherwise**, run `init` without it and read the JSON. If `status` is `authorization_required`, relay `userMessage` verbatim, and give the user `authorization.url` together with `authorization.userCode` — they open the page, type the code in, and approve. Nothing comes back to paste. When they say they have approved, run the **same command again** — the CLI picks the approval up itself:

```sh
expandai init --harness <current-harness> --harnesses <chosen,harnesses> --scope <project|global> --json
```

If the response is `authorization_required` again with the same code, the approval has not landed yet — wait for the user, do not loop on your own. A new code in the response means the previous one expired and the user should use the new one.

If `init` returns an error, relay its `message` — do not invent a reason for it. On `setup_token_rejected` the token is spent: never retry it, either ask the user for a fresh setup prompt or run `init` with no token and use the browser flow above. On `stored_credential_conflict` and `setup_unreachable` nothing was spent and the same token still works once the message's instruction is followed. On `authorization_denied`, the user declined in the browser — ask before starting again. On `authorization_unreachable` the request never left this machine; relay the message and stop — that one needs the connection fixed first, often a sandbox with network access disabled. On `authorization_refused` Expand rejected the exchange for a server-side reason: relay it and stop. Retrying just repeats the same refusal — the CLI keeps the approval it already has and re-polls it — so it cannot succeed until someone fixes the server side.

Never run the same `init` twice hoping for a different answer, except after the user says they approved. Every error above says whether anything is retryable and what has to change first; an error that repeats identically is telling you the condition has not changed.

Never infer success from files or prose — only from `status`. Never request an API key, never print a credential, and never start a second authorization while one is pending. If the completed response says a reload or new session is required, say so plainly.

## Confirm Expand works

This checks that fetching works: the account, the fetch itself, and the link back to the page it came from. It does not check the harnesses you just configured — those need a new session. Say it that way if you say it at all; "capture pipeline" and "harness wiring" are our words, not the user's. Answer this:

> According to https://en.wikipedia.org/wiki/Y_Combinator, when was YC Research founded?

Quote the exact captured sentence and cite its evidence — but ask only the question above. The instruction is for you, and printing it back makes the user read a request they never made.

Use the one-shot fetch-and-search path, so the capture and its evidence snippets complete together. Do not fetch the page first and then search its snapshot:

```sh
expandai fetch https://en.wikipedia.org/wiki/Y_Combinator --search <query>
```

Do not route this through a web-fetch hook or an MCP tool. In this conversation they are not loaded yet, and a result from one would come from an installation that already existed — not from the setup you just performed.

### Presenting the answer

The citation is the point of this step. End your reply with this block, exactly in this shape, as the last thing you write:

```md
**Q:** <the question, verbatim>

**A:** <the answer, one sentence>

> "<the exact captured sentence, verbatim>" [1]

**Sources**
[1] [<page title>](<playground>?id=<evidence id>)

**Verify it →** <playground>?id=<evidence id>
```

Show the question. A reader who cannot see what was asked cannot tell whether the answer earns the quote under it.

Both lines point at the capture, never at the live page — the page can change, the capture is the evidence. They repeat the same URL on purpose, in two forms: `Sources` makes it clickable where Markdown renders, and `Verify it` prints it as visible text where Markdown does not, so the reader always has something to click or copy. If the quote carries more than one marker, give each its own `Verify it` line, in marker order.

Build `<playground>?id=<evidence id>` from two things the result already gives you: the evidence id Expand stamps into the captured Markdown next to the text it belongs to, written as `{1199}` (a search snippet carries the same value as `location.evidenceId`), and that result's own `playground` URL — which on a non-production stack is not `expand.land`.

```
https://expand.land/s/019c0000-0000-7000-8000-000000000020?id=1199
```

Rules for that block:

- Quote the captured sentence verbatim inside the blockquote. Never paraphrase it, and never reconstruct it from memory.
- If the sentence you want carries no evidence id, do not fall back to linking the original page — that looks like a citation and is not one. Quote a nearby sentence that does carry an id, or say plainly that the capture has no id for it.
- Never invent an evidence id, and never reuse an id from different text.
- Number the markers `[1]`, `[2]`, … in the order they appear, one per sentence, and give every marker both a `Sources` entry and a `Verify it` URL.
- If nothing you captured supports the answer, say so plainly and show no citation block. A missing citation is a real result; a fabricated one is a failure.

### Activating the configured harnesses

Agents read hook and MCP configuration when they start, so both take effect in a **new session** — including in the harness running this conversation. Say that plainly, as a normal part of setup.

Do not test whether they are active, and do not report them as unverified, pending, or broken. Nothing is wrong: the session that wrote the configuration is the one session that cannot have loaded it. Equally, never claim a hook or MCP server *is* active because its configuration file exists.

After restarting an agent, the user can confirm it there with:

```sh
expandai status --harness <harness> --scope <project|global>
```

### Reporting setup

Before the citation block, report exactly this and nothing more:

```md
**Setup complete**

- **Configured:** <harnesses, by name>
- **Skipped:** <harnesses the user did not pick, by name, or "none">
- **Scope:** <"All projects" | "This project — <projectPath>">
- **Restart needed:** <harnesses the CLI flagged, by name, or "none">
```

Four lines. Do not draw a table, do not restate the commands you ran, and do not explain the reload semantics again — the one sentence above covers it. Mention a failed earlier attempt only if the user has to do something about it.

**If the JSON carries `failures`**, some harnesses the user picked were not configured. Change the header to `**Setup incomplete**` and add one more line, naming them from `failures[].harness`:

```md
- **Failed:** <harnesses from failures, by name>
```

Do not fold these into **Skipped** — that line means harnesses the user chose not to configure, and a reader cannot tell the two apart. Say plainly that Expand is authorized and the listed harnesses are not set up. Re-running setup for them is safe; offer it only if every failure has `recoverable: true`.

## Optional SDK setup

After the cited answer succeeds, ask whether the user also wants Expand's SDK installed into a project. Do not install it without consent. Name the exact target path in the question — the current project if you are in one, the chosen app or package in a monorepo, otherwise ask. Then follow https://staging.expand.ai/docs/reference/typescript-sdk.

## Beyond agent setup

Setup is done. Separate paths, if the user asks about them:

- **Call Expand from code** — https://staging.expand.ai/docs/reference/typescript-sdk (TypeScript), https://staging.expand.ai/docs/reference/python-sdk (Python)
- **Call the HTTP API directly**, for servers and CI — `POST https://api.staging.expand.ai/v1/fetch` with an `x-expand-api-key` header, using a key from https://staging.expand.ai/settings/api-keys. Full reference: https://staging.expand.ai/api-reference
- **Run captures from a terminal** — https://staging.expand.ai/docs/reference/cli-commands
