The Model Context Protocol server
The seven tools an agent can call to ask about your monitoring, and the scope each one needs.
Silent Outage speaks the Model Context Protocol, so an agent can ask about your monitoring directly — the question this exists for is "is Anthropic down and did it cost me money?", which resolves as get_dependency_status for the first half and query_incidents for the second.
POST https://<your-app-host>/mcp Authorization: Bearer sok_…
One endpoint, POST only, authenticated with the same scoped API key the REST API takes. You hold one credential for Silent Outage, not one per protocol — see the REST API guide for how to create, scope and revoke a key.
The protocol revision
Silent Outage implements the 2026-07-28 revision of the MCP core spec, and only that one.
Re-checked live on 2026-08-16 against https://modelcontextprotocol.io/specification/versioning: 2026-07-28 is the current revision. What it changed, and why Silent Outage cares:
- No `initialize` handshake and no protocol-level session. Every request carries its own protocol version, client info and capabilities in
_meta.Mcp-Session-Idno longer exists; Silent Outage never mints one and ignores one if a client sends it. - `server/discover` is mandatory and returns the supported versions, the capabilities and the server identity in one request.
- Every result carries `resultType`. Silent Outage's results are always
"complete"— no tool here ever needs a second round trip, so you will never see aninput_required. - Selected body fields are mirrored into HTTP headers. Every POST must carry
MCP-Protocol-VersionandMcp-Method, and atools/callmust also carryMcp-Name. A header that disagrees with the body is refused with-32020, because an intermediary routing on the header and a server executing on the body must not be able to disagree about what the request is.
Older, handshake-based revisions (2025-11-25 and earlier) are not supported: carrying them would mean holding session state for clients the current SDKs no longer produce. A client asking for one gets HTTP 400 with -32022 and the list of versions we do speak, which is what a conforming client uses to retry.
GET /mcp and DELETE /mcp answer 405. Those were the session-era verbs — a standalone SSE stream and a session teardown — and this revision has neither.
Setting it up
Silent Outage is a remote MCP server: there is nothing to install and no process to run. Every client below wants the same three things — the URL, the header, and nothing else.
Claude Code
claude mcp add --transport http silentoutage https://<your-app-host>/mcp \ --header "Authorization: Bearer sok_…"
Then /mcp in a session to confirm it connected, and the seven tools appear.
Claude Desktop
claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"silentoutage": {
"type": "http",
"url": "https://<your-app-host>/mcp",
"headers": { "Authorization": "Bearer sok_…" }
}
}
}Cursor
.cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project:
{
"mcpServers": {
"silentoutage": {
"url": "https://<your-app-host>/mcp",
"headers": { "Authorization": "Bearer sok_…" }
}
}
}VS Code
.vscode/mcp.json. Use an input rather than pasting the key into a file you may commit:
{
"inputs": [
{
"type": "promptString",
"id": "silentoutage-key",
"description": "Silent Outage API key",
"password": true
}
],
"servers": {
"silentoutage": {
"type": "http",
"url": "https://<your-app-host>/mcp",
"headers": { "Authorization": "Bearer ${input:silentoutage-key}" }
}
}
}Anything else
Any client that speaks Streamable HTTP and lets you set a request header will work. If yours speaks an older revision it will get a -32022 naming 2026-07-28; there is no compatibility mode to switch on.
The tools
Seven, and each one declares a JSON-Schema input and returns structuredContent matching a declared output schema. Call tools/list for the schemas themselves — they are the contract, and they are generated from the same registry the server enforces.
| Tool | Scope | What it does |
|---|---|---|
create_monitor | checks:write | Create a check in a project. The answer carries the ping URL. |
list_monitors | checks:read | Every check and its current state. |
get_status | status:read | Every check's state plus the incidents nobody has closed. |
query_incidents | incidents:read | Incidents with their attribution verdict and dollar range. |
list_dependencies | status:read | The curated providers Silent Outage watches, worst first. |
get_dependency_status | status:read | One provider's feed reading and Silent Outage's own probe. |
ack_incident | incidents:write | "I have this" — halts escalation, leaves the incident open. |
Each scope is the same grant the equivalent REST endpoint requires; the two dependency tools have no REST endpoint and use status:read. A key holding fewer scopes sees fewer tools in tools/list — the spec allows the tool set to vary with the credential presented, and an agent that cannot see a tool it may not call does not waste a turn discovering that. The filter is a courtesy: tools/call checks the scope again regardless.
project_id is optional on list_monitors, get_status and query_incidents. Omit it and the read covers every project in the account the key belongs to — which is what makes "did it cost me money?" answerable by an agent that has no project id to hand. There is no tool that takes an account: the account comes from the key and from nowhere else, so another account's project id returns that account's absence of it rather than its data.
What a tool will not do
- No dollar figure on a non-revenue outage. A heartbeat incident's
dollarLossisnull. Where there is a figure it is always a range with a confidence label — never a point. Do not let an agent average it into one number; the range is the honest answer and the width is information. - No verdict from a feed we could not read.
get_dependency_statusanswersunknown, neverdown.unknownandinconclusiveare real answers here, not missing ones. - No green from a stale reading. Past 15 minutes without a fresh sample the status degrades to
unknownandreportedStatuskeeps what the feed last said. A stale green is the dangerous direction: it would launder a broken poller into a clean bill of health. - No credential in an answer. A check's ping token is returned only as the assembled ping URL, and nothing returns an API key, a digest, or a notification destination.
- No status page taken on trust.
probeContradictsFeedis true when a provider says all is well and Silent Outage's own probe of it failed. Vendor pages lag reality by 30–90 minutes; treat it as evidence, not as a verdict.
Errors
Two kinds, and the difference matters to an agent:
- Tool execution errors come back as a successful JSON-RPC result with
isError: trueand a message. Bad arguments, a project that does not exist, a tier that does not include the check type (the message carries the plan that lifts it). These are the ones a model can act on. - Protocol errors come back as JSON-RPC errors. Unknown tool (
-32602), unknown method (-32601, HTTP 404), header/body mismatch (-32020, HTTP 400), unsupported version (-32022, HTTP 400).
Authorization is HTTP-shaped, as the spec requires:
| Status | When | What comes with it |
|---|---|---|
| 401 | no key, an invalid key, or a revoked one | WWW-Authenticate: Bearer, and data.reason distinguishes revoked |
| 403 | a valid key without the tool's scope | WWW-Authenticate: Bearer error="insufficient_scope", scope="…" |
| 429 | the key's rate-limit window is spent | Retry-After and the RateLimit-* headers |
One MCP request costs the key exactly one request against its rate limit, whatever the tool does internally — a get_status fanning out over five projects is still one. A 403 costs one too: a refusal that were free would let a stolen key be enumerated at full speed.
Origin
The transport requires servers to validate the Origin header against DNS rebinding. Silent Outage accepts a request with no `Origin` — which is every real MCP client, since a client is a process and not a page — and otherwise only its own origin. If you are deliberately running a browser-hosted client, list its origin in SILENTOUTAGE_MCP_ALLOWED_ORIGINS (comma-separated).
Where this runs
The MCP endpoint is served by the same part of Silent Outage as the REST API and the dashboard. That is a consequence of the 2026-07-28 revision being stateless: with no session to pin to a process, an MCP request is an ordinary authenticated HTTP POST, and there is nothing here that would justify one more moving part to operate.
It is deliberately not on the alert path. What has to stay independent is the edge that receives your reports and the process that sends your alerts; an MCP outage costs you the ability to ask about an incident and costs nothing about being told about one.