---
name: fats-setup
description: |
  Install, connect and verify fats (fatsearch.com): one local binary, a CLI and a stdio MCP server with one tool,
  that reads web pages and PDFs as short cached Markdown outlines for agents. Use when the user asks to install or
  set up fats / fatsearch, or wants this agent to read the web through it. Work autonomously: reuse an installed
  fats and any existing provider key, install the prebuilt release otherwise, connect it to the host you run in,
  and verify every layer before saying it is ready.
---

# Set up fats

`fats` 0.1.2 (2026-10-17). Full guide: https://fatsearch.com/docs/installation.md · source: https://github.com/fatsearch/fatsearch

Run this as one sequence: **preflight → install → keys → connect → verify → hand off**.

Rules for the whole run:

- Do every step from the terminal yourself. Ask the user only when you are truly blocked (a GUI app to restart,
  a permission you lack, a real choice such as which Bright Data zone), and then name only the blocker and the one action.
- Reuse what works. Never reinstall a working `fats`, never overwrite a saved key, never remove other MCP servers.
- Keys are secrets: never print, echo, log, commit or paste a key value, and never ask the user to paste one into
  the chat. Key *names* and `fats` status lines are enough.
- Use the prebuilt release, not a source build. Install for this user across all projects (user/global scope)
  unless the user asked for one project only.
- Do not edit shell startup files; the installer handles `PATH`.

## 1. Preflight

1. Note the OS and which agent host you are running in (Claude Code, Codex, Cursor, …). Configure only that host,
   or the hosts the user named.
2. `command -v fats` (Windows: `where fats`). If found, run `fats --version`: it prints `= fats <version> · …`.
   - 0.1.2 or newer: skip step 2.
   - Older: update it the way it was installed (`brew upgrade fatsearch`, `npm i -g fatsearch@latest`,
     or rerun the installer below).

## 2. Install (only if missing)

macOS, Linux:

```sh
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/fatsearch/fatsearch/releases/latest/download/fatsearch-installer.sh | sh
```

Windows (PowerShell):

```powershell
powershell -ExecutionPolicy Bypass -c "irm https://github.com/fatsearch/fatsearch/releases/latest/download/fatsearch-installer.ps1 | iex"
```

If the user prefers a package manager: `brew install fatsearch/tap/fatsearch` · `npm i -g fatsearch` · `cargo install --locked fatsearch`.

The installer puts `fats` in `~/.cargo/bin` (Windows `%USERPROFILE%\.cargo\bin`). If `command -v fats` still
finds nothing in this process, prepend that folder to `PATH` for this process only and check again.

Check: `fats --version` starts with `= fats `. From here on, **`<FATS>`** means the absolute path that
`command -v fats` prints. GUI hosts do not read the shell's `PATH`, so always register the absolute path.

## 3. Keys (optional, bring your own)

Without a key `fats` reads what a plain HTTP request gets, for $0. A key from **Oxylabs** or **Bright Data** adds
JS rendering, walled pages and web search, billed by that provider to the user. Look for keys the user already has;
do not ask for new ones.

1. `fats setup dry:true`: shows where each key was found (environment, `./.env`, the Bright Data CLI's login,
   the key dir), with no call and no write.
2. If it found a key: `fats setup`. It checks the key for $0 and saves it (mode 600) so every host can use it.
   If it lists several Bright Data zones, ask the user which one, then `fats setup zone:<name>`.
3. Found none: skip this step, carry on keyless. Do not stop setup over it.

Check: `fats | grep '^keys'` shows `oxy:file` and/or `bd:file` (or `keys none` when keyless).

## 4. Connect to the host

Skip if the host already lists a working `fats` server. Leave keys out of host configs (step 3 saved them).

