---
title: WatchFor MCP server for AI agents
description: Connect AI agents (Claude, Cursor, VS Code, any MCP client) to WatchFor — 59 tools, reference resources and prompt templates over the same API.
canonical: https://watchfor.io/docs/api/mcp
---

# WatchFor MCP server for AI agents

Connect AI agents (Claude, Cursor, VS Code, any MCP client) to WatchFor — 59 tools, reference resources and prompt templates over the same API.

WatchFor ships a built-in [MCP](https://modelcontextprotocol.io) (Model
Context Protocol) server, so AI agents can watch your infrastructure,
investigate incidents and manage monitors through natural language. It
exposes **59 tools**, four read-only **resources** and three **prompt
templates**, all backed by the [REST API](/docs/api) — the same
credentials, scopes, validation and per-plan rate limits apply, so the
MCP surface can never behave differently from the API.

**Endpoint:** `https://watchfor.io/api/mcp` — Streamable HTTP
**Manifest:** [`/.well-known/mcp.json`](https://watchfor.io/.well-known/mcp.json) ·
**Server card:** [`/api/mcp/server-card`](https://watchfor.io/api/mcp/server-card) (also at [`/.well-known/mcp/server-card.json`](https://watchfor.io/.well-known/mcp/server-card.json))

## Authentication

Two ways, both described in [Authentication](/docs/api/authentication):

- **OAuth 2.1** — clients that implement the MCP authorization spec
  (claude.ai connectors, Claude Code and most current clients) connect
  with **no key at all**: add the server, your browser
  opens a WatchFor consent screen, approve, done. The scopes you grant
  (`read` / `write`) bound what the AI agent can do. The server advertises
  its authorization server on every `401` via `WWW-Authenticate`.
  The consent screen names the application and says where your browser
  will be sent after approving; clients WatchFor does not recognise are
  marked **not verified**, so only approve a request you started yourself
  from an app you trust. Everything you have approved is listed under
  **Account settings → Security → Connected apps**, where one click
  revokes an app's access.
- **API key** — put `Authorization: Bearer wf_live_…` in the client's
  header configuration. A `read` key allows only the read tools; `write`
  enables creating and changing monitors, alert rules, contacts,
  maintenance windows, report emails and incident actions.

Discovery is anonymous: `initialize`, `ping`, `tools/list`,
`resources/list`, `resources/read`, `prompts/list` and `prompts/get` work
without any credential, so a client (or a registry scanner) can inspect
the server before you have configured anything. Only `tools/call`
touches your account and needs a credential — an unauthenticated
`tools/call` returns HTTP `401` with the OAuth hint.

## Connect a client

### Claude (claude.ai connectors)

Settings → Connectors → Add custom connector →
`https://watchfor.io/api/mcp`. Claude discovers the OAuth server and
walks you through the consent screen — no API key needed.

### Claude Code

```bash
# OAuth (no key) — run /mcp afterwards and authenticate in the browser:
claude mcp add --transport http watchfor https://watchfor.io/api/mcp

# or with an API key:
claude mcp add --transport http watchfor https://watchfor.io/api/mcp \
  --header "Authorization: Bearer wf_live_YOUR_KEY"
```

### Cursor, VS Code and other JSON-config clients

```json
{
  "mcpServers": {
    "watchfor": {
      "url": "https://watchfor.io/api/mcp",
      "headers": {
        "Authorization": "Bearer wf_live_YOUR_KEY"
      }
    }
  }
}
```

Clients that support remote OAuth can omit `headers` and authorize
interactively instead.

### Claude Desktop (via mcp-remote)

Claude Desktop's config file takes stdio servers — bridge with
[`mcp-remote`](https://www.npmjs.com/package/mcp-remote):

```json
{
  "mcpServers": {
    "watchfor": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://watchfor.io/api/mcp",
        "--header",
        "Authorization: Bearer wf_live_YOUR_KEY"
      ]
    }
  }
}
```

### Smithery

The server is listed in the [Smithery](https://smithery.ai) registry at
[smithery.ai/servers/hello-65wl/watchfor](https://smithery.ai/servers/hello-65wl/watchfor);
Smithery-based clients can add it from there. The endpoint is the same
`https://watchfor.io/api/mcp`.

### Agent skills

For AI agents that load skills rather than raw tools, WatchFor publishes
three SKILL.md files (`watchfor-monitoring`,
`watchfor-incident-response`, `watchfor-reliability-reports`) at
[`/.well-known/agent-skills/index.json`](https://watchfor.io/.well-known/agent-skills/index.json)
and in the [agent-toolkit repo](https://github.com/watchfor-io/agent-toolkit)
(`npx skills add watchfor-io/agent-toolkit`).

## Tools

Every tool wraps one or two REST calls with the same names and
semantics; validation errors return the allowed values so AI agents can
self-correct. Tool annotations mark `get_*`/`list_*` as read-only,
`delete_*` and `reset_*` as destructive, and `get_/list_/set_/update_/delete_` as
idempotent.

### Organization

| Tool | Scope | What it does |
| --- | --- | --- |
| `get_summary` | read | One-call organization snapshot: monitor status counts (up/degraded/down/paused/unknown + health score), active incident counts and open maintenance windows. Start here for "how is my infrastructure right now?" |
| `get_incident_stats` | read | Aggregate incident statistics over `24h`, `7d`, `30d` or `90d`: totals by severity, MTTR, MTBF and the five most unstable monitors |
| `get_report` | read | Org report for a period vs the previous equal-length period: uptime, incidents, MTTR/MTBF, downtime, response-time trend, per-monitor rows, type-aware sections and plain-language insights — the same engine as the dashboard Reports page |
| `get_report_schedules` | read | The two report-email cadences (weekly + monthly): enabled state, recipients and any who unsubscribed |
| `set_report_schedule` | write | Enable/disable the weekly or monthly report email and/or replace its recipients (up to 5) |
| `get_plan` | read | Current plan with limits (`-1` unlimited, `0` off) and live usage counts |

### Monitors

| Tool | Scope | What it does |
| --- | --- | --- |
| `list_monitors` | read | List monitors (cursor-paginated, slim items); filter by type, status (`up`, `degraded`, `down`, `paused`, `unknown`), tag or search name/target with `q` |
| `get_monitor` | read | One monitor by id, including config and `available_metrics` (the alert metrics valid for its type) |
| `get_monitor_types` | read | Discovery catalog of all 30 monitor types: target format, default rules, exact alert-metric strings, operators, config fields. Consult before creating monitors or rules. Type `playwright` = browser checks (Playwright journeys); type `browser` = Core Web Vitals (Lighthouse) |
| `create_monitor` | write | Create a monitor; location ids from `list_locations`, target/config per `get_monitor_types`; interval validated against the plan minimum; `config` validated per type (`400` names the key). Name up to 50 characters, up to 10 tags, optional `description`. `locations` is optional: heartbeat monitors take none, and `cloneFromMonitorId` copies an existing monitor of the same type (rules + config; omitted fields default to the source's) |
| `update_monitor` | write | Update fields; send only what changes. `config` is a true partial: omitted keys are kept, `null` removes a key, arrays and objects you send replace the stored value whole; `description: null` clears it |
| `set_monitor_paused` | write | Pause (`paused: true`) or resume a monitor; idempotent |
| `delete_monitor` | write | Permanently delete a monitor with its alert rules and open incidents — the description tells AI agents to confirm with you first |
| `run_check_now` | write | Dispatch an immediate check (plan-limited per hour); the result lands in `get_monitor_checks` shortly |
| `reset_monitor_history` | write | **Irreversible.** Delete everything a monitor recorded — every check, every incident with its notes, post-mortems and status-page copies, and the alerting counters — and start uptime over ("since reset"). The monitor keeps its configuration, alert rules, tags and locations; the description tells AI agents to confirm with you first |
| `get_integrity_baseline` | read | Page integrity monitors: the accepted baseline of every watched page — whether it has one, when and how it was captured (first check, dashboard, API or auto-accept timer), trusted sources and the text-change threshold |
| `accept_integrity_baseline` | write | Page integrity monitors: accept what the newest check saw as the new baseline — all pages or only `pages` — after an intended change such as a deploy; `fresh: true` checks the pages first and accepts that check; open integrity incidents resolve at once when nothing else differs; pages a check could not fetch come back in `skipped` |
| `get_monitor_uptime` | read | Uptime percentage and check totals over `1h`–`90d`, maintenance excluded |
| `get_monitor_checks` | read | Recent check results with per-location performance; `success=false` fetches only failed checks; `hours` up to 720 |
| `list_locations` | read | Probe locations — the ids for `create_monitor` |

### Alert rules

| Tool | Scope | What it does |
| --- | --- | --- |
| `list_alert_rules` | read | A monitor's alert rules (system defaults + custom) |
| `create_alert_rule` | write | Create a rule; `metric` must come from the type catalog, `value` is a string; one rule per metric per severity |
| `update_alert_rule` | write | Fix a noisy threshold, change severity, or enable/disable; fields are validated against the catalog |
| `delete_alert_rule` | write | Delete a custom rule (system rules cannot be deleted — disable them instead) |

### Incidents

| Tool | Scope | What it does |
| --- | --- | --- |
| `list_incidents` | read | Incidents newest first; filter by status, severity, monitor and a `since`/`until` range; each carries the rule that fired and `duration_seconds` |
| `get_incident` | read | Full detail of one incident |
| `acknowledge_incident` | write | Acknowledge a firing incident — pauses repeat notifications while someone investigates |
| `resolve_incident` | write | Manually resolve; accepted asynchronously, re-fires if the problem persists |
| `set_incident_uptime_exclusion` | write | Mark a **resolved** incident as a false positive (`excluded: true`, optional `reason`) or undo it (`excluded: false`). Excluded incidents stay on record but are left out of uptime, SLA, reports and the public status page; excluding an open incident fails with `409` |

### Contacts & groups

| Tool | Scope | What it does |
| --- | --- | --- |
| `list_contacts` | read | Alert recipients with their group memberships ("who gets notified?") |
| `get_contact` | read | One contact: name, email, phone, groups |
| `create_contact` | write | Create a recipient, optionally straight into groups |
| `update_contact` | write | Update a contact; `group_ids` replaces all memberships |
| `delete_contact` | write | Delete a contact (irreversible) |
| `list_contact_groups` | read | Notification groups — where alerts are delivered |
| `get_contact_group` | read | One group including its member list |
| `create_contact_group` | write | Create a group, optionally with initial members |
| `update_contact_group` | write | Update a group; `contact_ids` replaces the full member list |
| `delete_contact_group` | write | Delete a group (the default group cannot be deleted; a group still used by alert rules, monitors or channels is refused — remove the references first, or use `DELETE /v1/contact-groups/{id}?force=true`) |

### Maintenance, notifications & audit

| Tool | Scope | What it does |
| --- | --- | --- |
| `get_check_details` | read | Everything the probe saw on one check run (headers, timings, TLS, DNS answers, assertions), redacted like the dashboard's probe-result view |
| `list_status_pages` | read | The org's status pages with what each says right now |
| `get_status_page` | read | One page: `overall_status`, components with status and the monitors and hosts behind them, third-party mirrors |
| `list_announcements` | read | Announcements on a page with their update timeline and schedule |
| `get_on_call` | read | Who is on call, until when, who is next, layers, overrides, reachability |
| `list_notification_channels` | read | Alert delivery channels with type, routes and a redacted config |
| `list_hosts` | read | Servers running watchfor-agent: liveness (online / stale / offline / never) and current CPU, memory, disk; `status` filter |
| `get_host` | read | One host — OS, agent version, hardware, addresses, gauges, `monitor_id` |
| `get_host_metrics` | read | Metric time series for a host over 1h–30d (`cpu.usage_pct`, `mem.used_pct`, `disk.used_pct`, …) |
| `list_maintenance_windows` | read | Scheduled maintenance windows, most recent first |
| `create_maintenance_window` | write | Schedule a window — alerts suppressed and downtime excluded for the covered monitors; ISO 8601 start, duration in minutes, monitors by id or tag |
| `delete_maintenance_window` | write | Cancel a window — removes future occurrences and lifts active silences |
| `list_notifications` | read | Alerting delivery history — every notification attempt with channel, status (sent/failed/silenced), severity, incident and monitor |
| `list_activity` | read | The organization audit trail — who changed what and when, with free-text search and entity/time filters |

### Live diagnostics

Three tools that **measure right now** from the probe fleet instead of
reading what WatchFor already recorded — and they work on targets you do
not monitor. Full reference: [Live diagnostics](/docs/api/diagnostics).

| Tool | Scope | What it does |
| --- | --- | --- |
| `list_diagnostics` | read | Catalog of the 24 live checks, the question each answers, its exact option names, and this organization's remaining allowance for each. Call it before a long investigation to see the budget |
| `run_diagnostic` | write | Run one check (`tool` + `target` + optional `options` and `location_id`): DNS, DNS propagation, whois/RDAP, ping, traceroute, TCP port, blacklists, SSL, TLS grade, MCP handshake, HTTP headers, API request, CDN, sitemap, Brotli, email policy, DNS health, mail servers, Core Web Vitals or a full site audit. Graded checks return a `grade` (the dashboard's A+ to F letter, its rules version (`rubric`) and the findings that cap it, with fixes). The tool description enumerates every slug with its question, so no discovery round-trip is needed |
| `diagnose_target` | write | Investigate a host or URL in ONE call — DNS, propagation, TLS grade, HTTP headers and ping from up to 3 regions in parallel — returned as one verdict with a status per check, a machine-readable findings list and the TLS and security headers grades. Needs a plan with location selection |

A check that ran and found a problem (closed port, `NXDOMAIN`, failed
handshake) returns normally with `success: false` — that is the answer,
not an error. Each run spends the same per-plan allowance the dashboard
Toolbox uses, and every response carries `remaining` so a model can pace
itself.

### Browser checks

Three tools for [browser checks](/docs/monitors/browser-checks) — Playwright
scripts run in a sandboxed browser. The agent recipe is on
[Browser checks with an agent](/docs/monitors/browser-checks/agents).

| Tool | Scope | What it does |
| --- | --- | --- |
| `test_playwright_script` | write | Run a Playwright Test script once without saving it (`script`, `target`, optional `location_id` and `timeout_seconds`). A script error returns `400` naming the line. Waits up to about 60 s and returns the run — status, failed step with its error and code frame, console errors, failed requests, Web Vitals — plus `missing_variables` (the `process.env` names the organization has not set). Counts against the plan's test runs per hour |
| `get_playwright_run` | read | One run in detail: `monitor_id` + `run_id` for a scheduled or Run-now run, or `test_run_id` for a test run. Steps, failure, console and page errors, failed requests, Web Vitals per page, runtime versions, signed screenshot URLs (15 min) and the trace-viewer link |
| `list_playwright_runs` | read | A browser check's runs, newest first — status, duration, failed step, error counts; filter `status=failed` or `flaky` |

To keep a script that passed as a scheduled check, call `create_monitor`
with `type: "playwright"` and `config.script`.

## Resources

Read-only reference documents an AI agent can pull over the same protocol
(`resources/list`, then `resources/read` with the `uri`). Anonymous.

| Resource | URI | Content |
| --- | --- | --- |
| `monitor-types` | `https://watchfor.io/api/v1/meta/monitor-types` | The monitor type catalog with exact alert-metric strings and config fields (`application/json`) |
| `agents-quickstart` | `https://watchfor.io/agents.md` | When to use WatchFor, how to authenticate, the first calls to make (`text/markdown`) |
| `llms-overview` | `https://watchfor.io/llms.txt` | Structured overview of the platform, monitor types and key pages (`text/plain`) |
| `openapi` | `https://watchfor.io/openapi.json` | The OpenAPI 3.1 spec of the REST API (`application/json`) |

Only these URIs are readable; `resources/templates/list` is empty and
subscriptions are not offered.

## Prompts

Reusable, parameterized starting points (`prompts/list`, `prompts/get`)
that compose the tools above. Anonymous to list and fetch.

| Prompt | Arguments | What it asks the AI agent to do |
| --- | --- | --- |
| `diagnose-incidents` | — | Call `get_summary`, then list firing incidents; for each report the monitor, the rule that fired, its duration, the likely cause and a next step |
| `setup-monitor` | `target` (required), `type` (optional) | Confirm the right type and config via `get_monitor_types`, create the monitor with sensible defaults, then propose fitting alert rules and ask before creating them |
| `reliability-report` | `period` (optional, default `7d`) | Combine `get_summary` and `get_incident_stats` into a short reliability assessment with one improvement suggestion |

## Documentation MCP server

Beyond the product server, WatchFor runs a second, **read-only
documentation MCP server** so an AI agent can browse and read these docs
over the same protocol it uses to act:

**Endpoint:** `https://watchfor.io/api/docs-mcp` — anonymous, no key. ·
**Server card:** [`/api/docs-mcp/server-card`](https://watchfor.io/api/docs-mcp/server-card)

A `POST` to `https://watchfor.io/docs/api/mcp` (this page's URL) is
served by the same server, so a client that guesses the docs URL as an
MCP endpoint also works.

| Tool | What it does |
| --- | --- |
| `list_docs` | Every documentation page with path, title and description; optional `section` filter (`api`, `monitors`, `alerting`, …) |
| `search_docs` | Keyword search over titles, descriptions and headings; returns matching pages ranked by relevance |
| `read_doc` | The full markdown of one page by `path` (e.g. `/docs/api/mcp`) |

Use the product server at `/api/mcp` to *act* on an account and this
one to *learn*. Tool-execution errors carry a structured
`{ "error": { "code", "message" } }` in the text content.

## Transport details

- **Streamable HTTP**, stateless, JSON responses. `POST` a JSON-RPC 2.0
  message (or a batch array) and get JSON back; notifications are
  acknowledged with `202` and no body.
- Protocol versions `2025-11-25`, `2025-06-18`, `2025-03-26` and
  `2024-11-05` are accepted; an unknown requested version negotiates to the
  latest. The handshake-less `2026-07-28` revision is not supported yet.
- `initialize` returns an `Mcp-Session-Id` header for clients that
  expect one; the server is stateless, so any replica accepts any
  request and the id is never validated. `DELETE` (session end) returns
  `200`.
- `GET` opens a keep-alive `text/event-stream` (comments only — the
  server never pushes messages) so strict clients complete the transport
  handshake.
- Tool results are `content: [{ type: "text", text:  }]`; failures
  set `isError: true` with the API's error message (including the HTTP
  status). Unknown tools and invalid arguments are reported the same
  way, naming the available tools or the offending argument.
- Tool calls count toward your plan's API rate limit; anonymous
  discovery is bounded per IP. Both advertise `X-RateLimit-*` headers.

## Notes

- `get_summary` is the recommended first call; `get_monitor_types`
  before creating anything. The server's `instructions` say the same to
  the model.
- Example prompts: *"Any incidents in the last 24 hours? What caused
  them?"*, *"Create an HTTP monitor for shop.example.com checked every
  minute from two EU locations"*, *"Schedule maintenance for all monitors
  tagged `backend` on Saturday 22:00–24:00 UTC"*, *"Who got paged for
  incident 19351 and did the Slack message go out?"*.
- WatchFor can also **monitor** MCP servers (handshake, tool inventory,
  drift) — see [MCP monitoring](/docs/monitors/mcp).
- For AI agents that delegate whole tasks rather than call tools, see the
  [A2A agent](/docs/api/a2a).

---

Canonical page: https://watchfor.io/docs/api/mcp · All docs: https://watchfor.io/docs · Site guide: https://watchfor.io/llms.txt
