@site-spy/mcp-server
@site-spy/mcp-server
Let an AI agent watch web pages for you. This MCP server connects your assistant to Site Spy: 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.
Install
Get an API key from Settings → 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:
# 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:
{
"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.jsonWindows: %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.
Clients whose config shape differs
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.
[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.
{
"$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.
{
"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.
{
"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.
{
"context_servers": {
"site-spy": {
"command": "npx",
"args": ["-y", "@site-spy/mcp-server"],
"env": { "SITE_SPY_API_KEY": "your-key" }
}
}
}
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
npxruns (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_urlkeeps timing out — passfetch_backendexplicitly.html_requestsis fast and right for static pages;html_webdriverrenders JavaScript;flaresolverris for Cloudflare.autotries all three and gives up at 30s. On failure the response carriesattempts[]andcascade_summaryshowing 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"