# @site-spy/mcp-server

> MCP server for Site Spy — lets AI agents monitor websites for changes

Latest version **0.3.1** (published 2026-09-22) · ISC license · 0 weekly downloads

## Install

```sh
npm install @site-spy/mcp-server
pnpm add @site-spy/mcp-server
yarn add @site-spy/mcp-server
bun add @site-spy/mcp-server
```

Provides the command `site-spy-mcp`.

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.3.1 |
| Published | 2026-09-22 |
| First published | 2026-02-25 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | ESM |
| Node | >=20.19 |
| Dependencies | 2 |
| Unpacked size | 74 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | site-spy |
| Keywords | mcp, model-context-protocol, site-spy, website-monitoring, ai-agents |

## Links

- npm: https://www.npmjs.com/package/@site-spy/mcp-server
- Homepage: https://docs.sitespy.app/docs/dashboard/mcp-integration
- npm.io page: https://npm.io/package/@site-spy/mcp-server

## Dependencies (2)

- [zod](https://npm.io/package/zod.md) ^4.5.4
- [@modelcontextprotocol/sdk](https://npm.io/package/@modelcontextprotocol/sdk.md) ^1.30.0

## Alternatives

- [pagerjs](https://npm.io/package/pagerjs.md) — 60 weekly downloads
- [whistle.savefor-mock](https://npm.io/package/whistle.savefor-mock.md) — 4 weekly downloads
- [auto-mock-data](https://npm.io/package/auto-mock-data.md) — 0 weekly downloads
- [@distube/youtube](https://npm.io/package/@distube/youtube.md) — 0 weekly downloads
- [@wcsjun/polymock](https://npm.io/package/@wcsjun/polymock.md) — 0 weekly downloads

## Recent versions

- 0.3.1 (latest) — 2026-09-22
- 0.3.0 — 2026-09-04
- 0.2.2 — 2026-05-13
- 0.2.1 — 2026-05-13
- 0.2.0 — 2026-05-07
- 0.1.1 — 2026-03-20
- 0.1.0 — 2026-03-20
- 0.0.5 — 2026-03-12
- 0.0.4 — 2026-03-11
- 0.0.3 — 2026-03-11
- 0.0.2 — 2026-03-10
- 0.0.1 — 2026-02-25

## README

# @site-spy/mcp-server

Let an AI agent watch web pages for you. This MCP server connects your assistant to
[Site Spy](https://sitespy.app): it can start monitoring a URL, tell you what changed
between two points in time, and fetch or search the web on demand.
Full docs at [docs.sitespy.app](https://docs.sitespy.app/docs/dashboard/mcp-integration).

## Install

Get an API key from [Settings → API](https://sitespy.app/dashboard/settings?tab=api).
Every plan, including the free one, can read and write — you are bounded by watch count
and daily requests, not by which tools you may call.

If your client has a CLI, this is the whole setup:

```bash
# Claude Code
claude mcp add site-spy --env SITE_SPY_API_KEY=your-key -- npx -y @site-spy/mcp-server

# Codex CLI
codex mcp add site-spy --env SITE_SPY_API_KEY=your-key -- npx -y @site-spy/mcp-server

# Gemini CLI  (the -- matters: without it, -y is parsed as a gemini flag)
gemini mcp add -s user -e SITE_SPY_API_KEY=your-key site-spy npx -- -y @site-spy/mcp-server

# OpenClaw
openclaw mcp add site-spy --command npx --arg -y --arg @site-spy/mcp-server \
  --env SITE_SPY_API_KEY=your-key

# VS Code
code --add-mcp '{"name":"site-spy","command":"npx","args":["-y","@site-spy/mcp-server"],"env":{"SITE_SPY_API_KEY":"your-key"}}'
```

Otherwise add this to your client's config file:

```json
{
  "mcpServers": {
    "site-spy": {
      "command": "npx",
      "args": ["-y", "@site-spy/mcp-server"],
      "env": {
        "SITE_SPY_API_KEY": "your-key"
      }
    }
  }
}
```

| Client         | Config file                                                                                                                 | Shape              |
| -------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| Claude Code    | `.mcp.json` (project) or `~/.claude.json`                                                                                   | as above           |
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json`<br>Windows: `%APPDATA%\Claude\claude_desktop_config.json` | as above           |
| Cursor         | `.cursor/mcp.json` or `~/.cursor/mcp.json`                                                                                  | as above           |
| Windsurf       | `~/.codeium/windsurf/mcp_config.json`                                                                                       | as above           |
| Gemini CLI     | `.gemini/settings.json` or `~/.gemini/settings.json`                                                                        | as above           |
| Codex CLI      | `~/.codex/config.toml`                                                                                                      | TOML, see below    |
| OpenCode       | `opencode.json` or `~/.config/opencode/opencode.json`                                                                       | differs, see below |
| OpenClaw       | `~/.openclaw/openclaw.json`                                                                                                 | differs, see below |
| VS Code        | `.vscode/mcp.json`                                                                                                          | differs, see below |
| Zed            | run the `zed: open settings file` action                                                                                    | differs, see below |

Restart the client afterwards; the tools appear on their own.

<details>
<summary>Clients whose config shape differs</summary>

**Codex CLI** — TOML, and the key is `mcp_servers`. The same file is read by the Codex
CLI, the ChatGPT desktop app, and the IDE extension.

```toml
[mcp_servers.site-spy]
command = "npx"
args = ["-y", "@site-spy/mcp-server"]

[mcp_servers.site-spy.env]
SITE_SPY_API_KEY = "your-key"
```

**OpenCode** — key is `mcp`, `command` is one array, and the env key is `environment`.

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "site-spy": {
      "type": "local",
      "command": ["npx", "-y", "@site-spy/mcp-server"],
      "enabled": true,
      "environment": { "SITE_SPY_API_KEY": "your-key" }
    }
  }
}
```

**OpenClaw** — servers nest under `mcp.servers`.

```json
{
  "mcp": {
    "servers": {
      "site-spy": {
        "command": "npx",
        "args": ["-y", "@site-spy/mcp-server"],
        "env": { "SITE_SPY_API_KEY": "your-key" },
        "enabled": true
      }
    }
  }
}
```

**VS Code** — key is `servers`, and `inputs` keeps the key out of the file.

```json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "site-spy-key",
      "description": "Site Spy API key",
      "password": true
    }
  ],
  "servers": {
    "site-spy": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@site-spy/mcp-server"],
      "env": { "SITE_SPY_API_KEY": "${input:site-spy-key}" }
    }
  }
}
```

**Zed** — key is `context_servers`.

```json
{
  "context_servers": {
    "site-spy": {
      "command": "npx",
      "args": ["-y", "@site-spy/mcp-server"],
      "env": { "SITE_SPY_API_KEY": "your-key" }
    }
  }
}
```

</details>

If you skip `SITE_SPY_API_KEY`, the agent asks you to authenticate interactively — but
that key lives in memory only and is gone when the server restarts.

## Tools

Read tools are annotated `readOnlyHint`, so most clients stop asking permission for them.

| Tool                 | Does                                               | Plan |
| -------------------- | -------------------------------------------------- | ---- |
| `list_watches`       | List monitored pages, with `limit` / `offset`      | all  |
| `get_watch`          | Full detail for one watch                          | all  |
| `search_watches`     | Find watches by URL or title                       | all  |
| `get_change_history` | Timestamps where a change was detected             | all  |
| `get_snapshot`       | The page as captured at one timestamp              | all  |
| `get_diff`           | What changed between two timestamps                | all  |
| `get_rss_settings`   | Current feed settings and token                    | all  |
| `get_notifications`  | Current notification settings                      | all  |
| `auth_status`        | Whether the server is connected                    | all  |
| `create_watch`       | Start monitoring a URL                             | all  |
| `update_watch`       | Rename, repoint, pause, change interval, mute      | all  |
| `delete_watch`       | Stop monitoring and drop the history               | all  |
| `trigger_recheck`    | Check everything now instead of on schedule        | all  |
| `authenticate`       | Supply an API key at runtime                       | all  |
| `generate_rss_token` | Mint a feed token — invalidates existing feed URLs | all  |
| `revoke_rss_token`   | Kill feed access immediately                       | all  |
| `fetch_url`          | Fetch one URL, with a browser backend for JS pages | all  |
| `web_search`         | Find URLs to fetch, instead of guessing them       | all  |
| `get_ai_summary`     | Plain-English summary of the latest change         | Pro  |

`get_snapshot` and `get_diff` cap output at 20,000 characters; pass `max_chars` for more.

Once a token exists, feed URLs are `https://sitespy.app/api/rss?token={token}` for
everything and `…/api/rss/watch/{uuid}?token={token}` for one watch.

## Environment variables

| Variable            | Description                    | Default                          |
| ------------------- | ------------------------------ | -------------------------------- |
| `SITE_SPY_API_KEY`  | API key                        | — (interactive auth)             |
| `SITE_SPY_API_URL`  | Backend API URL                | `https://api.sitespy.app/api/v1` |
| `SITE_SPY_AUTH_URL` | URL shown when a key is needed | `https://sitespy.app/dashboard`  |

Self-hosting: the backend `fetch_url` endpoint can be restricted with
`FETCH_URL_API_ENABLED`, `FETCH_URL_REQUIRE_MASTER_ADMIN`, or
`FETCH_URL_ALLOWED_API_KEYS`.

## Troubleshooting

- **"API key is invalid or expired"** — the key was revoked or regenerated. Copy a fresh
  one from Settings → API. The server itself is fine; there is no need to work around it.
- **Tools never appear** — restart the client after editing its config, and check `npx`
  runs (Node.js 20.19+).
- **"Watch limit reached"** — you are at your plan's cap. Delete one or upgrade.
- **"Rate limit reached"** — the day's write allowance is spent; the error says how long
  to wait. Reads do not count against it.
- **`fetch_url` keeps timing out** — pass `fetch_backend` explicitly. `html_requests` is
  fast and right for static pages; `impersonate` adds a real browser's TLS fingerprint
  at about the same cost; `html_webdriver` renders JavaScript; `flaresolverr` and
  `stealth_browser` are the anti-bot solvers. `auto` starts cheap, escalates only when
  the site blocks us, and gives up at 50s. On failure the response carries `attempts[]`
  and `cascade_summary` showing what was tried.

## Try it

- "Monitor https://example.com/pricing and tell me when the price changes"
- "What changed on my watches this week?"
- "Search for the current Postgres release notes and fetch the top result"

---
_Source: https://npm.io/package/@site-spy/mcp-server · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
