MCP tool reference
Generated from the tool registry (packages/agent). 108 tools. Connect with the same API token you use for the REST API; scopes gate each tool exactly as they gate the REST route it maps to. Every mutating call is audited (Settings → Agents → Activity, or list_agent_activity).
Account
whoami
Who am I? Returns how this connection is authenticated (API token or session), the organization(s) it can reach, the granted scopes, and the user behind it. Call this first. Works with any authenticated connection regardless of scopes.
- Scope:
org:read· read-only - REST:
GET /v1/whoami
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "whoami",
"arguments": {}
}
}
Documentation
search_docs
Full-text search over Bugwatch's documentation (setup, SDKs, API, MCP, alerts, billing, security). Returns slugs to pass to get_doc.
- Scope:
org:read· read-only - Arguments:
querystring (required) — Search termslimitinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_docs",
"arguments": {
"query": "source maps"
}
}
}
get_doc
Read one documentation page as Markdown by slug (from search_docs or list_docs).
- Scope:
org:read· read-only - Arguments:
slugstring (required) — Doc slug, e.g. quickstart
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_doc",
"arguments": {
"slug": "quickstart"
}
}
}
list_docs
Table of contents of the documentation: slug, title, one-line description per page.
- Scope:
org:read· read-only
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_docs",
"arguments": {}
}
}
Projects
list_projects
List the projects in an organization with slug, name, platform, and dashboard link.
- Scope:
project:read· read-only - REST:
GET /v1/orgs/{org}/projects - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_projects",
"arguments": {
"org": "acme"
}
}
}
get_project
Project settings: name, platform, retention tier, store-IP flag, inbound filters, project number.
- Scope:
project:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_project",
"arguments": {
"org": "acme",
"project": "checkout-api"
}
}
}
create_project
Create a project. Returns its DSN-bearing key; pass the platform id (e.g. javascript-nextjs, python-django) when known.
- Scope:
project:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects - Arguments:
orgstring (required) — Organization slugslugstring (required) — lowercase letters, digits, dashesnamestring (required)platformstring — Platform id from the registry (optional)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_project",
"arguments": {
"org": "acme",
"slug": "checkout-api",
"name": "Checkout API",
"platform": "node"
}
}
}
update_project
Update project name, platform, store-IP flag, or inbound filters (crawlers, legacy browsers, localhost, extensions, message deny list, allowed domains).
- Scope:
project:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/projects/{project} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugnamestringplatformstringstoreIpboolean — Keep client IP on events (default false)filtersobject — Inbound filters
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_project",
"arguments": {
"org": "acme",
"project": "checkout-api",
"filters": {
"dropCrawlers": true
}
}
}
}
get_repo_connection
Whether this organization has a repository connected for the fix agent, and which one. Connecting or disconnecting is human-only — it stores a credential that can write to source code.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/repo-connection - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_repo_connection",
"arguments": {
"org": "acme"
}
}
}
Issues
search_issues
List or search issues in a project (compact: id, level, status, title, impact, deep link). Filter by status, full-text q, sort, and page with cursor.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugqstring — Free-text match on title/culpritstatusstring one ofunresolved,resolved,ignored,regressedsortstring one oflast_seen,first_seenlimitintegercursorstring — nextCursor from a previous call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search_issues",
"arguments": {
"org": "acme",
"project": "checkout-api",
"status": "unresolved",
"limit": 10
}
}
}
get_issue
Compact summary of one issue (title, culprit, status, impact, first/last seen, deep link). For frames and source context call get_fix_context.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_issue",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
get_fix_context
Everything needed to FIX an issue in one payload (JSON, can be large): symbolicated in-app frames with source context, breadcrumbs, release + commit, impact numbers, similar resolved issues. Call before attempting a fix.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId}/fix-context - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_fix_context",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
get_issue_history
Day-by-day events and estimated affected users for an issue, from the nightly rollup — so it reaches back FURTHER than the analytics window the issue chart uses (up to 400 days). Use it to answer whether an issue is new, recurring, or seasonal. Sampling-derived estimates, not exact counts.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId}/history - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)daysnumber — How far back to read, 1–400. Defaults to 90.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_issue_history",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42,
"days": 365
}
}
}
get_issue_activity
Activity feed for an issue: status changes, regressions, agent actions, with actor and time.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId}/activity - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_issue_activity",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
resolve_issue
Mark an issue resolved. Requires event:write; audited.
- Scope:
event:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/projects/{project}/issues/{shortId} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "resolve_issue",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
ignore_issue
Ignore an issue (mute alerts). Requires event:write; audited.
- Scope:
event:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/projects/{project}/issues/{shortId} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "ignore_issue",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
unresolve_issue
Reopen an issue (back to unresolved). Requires event:write; audited.
- Scope:
event:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/projects/{project}/issues/{shortId} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "unresolve_issue",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
bulk_update_issues
Set the status of up to 100 issues at once (resolve, ignore, or reopen). Requires event:write; audited.
- Scope:
event:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects/{project}/issues/bulk - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdsarray (required) — Issue short idsstatusstring (required) one ofunresolved,resolved,ignored
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "bulk_update_issues",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortIds": [
42,
43
],
"status": "resolved"
}
}
}
import_issues
Import a triaged issue backlog from another error tracker. Carries status, assignee and first/last seen; does NOT copy events — counts arrive as source metadata, never as live counters. DEFAULTS TO A DRY RUN: call once to see the coverage report, then again with dryRun=false. Export the issues from the old tracker and pass them here; Bugwatch never asks for a token to it. An issue that already exists here is left alone, because its triage was made in this product. Requires event:write.
- Scope:
event:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects/{project}/import-issues - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugsourcestring (required) — Which tracker this came from, e.g. sentry or bugsnagissuesarray (required) — The exported issues. Each needs at least anid;title,status,assignee(email),firstSeen,lastSeen,count,userCount,fingerprintandpermalinkare used when present.dryRunboolean — Default true. Set false to actually create the issues.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "import_issues",
"arguments": {
"org": "acme",
"project": "checkout-api",
"source": "sentry",
"issues": [
{
"id": "4512",
"title": "TypeError: x is not a function",
"status": "resolved"
}
]
}
}
}
resolve_issues_from_commit
Resolve the issues a commit message closes. Reads GitHub-style trailers — Fixes #42, Closes COMPAT-42 — and resolves those issues, recording the commit on each one's activity feed. A bare mention without a closing verb resolves nothing. Call it after pushing a fix, or from CI. Requires event:write.
- Scope:
event:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects/{project}/resolve-by-commit - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshastring (required) — Commit SHAmessagestring (required) — The full commit message, including its trailersurlstring — Link to the commit
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "resolve_issues_from_commit",
"arguments": {
"org": "acme",
"project": "web",
"sha": "9f3a1c2",
"message": "checkout: guard against a null cart\n\nFixes #412"
}
}
}
Events
list_events
List recent events for an issue (event id, timestamp, size), newest first; page with cursor. Use get_event for a body.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId}/events - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)cursorstring
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_events",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
get_event
Full processed event body (JSON, often 10–40 KB): exception with all frames, breadcrumbs, contexts, tags, request, sdk. Prefer get_fix_context unless you need everything.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId}/events/{eventId} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)eventIdstring (required) — 32-hex event id from list_events
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_event",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42,
"eventId": "0123456789abcdef0123456789abcdef"
}
}
}
list_issue_attachments
Files the SDK attached to this issue's events (screenshots, logs, view hierarchies): filename, type, size, event id, newest first. Metadata only; the bytes are a binary download from GET …/attachments/{id}, not a tool result.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/issues/{shortId}/attachments - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugshortIdinteger (required) — Issue short id (the number in the dashboard URL)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_issue_attachments",
"arguments": {
"org": "acme",
"project": "checkout-api",
"shortId": 42
}
}
}
replay_raw_events
Re-process raw events already stored for a project over a time window — for after a pipeline incident. DEFAULTS TO A DRY RUN: call it once to see what it would cover, then again with dryRun=false. Events keep their original ids, so anything the 24h dedup window still remembers is a no-op; a window reaching further back is refused unless acceptDoubleCount is set, because those events would be counted and billed a second time. Transactions are never replayed. Requires event:write.
- Scope:
event:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects/{project}/replay - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugfromnumber (required) — Window start, epoch mstonumber (required) — Window end, epoch msdryRunboolean — Default true. Set false to actually re-enqueue.acceptDoubleCountboolean — Required to replay past the 24h dedup window; acknowledges that events will be re-counted and re-billed.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "replay_raw_events",
"arguments": {
"org": "acme",
"project": "checkout-api",
"from": 1757930000000,
"to": 1757940000000
}
}
}
Performance
query_performance
Per-transaction performance overview for the last N hours: throughput, p50/p75/p95/p99 ms, failures. Sampling-aware.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/transactions - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugsinceinteger — Window in hourslimitinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "query_performance",
"arguments": {
"org": "acme",
"project": "checkout-api",
"since": 24
}
}
}
get_transaction
One transaction in detail: throughput, p50/p75/p95/p99, failure rate, latency over time, the spans that own the most of its time, and the error issues seen in its recent traces (linked by trace id). Sampling-aware.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/transaction - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugnamestring — Exact transaction name, e.g. 'GET /api/orders'sinceinteger — Window in hoursintervalinteger — Series bucket size in minutes one of1,5,15,60,1440spansinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_transaction",
"arguments": {
"org": "acme",
"project": "checkout-api",
"name": "GET /api/orders",
"since": 24
}
}
}
get_web_vitals
p75 Core Web Vitals per transaction for the last N hours (LCP, FCP, CLS, INP, TTFB), sampling-aware. A vital with no measurements is reported as null, never as zero.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/vitals - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugsinceinteger — Window in hourslimitinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_web_vitals",
"arguments": {
"org": "acme",
"project": "web-app",
"since": 24
}
}
}
get_stats
Time series of event volume (errors, transactions, or sessions) for the last N hours at a chosen interval. Sampling-aware estimates.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/stats - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugdatasetstring one oferrors,transactions,sessionsintervalinteger — Bucket size in minutes one of1,5,15,60,1440sinceinteger — Window in hoursissuestring — Restrict to one issue id (internal id, not short id)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_stats",
"arguments": {
"org": "acme",
"project": "checkout-api",
"dataset": "errors",
"since": 24,
"interval": 60
}
}
}
Releases
list_releases
Releases in the organization: version, status, commit, deploy count, last deploy, artifact bundles.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/releases - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_releases",
"arguments": {
"org": "acme"
}
}
}
create_release
Register a release version (optionally with commit SHA and URL). Requires release:write.
- Scope:
release:write· mutating, audited - REST:
POST /v1/orgs/{org}/releases - Arguments:
orgstring (required) — Organization slugversionstring (required)commitShastringurlstring
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_release",
"arguments": {
"org": "acme",
"version": "1.4.2",
"commitSha": "a3f9c2e"
}
}
}
create_deploy
Record a deploy of a release to an environment. Requires release:write.
- Scope:
release:write· mutating, audited - REST:
POST /v1/orgs/{org}/releases/{version}/deploys - Arguments:
orgstring (required) — Organization slugversionstring (required)environmentstring (required) — e.g. productionnamestringurlstring
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_deploy",
"arguments": {
"org": "acme",
"version": "1.4.2",
"environment": "production"
}
}
}
get_release_health
Session health of a release in a project: sessions, crashed/errored/abnormal, crash-free rate.
- Scope:
event:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/releases/{version}/health - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugversionstring (required)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_release_health",
"arguments": {
"org": "acme",
"project": "checkout-api",
"version": "1.4.2"
}
}
}
Alerts
list_channels
Notification channels in the organization (Slack, webhook, email, PagerDuty) with masked targets.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/channels - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_channels",
"arguments": {
"org": "acme"
}
}
}
create_channel
Create a notification channel. config is one of: {kind:'slack_webhook',url}, {kind:'discord',url}, {kind:'teams',url}, {kind:'webhook',url}, {kind:'email',to}, {kind:'pagerduty',routingKey}, {kind:'voice',to}. Each url is host-checked: Slack on hooks.slack.com, Discord on discord.com/api/webhooks, Teams on a .logic.azure.com Workflows URL; anything else uses 'webhook'. voice takes an E.164 number. Stored encrypted. A 'webhook' channel gets its own signing secret (signingSecret, shown once in this response): its receiver verifies x-bugwatch-signature with it. An 'email' channel sends nothing until its address follows the confirmation link mailed to it (the response says verified:false until then). Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/channels - Arguments:
orgstring (required) — Organization slugnamestring (required)configobject (required) — Channel config (discriminated by kind)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_channel",
"arguments": {
"org": "acme",
"name": "#alerts",
"config": {
"kind": "slack_webhook",
"url": "https://hooks.slack.com/services/…"
}
}
}
}
rotate_channel_secret
Give a webhook channel a new signing secret, returned once; the old one stops verifying at the next delivery. Also how a channel listed with legacySigning:true (signed with the deployment's shared secret) gets a secret of its own. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/channels/{id}/rotate-secret - Arguments:
orgstring (required) — Organization slugidstring (required) — Channel id (a webhook channel)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "rotate_channel_secret",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
delete_channel
Delete a notification channel by id. Anything still pointing at it — services, monitors, alert rules — is detached in the same operation, so nothing is left holding a reference that pages nobody. A service left with no channels stops paging through channels entirely. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/channels/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Channel id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_channel",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
list_alert_rules
Alert rules for a project: conditions (new_issue, regression, frequency), filters, channel actions, throttle, enabled.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/alert-rules - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_alert_rules",
"arguments": {
"org": "acme",
"project": "checkout-api"
}
}
}
create_alert_rule
Create an alert rule. conditions: [{type:'new_issue'}|{type:'regression'}|{type:'frequency',count,windowMinutes}]; filters: [{type:'environment'|'min_level'|'release',value}]; actions: [{type:'channel',channelId}]. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects/{project}/alert-rules - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugnamestring (required)conditionsarray (required)filtersarrayactionsarray (required)environmentstringfrequencySinteger — Min seconds between notifications per issueenabledboolean
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_alert_rule",
"arguments": {
"org": "acme",
"project": "checkout-api",
"name": "New issues → Slack",
"conditions": [
{
"type": "new_issue"
}
],
"actions": [
{
"type": "channel",
"channelId": "01J…"
}
]
}
}
}
update_alert_rule
Replace an alert rule's definition (PATCH has replace semantics: send the full rule — name, conditions, actions — plus any of filters, environment, frequencyS, enabled). Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/projects/{project}/alert-rules/{id} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugidstring (required) — Rule idnamestring (required)conditionsarray (required)filtersarrayactionsarray (required)environmentstringfrequencySintegerenabledboolean
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_alert_rule",
"arguments": {
"org": "acme",
"project": "checkout-api",
"id": "01J…",
"name": "New issues → Slack",
"conditions": [
{
"type": "new_issue"
}
],
"actions": [
{
"type": "channel",
"channelId": "01J…"
}
],
"enabled": false
}
}
}
delete_alert_rule
Delete an alert rule by id. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/projects/{project}/alert-rules/{id} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugidstring (required)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_alert_rule",
"arguments": {
"org": "acme",
"project": "checkout-api",
"id": "01J…"
}
}
}
Uptime monitors
list_monitors
Uptime monitors in the organization: state (up/degraded/down/paused/pending), type, target, last check and latency.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/monitors - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_monitors",
"arguments": {
"org": "acme"
}
}
}
get_monitor
One uptime monitor: full check configuration (secrets redacted), interval, regions, thresholds, quorum, channels, current state and — for heartbeat monitors — the ping URL.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/monitors/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_monitor",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
create_monitor
Create an uptime monitor. check is one of: {type:'http',url,method?,expectedStatus?,keyword?,keywordAbsent?,timeoutMs?,maxLatencyMs?}; {type:'tcp',host,port}; {type:'tls',host,port?}; {type:'dns',name,recordType?,expected?}; {type:'heartbeat',expectedEverySeconds,graceSeconds?} (returns a ping URL the job must call). intervalSeconds must be at or above the plan minimum; regions are Cloudflare location hints (wnam, enam, weur, eeur, apac, oc, afr, sam) and a DOWN needs quorum of them to agree. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/monitors - Arguments:
orgstring (required) — Organization slugnamestring (required) — Display namecheckobject (required) — Check configuration, discriminated by type (http | tcp | tls | dns | heartbeat)intervalSecondsinteger — Seconds between checksregionsarray — Probe regionsfailureThresholdinteger — Consecutive failures in a region before it counts as failingrecoveryThresholdinteger — Consecutive passes before a region counts as passingquoruminteger — Regions that must agree before DOWN/UP (default ceil(regions/2))channelIdsarray — Notification channel ids to page (see list_channels). With a serviceId set these are only the fallback, used if the escalation cannot startserviceIdstring — Escalate through this service instead of paging channels: a DOWN opens an incident and its policy pages whoever is on call (see list_services)enabledboolean
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_monitor",
"arguments": {
"org": "acme",
"name": "Checkout API",
"check": {
"type": "http",
"url": "https://api.example.com/health",
"keyword": "ok"
},
"intervalSeconds": 60,
"regions": [
"wnam",
"weur",
"apac"
]
}
}
}
update_monitor
Update an uptime monitor: send only the fields to change (name, check, intervalSeconds, regions, failureThreshold, recoveryThreshold, quorum, channelIds, serviceId, enabled). A replaced check replaces the whole object. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/monitors/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor idnamestringcheckobject — Replacement check configuration (same shapes as create_monitor)intervalSecondsintegerregionsarrayfailureThresholdintegerrecoveryThresholdintegerquorumintegerchannelIdsarrayserviceIdstring — Escalate through this service; null detaches itenabledboolean
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_monitor",
"arguments": {
"org": "acme",
"id": "01J…",
"intervalSeconds": 30,
"channelIds": [
"01J…"
]
}
}
}
delete_monitor
Delete an uptime monitor and stop its probes. History stays queryable until it ages out. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/monitors/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_monitor",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
pause_monitor
Pause an uptime monitor: probes stop and it never pages until resumed (use this during planned maintenance). Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/monitors/{id}/pause - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "pause_monitor",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
resume_monitor
Resume a paused uptime monitor. It restarts in the pending state and pages again once the consensus is DOWN. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/monitors/{id}/resume - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "resume_monitor",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
snooze_monitor
Quiet a monitor's paging for 15, 60, 240 or 1440 minutes while somebody works on it (#209). Checks, state and status pages carry on; only the DOWN page is withheld, and a monitor still down when the snooze ends is paged then. Never indefinite. To stop an open incident paging, acknowledge it instead. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/monitors/{id}/snooze - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor idminutesinteger (required) — How long, in minutes one of15,60,240,1440
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "snooze_monitor",
"arguments": {
"org": "acme",
"id": "01J…",
"minutes": 60
}
}
}
unsnooze_monitor
Lift a monitor's snooze now. If it is down, the withheld page goes out at its next check. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/monitors/{id}/snooze - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "unsnooze_monitor",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
get_monitor_history
Uptime and latency history for one monitor: per-bucket uptime % with p50/p95, plus a per-region summary over the window. Sampling-aware estimates.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/monitors/{id}/history - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor idsinceinteger — Window in hoursintervalinteger — Bucket size in minutes one of1,5,15,60,1440
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_monitor_history",
"arguments": {
"org": "acme",
"id": "01J…",
"since": 24,
"interval": 5
}
}
}
list_monitor_events
State-change history for one monitor (most recent 100): when it went up, degraded, down or paused, how many regions were failing, and why.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/monitors/{id}/events - Arguments:
orgstring (required) — Organization slugidstring (required) — Monitor id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_monitor_events",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
On-call schedules
list_schedules
On-call schedules in the organization: name, timezone and how many rotation layers each has.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/schedules - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_schedules",
"arguments": {
"org": "acme"
}
}
}
get_schedule
One on-call schedule in full: timezone, every rotation layer (type, handoff wall-clock time, rotation order, restrictions, active dates) and every override.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/schedules/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_schedule",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
who_is_on_call
Who is on call for a schedule at an instant (default: now). Returns the user, whether an override or a rotation layer decided it, and null when the window is UNCOVERED — a gap is a real answer, not an error.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/schedules/{id}/on-call - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule idatinteger — Epoch ms; defaults to now
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "who_is_on_call",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
get_schedule_coverage
Coverage for a schedule over a window (default: the next 7 days, 90 days maximum) as contiguous segments. Uncovered windows appear as segments with a null user — use this to find gaps before they page nobody.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/schedules/{id}/coverage - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule idfrominteger — Window start, epoch ms; defaults to nowtointeger — Window end, epoch ms; defaults to 7 days after from
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_schedule_coverage",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
create_schedule
Create an on-call schedule. timeZone is an IANA zone name (never a UTC offset — offsets change, zones don't) and handoffs are wall-clock times in it, so a Monday 09:00 handoff stays 09:00 across DST. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/schedules - Arguments:
orgstring (required) — Organization slugnamestring (required)timeZonestring (required) — IANA zone, e.g. America/New_YorkteamIdstringlayersarray (required) — Rotation layers, highest position wins. Each: {name, position, rotationType: daily|weekly|custom, turnLengthSeconds (custom), handoffLocalTime like "09:00" (WALL CLOCK in the schedule timezone), handoffWeekday (weekly), startDate/endDate epoch ms, users (rotation order), restrictions [{kind: daily|weekly, startLocalTime, durationSeconds, weekday}].
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_schedule",
"arguments": {
"org": "acme",
"name": "Platform primary",
"timeZone": "America/New_York",
"layers": [
{
"name": "Weekly primary",
"position": 1,
"rotationType": "weekly",
"handoffLocalTime": "09:00",
"handoffWeekday": 1,
"startDate": 1767225600000,
"users": [
"usr_ada",
"usr_bo",
"usr_cy"
],
"restrictions": []
}
]
}
}
}
update_schedule
Update a schedule's name, timezone, team or layers. Sending layers REPLACES the whole stack — positions, rotation order and restrictions only make sense as a set. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/schedules/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule idnamestringtimeZonestringteamIdstringlayersarray — Rotation layers, highest position wins. Each: {name, position, rotationType: daily|weekly|custom, turnLengthSeconds (custom), handoffLocalTime like "09:00" (WALL CLOCK in the schedule timezone), handoffWeekday (weekly), startDate/endDate epoch ms, users (rotation order), restrictions [{kind: daily|weekly, startLocalTime, durationSeconds, weekday}].
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_schedule",
"arguments": {
"org": "acme",
"id": "01J…",
"timeZone": "Europe/London"
}
}
}
delete_schedule
Delete an on-call schedule. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/schedules/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_schedule",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
create_override
Put someone on call for a window regardless of the rotation — a cover for illness, holiday or a handover. Overrides beat every layer. Half-open: [startsAt, endsAt). Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/schedules/{id}/overrides - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule iduserIdstring (required) — User taking the shiftstartsAtinteger (required) — Epoch ms, inclusiveendsAtinteger (required) — Epoch ms, exclusive
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_override",
"arguments": {
"org": "acme",
"id": "01J…",
"userId": "usr_sam",
"startsAt": 1767225600000,
"endsAt": 1767268800000
}
}
}
delete_override
Remove an override, handing the window back to the rotation. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/schedules/{id}/overrides/{overrideId} - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule idoverrideIdstring (required) — Override id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_override",
"arguments": {
"org": "acme",
"id": "01J…",
"overrideId": "01J…"
}
}
}
list_devices
The phones registered to you in this organization, with when each last confirmed a delivery. Push tokens are never returned — this is for recognising a device, not for reading its credentials. A device that stopped confirming deliveries is going stale and stops being counted on for pages.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/devices - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_devices",
"arguments": {
"org": "acme"
}
}
}
revoke_device
Stop paging one of your devices and clear its push credentials — a lost or replaced phone. Yours only; revoking somebody else's device would take them off call without telling them. Requires a session.
- Scope:
org:read· mutating, audited - REST:
DELETE /v1/orgs/{org}/devices/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Device id from list_devices
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "revoke_device",
"arguments": {
"org": "acme",
"id": "01JDEVICE"
}
}
}
get_notification_rules
Your notification rules for this organization: which categories are on, quiet hours, active mutes and which devices take pages. Pages are not among the things that can be switched off — an escalation targeting you always rings.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/notification-prefs - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_notification_rules",
"arguments": {
"org": "acme"
}
}
}
set_notification_rules
Replace your notification rules for this organization. Send the whole object. categories may not switch page off, and every mute needs an expiry (at most 30 days) — an indefinite silent mute is how a page gets missed. Requires a session.
- Scope:
org:read· mutating, audited - REST:
PUT /v1/orgs/{org}/notification-prefs - Arguments:
orgstring (required) — Organization slugcategoriesobject — Category → on/off.pagecannot be false.quietHoursobject — {startLocalTime:"22:00", endLocalTime:"08:00", timeZone:"Europe/London"} or null. Never applies to pages.mutesarray — [{scope:{kind:"all_non_page"|"category"|"thread", …}, until: epochMs}]pageDeviceIdsarray — Devices that take pages; empty means all of them
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_notification_rules",
"arguments": {
"org": "acme",
"quietHours": {
"startLocalTime": "22:00",
"endLocalTime": "08:00",
"timeZone": "Europe/London"
}
}
}
}
diff_imported_schedule
Compare an Opsgenie or PagerDuty schedule against one of ours over a 30-day window, without importing anything. Pass the provider's schedule payload as source, name the provider, and give a userMap from their usernames to our user ids. Returns what the mapping could not carry across, then the coverage differences. Read-only: it stores nothing and cannot activate a rotation — a migration needs human sign-off before it pages anybody.
- Scope:
org:read· read-only - REST:
POST /v1/orgs/{org}/schedules/{id}/import-diff - Arguments:
orgstring (required) — Organization slugidstring (required) — Schedule idproviderstring — Which system the payload came from. Default opsgenie. one ofopsgenie,pagerdutysourceobject (required) — The provider's schedule payload — Opsgenie (id, timezone, rotations[]) or PagerDuty (id, time_zone, schedule_layers[], overrides[])userMapobject — Their username or id → our user id. Unmapped people are reported, never assumed.frominteger — Window start, epoch ms. Defaults to now.daysinteger — Window length in days (1–30, default 30)boundaryToleranceMsinteger — Differences shorter than this are listed separately as boundary noise. Never reduces uncovered time.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "diff_imported_schedule",
"arguments": {
"org": "acme",
"id": "01J…",
"source": {
"id": "sch-og",
"timezone": "Europe/London",
"rotations": []
},
"userMap": {
"ada@acme.test": "usr_ada"
}
}
}
}
Incidents & escalation
list_incidents
Incidents in the organization, newest first. Filter by status (triggered, acknowledged, resolved) — triggered is the list that matters during an outage: nobody has picked those up yet.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/incidents - Arguments:
orgstring (required) — Organization slugstatusstring one oftriggered,acknowledged,resolvedlimitinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_incidents",
"arguments": {
"org": "acme",
"status": "triggered"
}
}
}
get_incident
One incident with its full timeline: when it triggered, every escalation step, who was paged on which channel, who acknowledged and when it resolved. Read this before asking anyone what happened.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/incidents/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_incident",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
trigger_incident
Open an incident and start its escalation chain. A repeated call with the same dedupKey joins the open incident instead of paging a second time. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/incidents - Arguments:
orgstring (required) — Organization slugserviceIdstring (required) — Service idtitlestring (required)summarystringseveritystring one ofsev1,sev2,sev3,sev4urgencystring one oflow,highdedupKeystring — Repeated triggers with this key join the open incident
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "trigger_incident",
"arguments": {
"org": "acme",
"serviceId": "01J…",
"title": "Checkout API returning 500s",
"severity": "sev2"
}
}
}
acknowledge_incident
Acknowledge an incident: escalation stops immediately. If the service sets an ack timeout and nobody resolves it, it re-escalates — acking is not a way to make it go away. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/incidents/{id}/acknowledge - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "acknowledge_incident",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
resolve_incident
Resolve an incident: escalation stops and the timer clears. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/incidents/{id}/resolve - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "resolve_incident",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
list_escalation_policies
Escalation policies: how many rules each chain has, whether it repeats, and its fallback target.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/escalation-policies - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_escalation_policies",
"arguments": {
"org": "acme"
}
}
}
get_escalation_policy
One escalation policy: every rule in order, its targets (schedule or user), delay and urgency.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/escalation-policies/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Escalation policy id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_escalation_policy",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
create_escalation_policy
Create an escalation policy. Rule 0 fires the moment an incident opens; each rule's delaySeconds is how long to wait before the NEXT one. Set fallbackUserId so an uncovered rotation still reaches somebody. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/escalation-policies - Arguments:
orgstring (required) — Organization slugnamestring (required)rulesarray (required) — Ordered escalation rules. Each: {position (0 fires immediately), delaySeconds (wait before the NEXT rule), urgency: low|high, targets: [{kind: schedule|user, targetId}]}. Low urgency notifies without paging.repeatCountinteger — Times to run the whole chain againrepeatDelaySecondsintegerfallbackUserIdstring — Paged when a rule resolves to nobodyteamIdstring
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_escalation_policy",
"arguments": {
"org": "acme",
"name": "Platform chain",
"fallbackUserId": "usr_lead",
"rules": [
{
"position": 0,
"delaySeconds": 300,
"urgency": "high",
"targets": [
{
"kind": "schedule",
"targetId": "01J…"
}
]
},
{
"position": 1,
"delaySeconds": 300,
"urgency": "high",
"targets": [
{
"kind": "user",
"targetId": "usr_lead"
}
]
}
]
}
}
}
update_escalation_policy
Update a policy's name, repeat behaviour, fallback or rules. Sending rules REPLACES the whole chain — positions and targets only mean anything as an ordered set. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/escalation-policies/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Escalation policy idnamestringrulesarray — Ordered escalation rules. Each: {position (0 fires immediately), delaySeconds (wait before the NEXT rule), urgency: low|high, targets: [{kind: schedule|user, targetId}]}. Low urgency notifies without paging.repeatCountintegerrepeatDelaySecondsintegerfallbackUserIdstring
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_escalation_policy",
"arguments": {
"org": "acme",
"id": "01J…",
"repeatCount": 2
}
}
}
delete_escalation_policy
Delete an escalation policy. Services pointing at it stop paging, so repoint them first. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/escalation-policies/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Escalation policy id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_escalation_policy",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
list_services
Services: what an incident is about, which escalation policy it pages, which channels it notifies, and its auto-resolve and ack-timeout settings.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/services - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_services",
"arguments": {
"org": "acme"
}
}
}
create_service
Create a service: a name, the escalation policy its incidents page, the channels they notify, and optionally the product-line-1 project it belongs to. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/services - Arguments:
orgstring (required) — Organization slugnamestring (required)escalationPolicyIdstring — Escalation policy idprojectIdstring — Links the service to a Bugwatch projectchannelIdsarray — Notification channels to pageautoResolveSecondsintegerackTimeoutSecondsinteger — Re-escalate an ack nobody followed up
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_service",
"arguments": {
"org": "acme",
"name": "Checkout",
"escalationPolicyId": "01J…",
"channelIds": [
"01J…"
],
"ackTimeoutSeconds": 1800
}
}
}
update_service
Update a service's name, policy, channels, project link, auto-resolve or ack timeout. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/services/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Service idnamestringescalationPolicyIdstring — Escalation policy idprojectIdstringchannelIdsarrayserviceIdstring — Escalate through this service; null detaches itautoResolveSecondsintegerackTimeoutSecondsinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_service",
"arguments": {
"org": "acme",
"id": "01J…",
"ackTimeoutSeconds": 900
}
}
}
delete_service
Delete a service. Its open incidents keep their escalation; new alerts for it stop. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/services/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Service id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_service",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
get_incident_context
What else changed around an incident: error rate and probe latency before vs after it opened, and deploys in the two hours before. Ranked evidence for a responder who has already been paged — it never delays or replaces a page, and cannot acknowledge, resolve or suppress anything. Says plainly when nothing stood out, and which checks it was able to run.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/incidents/{id}/context - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_incident_context",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
draft_incident_retro
A retro draft assembled from the incident's own timeline: how long detection, acknowledgement and the fix each took, what the response itself got wrong (pages that were never delivered, a chain that reached its fallback, nobody answering), and the questions left to fill in. It measures; it does not write the analysis. Read-only.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/incidents/{id}/retro - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "draft_incident_retro",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
get_incident_brief
Catch up on an incident that is still happening: whether anybody has it, who has been paged and who answered, what has already been tried, and what is wrong with the RESPONSE itself — pages that were never delivered, a service with no escalation policy, a source that fired again. Written for somebody who was just paged and has ten seconds. Distinguishes 'nobody answered' from 'nothing was ever delivered', which have different next actions. Read-only.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/incidents/{id}/brief - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_incident_brief",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
draft_status_update
A status-page update drafted for CUSTOMERS from what the incident records: the stage (investigating, identified, monitoring, resolved), which components are affected in the words the public page uses, how long it has been going on, and when the next update is promised. It never states a cause, never names anything internal, and refuses to write an all-clear while a component is still reporting a fault. Optional stage asks for monitoring; optional nextUpdateMinutes sets the cadence. Read-only — publishing is a human action.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/incidents/{id}/status-draft - Arguments:
orgstring (required) — Organization slugidstring (required) — Incident idstagestring — Ask for a stage. Onlymonitoringis honoured, and only once the incident is acknowledged — every other stage is derived from the incident itself, because an operator who can choose the stage can chooseresolvedduring an outage. one ofinvestigating,identified,monitoring,resolvednextUpdateMinutesnumber — Minutes until the next promised update. Defaults per stage.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "draft_status_update",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
Status pages
list_status_pages
Public status pages in the organization: slug, public URL, and whether each is published.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/status-pages - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_status_pages",
"arguments": {
"org": "acme"
}
}
}
get_status_page
One status page with its components, in display order, and what each component reads its health from.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/status-pages/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_status_page",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
create_status_page
Create a public status page. components are what readers see, in order — each one a public NAME for a monitor or service, so nobody outside learns your monitor ids. Pages are unpublished until published is true. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/status-pages - Arguments:
orgstring (required) — Organization slugslugstring (required) — Public URL segment: lowercase letters, digits and dashesnamestring (required) — Page title, e.g. "Acme Status"headlinestring — One line shown above the componentspublishedboolean — False (the default) authors the page without serving itcomponentsarray — What the page shows, in display order. Each: {name (the public label, e.g. "Checkout"), description?, sourceKind: monitor|service, sourceId}. The name is what readers see — a monitor id never reaches the page.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_status_page",
"arguments": {
"org": "acme",
"slug": "acme",
"name": "Acme Status",
"published": true,
"components": [
{
"name": "Checkout",
"sourceKind": "monitor",
"sourceId": "01J…"
}
]
}
}
}
update_status_page
Update a status page. Sending components REPLACES the whole list — order is the display order, so it only means anything as a set. Setting published to false takes the page down immediately. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/status-pages/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page idslugstring — Changing this changes the public URL and retires the old onenamestringheadlinestringpublishedbooleancomponentsarray — What the page shows, in display order. Each: {name (the public label, e.g. "Checkout"), description?, sourceKind: monitor|service, sourceId}. The name is what readers see — a monitor id never reaches the page.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "update_status_page",
"arguments": {
"org": "acme",
"id": "01J…",
"published": true
}
}
}
delete_status_page
Delete a status page. Its public URL stops answering immediately. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/status-pages/{id} - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "delete_status_page",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
list_status_page_domains
Custom domains on a status page: the hostname, whether it is live, and the DNS records still waiting to be added. state is pending, active or failed — a domain serves traffic only when it is active.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/status-pages/{id}/domains - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_status_page_domains",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
add_status_page_domain
Point a hostname you own at a status page. Returns the DNS records to add; the domain goes live on its own once they resolve and the certificate issues — usually minutes. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/status-pages/{id}/domains - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page idhostnamestring (required) — The hostname to serve the page on, e.g. status.acme.com. No wildcards.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "add_status_page_domain",
"arguments": {
"org": "acme",
"id": "01J…",
"hostname": "status.acme.com"
}
}
}
verify_status_page_domain
Re-check a custom domain with the certificate authority now, instead of waiting for the next automatic check. Use after adding the DNS records. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/status-pages/{id}/domains/{domainId}/verify - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page iddomainIdstring (required) — Custom domain id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "verify_status_page_domain",
"arguments": {
"org": "acme",
"id": "01J…",
"domainId": "01J…"
}
}
}
remove_status_page_domain
Stop serving a status page on a custom domain and release its certificate. The hostname stops answering immediately. Requires alert:write.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/status-pages/{id}/domains/{domainId} - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page iddomainIdstring (required) — Custom domain id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "remove_status_page_domain",
"arguments": {
"org": "acme",
"id": "01J…",
"domainId": "01J…"
}
}
}
list_maintenance
Scheduled maintenance windows on a status page, newest first, including past ones. A window with no components covers the whole page.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/status-pages/{id}/maintenance - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_maintenance",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
schedule_maintenance
Schedule a maintenance window on a status page. Components inside an open window read 'maintenance' — unless they are genuinely down, which always wins. Omit componentIds to cover the whole page. Times are epoch ms. Requires alert:write; audited.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/status-pages/{id}/maintenance - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page idtitlestring (required) — What the notice says, e.g. "Database upgrade".bodystring — Optional detail shown under the title.startsAtnumber (required) — Epoch ms when the window opens.endsAtnumber (required) — Epoch ms when it closes. Must be after startsAt.componentIdsarray — Component ids this covers. Omit or leave empty for the whole page.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "schedule_maintenance",
"arguments": {
"org": "acme",
"id": "01J…",
"title": "Database upgrade",
"startsAt": 1789000000000,
"endsAt": 1789007200000
}
}
}
cancel_maintenance
Cancel a scheduled maintenance window. The status page stops showing it immediately. Requires alert:write; audited.
- Scope:
alert:write· mutating, audited - REST:
DELETE /v1/orgs/{org}/status-pages/{id}/maintenance/{windowId} - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page idwindowIdstring (required) — The window's id.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "cancel_maintenance",
"arguments": {
"org": "acme",
"id": "01J…",
"windowId": "01K…"
}
}
}
list_status_incidents
Incidents this status page is showing right now — open ones and any resolved in the last 7 days — each with the stage readers see and every update published about it. This is the page's own view, so it is what readers see and not a separate report of it.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/status-pages/{id}/incidents - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page id
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_status_incidents",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
post_status_update
Publish an update about an incident to a status page: the stage it is at (investigating, identified, monitoring, resolved) and what you want readers to know, in your words. This is PUBLIC the moment it is written — the page rebuilds immediately. The stage you set is what the page shows, overriding the one derived from whether anybody has acknowledged the page; a closed incident always reads resolved whatever was last published. Requires alert:write; audited.
- Scope:
alert:write· mutating, audited - REST:
POST /v1/orgs/{org}/status-pages/{id}/incidents/{incidentId}/updates - Arguments:
orgstring (required) — Organization slugidstring (required) — Status page idincidentIdstring (required) — The incident to publish about. It must be one this page shows.statestring (required) — investigating: we know something is wrong. identified: we know what. monitoring: a fix is out and we are watching. resolved: it is over. one ofinvestigating,identified,monitoring,resolvedbodystring (required) — What readers are told. Plain prose; no internal names or responder identities.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "post_status_update",
"arguments": {
"org": "acme",
"id": "01J…",
"incidentId": "01K…",
"state": "identified",
"body": "A bad deploy is returning errors on checkout. We are rolling it back."
}
}
}
DSN keys
list_keys
DSN keys for a project (public key, DSN, label, status). Use the DSN to configure an SDK.
- Scope:
project:read· read-only - REST:
GET /v1/orgs/{org}/projects/{project}/keys - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_keys",
"arguments": {
"org": "acme",
"project": "checkout-api"
}
}
}
create_key
Create an additional DSN key for a project (for rotation or a second environment). Requires project:write.
- Scope:
project:write· mutating, audited - REST:
POST /v1/orgs/{org}/projects/{project}/keys - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project sluglabelstring
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_key",
"arguments": {
"org": "acme",
"project": "checkout-api",
"label": "staging"
}
}
}
set_key_status
Enable or disable a DSN key. Disabled keys are rejected at ingest within seconds. Requires project:write.
- Scope:
project:write· mutating, audited - REST:
PATCH /v1/orgs/{org}/projects/{project}/keys/{keyId} - Arguments:
orgstring (required) — Organization slugprojectstring (required) — Project slugkeyIdstring (required)statusstring (required) one ofactive,disabled
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_key_status",
"arguments": {
"org": "acme",
"project": "checkout-api",
"keyId": "01J…",
"status": "disabled"
}
}
}
Members
list_members
Organization members with role (admin, member, viewer) and email.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/members - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_members",
"arguments": {
"org": "acme"
}
}
}
API tokens
list_tokens
API tokens in the organization (name, scopes, last used, expiry). Secrets are never returned. Requires org:admin.
- Scope:
org:admin· read-only - REST:
GET /v1/orgs/{org}/tokens - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_tokens",
"arguments": {
"org": "acme"
}
}
}
revoke_token
Revoke an API token by id. Anything using it stops working immediately. Requires org:admin.
- Scope:
org:admin· mutating, audited - REST:
DELETE /v1/orgs/{org}/tokens/{id} - Arguments:
orgstring (required) — Organization slugidstring (required)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "revoke_token",
"arguments": {
"org": "acme",
"id": "01J…"
}
}
}
Billing & usage
get_agent_usage
Fix-agent credits and usage: this month's allowance and what is left of it, purchased credit remaining, which models the plan may use and what they cost per million tokens, and the most recent runs.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/agent-usage - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_agent_usage",
"arguments": {
"org": "acme"
}
}
}
get_usage
Exact usage and plan for the organization: plan limits, overage flag, daily accepted events by category, credit balance and expiry.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/usage - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_usage",
"arguments": {
"org": "acme"
}
}
}
get_billing_plans
Plan catalog with prices, included events, retention, overage rate, and whether checkout is available.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/billing/plans - Arguments:
orgstring (required) — Organization slug
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "get_billing_plans",
"arguments": {
"org": "acme"
}
}
}
set_overage
Turn pay-as-you-go overage on or off (off = hard cap at the plan's included events). Requires org:admin.
- Scope:
org:admin· mutating, audited - REST:
POST /v1/orgs/{org}/billing/overage - Arguments:
orgstring (required) — Organization slugenabledboolean (required)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "set_overage",
"arguments": {
"org": "acme",
"enabled": true
}
}
}
Agents
list_agent_activity
Recent agent (MCP) actions across the organization: tool, arguments, token, outcome, time.
- Scope:
org:read· read-only - REST:
GET /v1/orgs/{org}/agent-activity - Arguments:
orgstring (required) — Organization sluglimitinteger
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_agent_activity",
"arguments": {
"org": "acme"
}
}
}
Routes without a tool
POST /v1/orgs/{org}/tokens— Agents must not mint credentials; tokens are created by a human in Settings → Agents / API tokens.POST /v1/orgs/{org}/members— Adding a member (or changing a role) grants access that outlives the credential that granted it, so a leaked token or a misled agent could keep its foothold after revocation (#276). Human-only, in Settings → Members.GET /v1/orgs/{org}/projects/{project}/attachments/{id}— The bytes of a file an SDK attached to an event: binary and always served as a download, not something a tool result can carry. Agents get the metadata from list_issue_attachments; the file is fetched from this route with an event:read token, or from the issue page (#240).GET /v1/orgs/{org}/export— A bulk download of every row the org owns, streamed as NDJSON for a backup or a move; far beyond what a tool result can carry. Use curl with an org:admin token (P2.2).GET /v1/orgs/{org}/projects/{project}/export/events— A bulk stream of a project's stored event bodies from R2; a download, not a tool result (P2.2).DELETE /v1/orgs/{org}— Deleting an organization erases all of its data and cannot be undone. Owner-only, signed-in-only, with the slug typed back, in Settings → General (P2.2).DELETE /v1/orgs/{org}/members/{userId}— A leaked token must not be able to remove the admins who would revoke it (#276). Human-only, in Settings → Members.POST /v1/orgs/{org}/billing/checkout— Browser redirect to Stripe Checkout; purchases stay human-initiated.POST /v1/orgs/{org}/billing/portal— Browser redirect to the Stripe Billing Portal.POST /v1/orgs/{org}/billing/agent-credits/checkout— Browser redirect to Stripe Checkout for a fix-agent credit pack; purchases stay human-initiated.POST /v1/orgs/{org}/projects/{project}/artifact-bundles— Binary source-map upload; use sentry-cli or the REST endpoint directly.POST /v1/orgs/{org}/repo-connection— Stores a credential that can write to the customer's source code; connecting a repository stays human-initiated, like minting a token.DELETE /v1/orgs/{org}/repo-connection— The same human-only gate as connecting: an agent must not be able to sever, or silently re-point, the org's source-code access.POST /v1/orgs/{org}/projects/{project}/issues/{shortId}/fix-agent— Server-sent event stream that runs a model; an agent wanting the same material should call get_fix_context and do its own reasoning rather than nest an agent inside a tool call.POST /v1/orgs/{org}/devices— A device registers itself with its own push credentials from the app; there is nothing for an agent to do here, and a tool that could write push tokens could redirect somebody's pages to another handset.POST /v1/orgs/{org}/chat— The mobile companion's own model loop, which runs THESE tools. An agent calling it would be nesting an agent inside a tool call to reach the same registry it already has — the same reason the fix-agent stream is exempt. Its mutations are the mobile allowlist and each needs a person to tap a confirmation card, which a tool call cannot do.POST /v1/orgs/{org}/test-page— Rings the caller's own physical phone at critical-alert insistence to prove their paging setup works. Session-only by construction, and making somebody's handset ring is a thing a person asks for about their own hardware, not a thing an agent does on their behalf.GET /v1/orgs/{org}/devices/vapid-key— The application server key a BROWSER needs to call PushManager.subscribe(). It is public key material for a client-side API an agent has no way to call; list_devices already reports what is registered.POST /v1/orgs/{org}/services/{id}/inbound-key— Mints a credential that can open an incident on this service, shown exactly once. Minting stays human-initiated for the same reason API tokens do — and rotating one silently breaks every integration still pointed at the old key, which is a decision a person makes.POST /v1/orgs/{org}/devices/{id}/receipt— A handset confirms a push it actually received. An agent confirming on its behalf would mark a silent device fresh, which is exactly the state the receipt exists to detect.