| Host | Connect | Check |
|---|---|---|
| Claude Code | `claude mcp add --scope user fats -- "<FATS>" mcp` | `claude mcp get fats` shows it; in a running session, `/mcp` |
| Codex (CLI, app, IDE) | `codex mcp add fats -- "<FATS>" mcp` | `codex mcp list` |
| Gemini CLI | `gemini mcp add --scope user fats "<FATS>" mcp` | `/mcp` in the session |
| Cursor | `~/.cursor/mcp.json`: under `mcpServers` add `"fats": {"command": "<FATS>", "args": ["mcp"]}`, keeping every server already there | Cursor Settings → MCP lists `fats`; reload Cursor |
| VS Code (Copilot) | `code --add-mcp '{"name":"fats","command":"<FATS>","args":["mcp"]}'` | **MCP: List Servers** → fats |
| Windsurf | `~/.config/devin/mcp_config.json` (Windows `%APPDATA%\devin\mcp_config.json`): under `mcpServers` add `"fats": {"command": "<FATS>", "args": ["mcp"]}`, keeping every server already there | refresh MCP servers in Cascade |
| Zed | Zed `settings.json`: under `context_servers` add `"fats": {"command": "<FATS>", "args": ["mcp"]}`, keeping every server already there | Settings → AI → MCP Servers: the dot next to `fats` is green |
| Cline | `~/.cline/data/settings/cline_mcp_settings.json` (extension: MCP Servers → Configure): under `mcpServers` add `"fats": {"command": "<FATS>", "args": ["mcp"]}`, keeping every server already there | MCP Servers lists `fats` as connected |
| OpenCode | `~/.config/opencode/opencode.json`: under `mcp` add `"fats": {"type": "local", "command": ["<FATS>", "mcp"], "enabled": true}`, keeping what is there | `opencode mcp list` shows it connected |
| Claude Desktop | `claude_desktop_config.json` (macOS `~/Library/Application Support/Claude/`, Windows `%APPDATA%\Claude\`): under `mcpServers` add `"fats": {"command": "<FATS>", "args": ["mcp"]}`, keeping every server already there | quit Claude Desktop fully and start it again |
| pi, or any agent without MCP | skip MCP; add to the agent's global instructions file (pi: `~/.pi/agent/AGENTS.md`): "Read web pages with `fats <url>` (outline with section ids), then `fats u1#3` for one section, `fats u1 <words>` to filter. Run `fats guide` once for the full card." | the note is in the file |
| Any other MCP host | register a **stdio** server named `fats`: command `<FATS>`, args `["mcp"]` | the host lists `fats` with one tool, `fats` |

For config files: create the file if it does not exist, keep valid JSON, and do not touch other entries.
A host that must restart to load the server is **"connected; restart required"**, not ready.

## 5. Verify every layer

Check each layer on its own. One good fetch does not prove the host can call `fats`.

1. Binary: `fats --version` starts with `= fats `.
2. Fetch: `fats https://example.com`. The first line starts with `= ` and contains `Example Domain`.
3. MCP server, without any host:

   ```sh
   printf '%s\n' \
    '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"check","version":"0"}}}' \
    '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
    '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' | fats mcp
   ```

   The `tools/list` reply contains `"name":"fats"`.
4. Host: the check from the table in step 4.
5. Status: `fats` prints a `keys` row and `mcp: ready · fats mcp = stdio server, one tool fats(cmd)`.

Stop at the first failed check, show its output, and fix it before going on. Every `fats` error line starting
with `!` ends in `→` and the command that fixes it. Troubleshooting: https://fatsearch.com/docs/installation.md (section 9).

Report in this shape, nothing more:

```text
fats <version> installed
plain fetch verified
keys: <oxy / bd saved | none: plain pages only>
MCP server answers
<host>: connected | connected; restart required
```

If no key was found, add one line: a key from https://dashboard.oxylabs.io/en/registration or
https://brightdata.com/cp/start adds JS pages, walled pages and search; put it in the environment and run `fats setup`.

## 6. Hand off into useful work

Do not end on a demo. If this conversation already has a task that needs the web, go back to it now using `fats`.
Otherwise ask exactly one question:

```text
fats is ready. What next?

1. Read a page or PDF with me now: paste a URL.
2. Search the web: tell me what to look for.
3. Add a provider key for JS-heavy or walled pages.

Reply with 1, 2, or 3.
```

If the user replies with a bare number, go straight on without repeating the menu.

Using fats (over MCP, pass the same text to the `fats` tool as `cmd`):

```sh
fats https://example.com     # outline with section ids, cached as u1
fats u1#3                    # read section 3
fats u1 price                # only the lines that match, inside the page
fats u1 links                # numbered links; fats l4 follows one
fats rust async runtime      # web search (needs a provider key)
fats ./report.pdf            # a local PDF, one section per page
fats guide                   # the one-screen cheat sheet
```
