Skip to main content
Glama

SolidPing

Distributed, self-hostable uptime monitoring. 43 check types, multi-region workers, private agents, status pages, incidents and on-call escalation — in a single Go binary.

Build Coverage Release Go Go Reference License

Live Status Docs Container


From docker run to the first result

https://github.com/user-attachments/assets/3bdaf8eb-7d20-45ab-ae15-e0ac5835c3a2

Start to finish in 34 seconds: docker run in a terminal, the first sign-in, an HTTP check created by pasting a URL, and its first response times from two regions. Recorded from a real SolidPing server, nothing here is a mock-up. The Tour page has a longer cut if the player above does not load.

Screenshots

Checks list

New-check form

Check detail

Related MCP server: uptimepage

Try it

Hosted

www.solidping.io — sign up, no card needed

Live status page

status.solidping.io — a real SolidPing instance watching the production one, from another provider in another country

Documentation

docs.solidping.io

Self-host

docker run -p 4000:4000 --hostname solidping ghcr.io/fclairamb/solidping (also on Docker Hub as fclairamb/solidping) — SQLite by default, no other service needed. First login is admin@solidping.io / solidpass, and you must change it (see Default Credentials). Prefer a bare binary? Every release also publishes one for Linux, macOS and Windows — see the installation guides. Also: brew install fclairamb/tap/solidping (tap), scoop bucket add fclairamb https://github.com/fclairamb/scoop-bucket then scoop install solidping, a Helm chart, and a Railway setup.

Overview

SolidPing is a multi-tenant monitoring system that enables organizations to monitor their infrastructure through distributed workers executing health checks. It's designed for low resource consumption and easy self-hosting.

Key Features

  • 43 check types: HTTP, TCP, UDP, ICMP, DNS, DNSBL, NTP, SSL/Domain, SSH, RDP, VNC, FTP/SFTP, SMTP/POP3/IMAP, Email (JMAP passive inbox), WebSocket, SIP, gRPC, Prometheus, 7 databases (Postgres, MySQL, MSSQL, Oracle, ClickHouse, MongoDB, Redis), 3 message queues (Kafka, RabbitMQ, MQTT), Docker, Kubernetes, SNMP, Freebox line, game server (Source/A2S, Minecraft), headless browser, custom JS, website crawl, health endpoint, heartbeat

  • Distributed workers: Multi-region check execution with lease-based scheduling, per-region check periods with spread control, and per-org check-rate quotas

  • Private locations: Deported agents run checks from inside your own network over an outbound WebSocket, with per-org agent quotas

  • Multi-tenant: Organization-scoped data isolation, RBAC, 2FA (TOTP), labels with autocomplete

  • Low footprint: Single binary; SQLite, embedded Postgres, or external Postgres

  • Fast checks: Sub-minute frequencies supported

  • Notifications (10 native): Slack (OAuth + threads + Marketplace install), Discord (OAuth + webhook), Email, Webhooks, Google Chat, Mattermost, Ntfy, PagerDuty, Pushover, Web Push (VAPID)

  • Incidents: Adaptive resolution with cooldown, group-incident correlation (one alert per outage, not per check), acknowledgment, snooze, manual resolve, and per-incident comments

  • Check groups: Organize checks into groups with grouped pagination and group-level incident correlation

  • On-call & escalation: Rotation schedules with overrides, multi-step escalation policies (user / schedule / connection / all-admins targets, repeats)

  • Credentials encryption at rest: Envelope encryption with out-of-band master key; secrets never echoed back to the dashboard

  • SSH tunnels: Reach otherwise-unreachable targets through SSH jump hosts

  • Status pages: Sections, resources, public availability metrics, locale-aware date formatting

  • Maintenance windows: Recurring suppression of alerts

  • JavaScript scripting: Sandboxed custom monitoring logic

  • Browser monitoring: Headless Chrome via Rod

  • MCP server: AI/LLM tool access via Model Context Protocol (listed on Smithery)

  • SSO / OAuth: Google, GitHub, GitLab, Microsoft, Slack, Discord, plus generic OIDC, SAML, and LDAP / Active Directory (per-provider enable toggle, with self-service token revocation)

  • Observability: Prometheus /metrics, Sentry integration, OpenTelemetry

  • CLI client: Manage checks and results from the terminal

  • i18n: Multi-language dashboard (English, French, German, Spanish)

Quick Start

Prerequisites

  • Go 1.24+

  • PostgreSQL 15+

  • Docker (for development)

  • Bun (for frontend development)

Development Setup

# Start PostgreSQL
docker-compose up -d

# Build and run
make build && ./solidping serve

# Or use hot reload for development
make dev-test   # Backend + frontend with hot reload

Default Credentials

  • Email: admin@solidping.io

  • Password: solidpass

  • Organization: default

Both halves of that pair are published here, so the first login on a fresh database must set a new password before the account can do anything else. The dashboard takes you straight to the form; over the API the login succeeds and every endpoint except POST /api/v1/auth/change-password, GET /api/v1/auth/me and POST /api/v1/auth/logout answers 403 with code PASSWORD_CHANGE_REQUIRED until you rotate it.

API Example

# Get a JWT token
TOKEN=$(curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"org":"default","email":"admin@solidping.io","password":"solidpass"}' \
  'http://localhost:4000/api/v1/auth/login' | jq -r '.accessToken')

# List checks
curl -s -H "Authorization: Bearer $TOKEN" \
  'http://localhost:4000/api/v1/orgs/default/checks'

Supported Check Types

Network

Protocol

Description

HTTP/HTTPS

Status codes, body matching, JSON assertions, Basic Auth

TCP

Port connectivity

UDP

Port reachability

ICMP

Ping

DNS

Record resolution

DNSBL

DNS blocklist (RBL) membership

NTP

Time server reachability and clock drift

WebSocket

Connection check

SIP

VoIP SIP server (OPTIONS ping)

Security & Certificates

Protocol

Description

SSL/TLS

Certificate validity and expiration

Domain

Domain name expiration (WHOIS)

Email

Protocol

Description

SMTP

Server connectivity, STARTTLS, AUTH

POP3

Server availability

IMAP

Server availability

Email (JMAP)

Passive inbox monitoring — receive a known message via JMAP and assert delivery

Databases

Protocol

Description

PostgreSQL

Connection + query execution

MySQL/MariaDB

Connection + query execution

MSSQL

Connection + query execution

Oracle

Connection + query execution

ClickHouse

Connection + query execution

MongoDB

Ping command

Redis

PING command

Remote Access

Protocol

Description

SSH

Server availability

RDP

Pre-auth RDP negotiation handshake (no credentials)

FTP

Server availability

SFTP

Server availability

Message Queues

Protocol

Description

Kafka

Broker connectivity

RabbitMQ

Broker connectivity

MQTT

Broker connectivity

Infrastructure

Type

Description

Docker

Container health

Kubernetes

Cluster / API server health

SNMP

Device monitoring

gRPC

Service health

A2S

Source / Steam game server query (Valve A2S)

Minecraft

Minecraft server query

Prometheus

Scrape a Prometheus endpoint and assert on a metric

Specialized

Type

Description

Heartbeat

Passive monitoring via incoming pings

JavaScript

Sandboxed custom monitoring logic

Browser

Headless Chrome (Rod) — JS, CSS, full render

Freebox Line

Freebox xDSL/fiber line quality (via connected Freebox)

Configuration

Everything is configured with SP_-prefixed environment variables. Precedence: environment variables > config.local.yml > config.yml > defaults.

You only need the database settings to get started — the defaults cover the rest.

SQLite (the default — good for a single instance)

Nothing to configure. The image already stores the SQLite database and every uploaded blob (org logos, status-page assets, screenshots) under /data, so a single mounted named volume is enough:

docker run -p 4000:4000 \
  --hostname solidping \
  -v solidping-data:/data \
  ghcr.io/fclairamb/solidping

--hostname solidping is not optional: the worker name is derived from the hostname and must match ^[a-z][a-z0-9-]{2,20}$. Docker's default hostname is the random container ID, which starts with a digit most of the time, and the server then refuses to start. Pass --hostname, or set SP_NODE_NAME instead.

If you use a bind mount instead of a named volume (-v ./solidping-data:/data), the host directory keeps its own ownership, which is usually not writable by the image's nonroot user (uid/gid 65532). Either chown 65532:65532 the host directory first, or run with -u "$(id -u):$(id -g)". A named volume, as used above, doesn't have this problem — Docker seeds it from the image with the right ownership.

Schema migrations run on first boot, so point it at an empty database and let it create its own tables:

docker run -p 4000:4000 \
  --hostname solidping \
  -e SP_DB_TYPE=postgres \
  -e SP_DB_URL='postgresql://solidping:password@postgres:5432/solidping?sslmode=disable' \
  ghcr.io/fclairamb/solidping

sslmode=disable is right for a database on the same private network, and is what a stock postgres container accepts — it serves no TLS, so sslmode=require fails against one with SSL is not enabled on the server. For a managed or remote database, use sslmode=require (or verify-full) instead.

The variables you actually need

Variable

Default

Description

SP_DB_TYPE

sqlite

sqlite or postgres

SP_DB_URL

—

PostgreSQL connection string (required when SP_DB_TYPE=postgres)

SP_DB_DIR

/data in the image, . for the bare binary

Where the SQLite file lives — set it to a volume

SP_SERVER_LISTEN

:4000

Listen address

SP_BASE_URL

http://localhost:4000

Public URL, used in links and notifications

SP_NODE_NAME

the hostname

Worker name, ^[a-z][a-z0-9-]{2,20}$. Set it, or pass --hostname — the server will not start if the hostname does not match

SP_LOG_LEVEL

info

debug, info, warn, error

That is the whole getting-started surface. Everything else — authentication and SSO, email and the other notification channels, custom domains and TLS, multi-region workers, data retention, storage — is optional and documented at docs.solidping.io:

Configuration overview

every variable, grouped by area

Database

connection strings, SSL modes, pooling, backups

Authentication

OAuth providers, OIDC, SAML, LDAP, 2FA

Notifications

Slack, Discord, email, webhooks and the rest

Architecture

Core Components

  • API Server: REST API for managing checks, incidents, and results

  • Dashboard (web/dash0): Admin UI (React + TanStack Router + shadcn/ui)

  • Status Page (web/status0): Public-facing status dashboard

  • Workers: Distributed agents executing monitoring checks

  • Notifications: Slack, Discord, Email, Webhooks, Google Chat, Mattermost, Ntfy, PagerDuty, Pushover, Web Push

  • Database: PostgreSQL (partitioned results) or SQLite

Technology Stack

  • Backend: Go 1.24+, go-chi/chi v5, Bun ORM, koanf

  • Frontend: React 19, TypeScript, Vite, TanStack Router/Query, Tailwind CSS, shadcn/ui

  • Database: PostgreSQL (production), SQLite (development/single-node)

Project Structure

solidping/
├── server/
│   ├── main.go                  # CLI entry point (serve, migrate, client)
│   └── internal/
│       ├── app/                 # Server setup, services, embedded assets
│       ├── handlers/            # HTTP handlers + business logic
│       ├── checkers/            # Protocol checker implementations
│       ├── notifications/       # Notification channels
│       ├── db/                  # Bun models + Postgres/SQLite migrations
│       └── middleware/          # Auth, CORS, org context
├── web/
│   ├── dash0/                   # Admin dashboard (React)
│   └── status0/                 # Public status page
├── docker-compose.yml           # Development PostgreSQL
├── Dockerfile                   # Production container
└── Makefile                     # Build targets

Development

Commands

make build            # Build complete application
make dev-test         # Hot-reload backend + frontend
make dev-backend      # Backend only with hot reload (air)
make dev-dash0        # Dashboard dev server
make test             # Run backend tests
make lint             # Lint all code
make fmt              # Format all code
make docker-build     # Build Docker image

CLI Client

# Build the CLI
make build-cli

# Usage
./bin/sp auth login
./bin/sp checks list
./bin/sp results list

Goals

Primary

  • Many protocols and test types

  • Low memory footprint

  • Fast execution (sub-minute checks)

  • Easy self-hosting (single binary + PostgreSQL)

  • Cross-platform (Linux, macOS, Windows)

  • Public status pages

Non-Goals

  • Multi-step transactional / scripted user-flow testing (use Playwright directly for that)

  • Application Performance Monitoring / RUM (use Datadog, New Relic, or Site24x7)

Inspiration

Contributing

Bug reports and pull requests are welcome — see CONTRIBUTING.md for local setup and PR conventions. Found a security issue? See SECURITY.md rather than opening a public issue.

License

AGPL-3.0 - See LICENSE.

Available Tools

23 tools
create_checkCreate checkAInspect

Create a new monitoring check and return it (uid, slug, placement, resolved periods). If you don't know what config shape a given type expects, call list_check_types with type first to fetch a working starting config, then use validate_check to dry-run before creating. An enabled check starts running on its next tick and opens an incident after its confirmation period; pass enabled:false to create it paused. A duplicate slug is rejected with a conflict, never merged — use update_check to change an existing check. Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoHuman-readable name, e.g. "API production". Auto-generated from URL if omitted.
slugNoURL-friendly slug (3-20 lowercase letters/digits/hyphens), e.g. "api-prod". Auto-generated if omitted.
typeNoCheck type. Allowed: http, tcp, icmp, dns, heartbeat, email, domain, ssl, smtp, udp, ssh, pop3, imap, websocket, postgresql, ftp, sftp, js, mysql, redis, mongodb, mssql, oracle, clickhouse, grpc, kafka, mqtt, a2s, minecraft, rabbitmq, snmp, docker, browser, freebox_line, dnsbl, sip, kubernetes, ntp, rdp, vnc, prometheus, private-location, crawl, health. Inferred from config if omitted.
configYesCheck-specific config. Shape depends on type. Example for http: {"url": "https://example.com", "method": "GET"}. Use list_check_types with type to discover the shape for other types.
labelsNoKey-value labels for organization and filtering, e.g. {"env":"production","team":"api"}.
periodNoCheck interval as HH:MM:SS, e.g. "00:00:30" for 30 seconds, "00:01:00" for 1 minute (default).
enabledNoWhether the check should run. Default true.
regionsNoRegion slugs to pin the check to, e.g. ["eu-west-1","us-east-1"]. An explicit list means placement "pinned": the check runs from exactly these regions and is never moved. When omitted, the check is placed automatically (placement "auto"): the scheduler picks regionCount healthy regions from the org's default_regions, then the system default, then every other declared region, and moves the check off a region that goes dark. (An org whose own default_regions names a private location keeps pinned checks on those defaults.)
placementNo"pinned" or "auto". Omit to infer it: regions given means pinned, otherwise auto. "auto" cannot be combined with regions. Private (@) regions are pinned-only.
failQuorumNoMulti-region quorum: how many of the check's regions must be failing, for the confirmation period, before it is down and an incident opens. "all", "majority" or a whole number such as "2" (clamped to the region count). The default is all regions for 1-2 regions and a majority for 3+. Fewer failing regions than the quorum is a "regional issue": the check shows warning and no incident opens. "all" keeps the per-result rule: any passing region resets the confirmation. Omit for the default.
regionPoolNoAutomatic placement only: the cloud region slugs the scheduler may choose from, e.g. ["paris","gravelines"]. Omit for any cloud region. Implies placement auto.
descriptionNoFree-text description shown in the UI.
regionCountNoAutomatic placement only: how many regions run the check (default 2, capped by the eligible regions and the org's checks-per-minute limit; the response carries a PLACEMENT_REGION_COUNT_REDUCED warning when reduced). Implies placement auto.
checkGroupUidNoAssign the check to a check group (UID or slug), e.g. "core-services".
recoveryPeriodSecondsNoWall-clock seconds the check must stay UP before auto-resolving an incident. Any failure inside the window resets the recovery clock. 0 = resolve immediately. Range 0–86400. Default 120.
confirmationPeriodSecondsNoWall-clock seconds to wait after the first failure before opening an incident. 0 = open immediately on the first failure. Range 0–86400 (one day). Default 120.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesCheck UID.
nameNoHuman-readable name.
slugNoURL-friendly slug.
typeNoCheck type, e.g. "http".
configNoCheck-specific configuration for the type.
labelsNoKey-value labels.
periodNoCheck interval as HH:MM:SS.
statusNoSynthesized status: up, down, validating, created or degraded.
enabledNoWhether the check runs.
regionsNoRegions the check runs from.
createdAtNoRFC3339 creation timestamp.
placementNo"pinned" or "auto".
descriptionNoFree-text description.
lastResultAtNoRFC3339 timestamp of the newest real result.
checkGroupUidNoCheck group UID, when the check belongs to a group.
statusChangedAtNoRFC3339 timestamp of the last status change.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnly/openWorld/idempotent/destructive hints, and the description adds substantial context beyond them: an enabled check starts on its next tick and opens an incident after its confirmation period, duplicate slugs are rejected with a conflict and never merged, and creation requires the mcp scope with at least the user role (mcp:read tokens refused). This is rich behavioral disclosure; it stops short of 5 only because rate limits or exact failure payloads are not described.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and return values in the first sentence, then layers prerequisites, lifecycle behavior, error semantics and required scopes in descending priority. Five sentences, no filler; each carries a distinct fact an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter mutation with nested config, the description covers the gaps structured data cannot: scope/role prerequisites, duplicate-slug conflict behavior, the paused-creation path, and the recommended discovery/validation workflow. An output schema exists and describes return values, so the brief return summary is sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents every parameter in depth, including placement/regions interaction, quorum rules and period ranges. The description reinforces 'enabled:false creates it paused' and the type/config dependency, but adds no syntax or format detail the schema does not already carry, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a new monitoring check'), plus the scope of what is returned (uid, slug, placement, resolved periods). It explicitly names update_check as the tool for modifying existing checks, so an agent can separate it from its siblings without reading either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit sequencing guidance: call list_check_types with the type first to get a working config shape, then validate_check to dry-run before creating. It also states the alternative (update_check) and the condition that selects it (changing an existing check), and explains the enabled:false escape hatch for creating paused.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_status_pageCreate status pageAInspect

Create a new status page for the organization and return the created page. A duplicate slug is rejected with a conflict, never merged. Only one page can be the default: the first page always becomes it, and isDefault:true demotes the previous default. Every new page is seeded with a default "Services" section and starts enabled and public — use manage_status_page_section to add more sections and update_status_page to edit the page later. Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesStatus page display name (required), e.g. "Public status".
slugYesURL-friendly slug (required, unique per org), e.g. "public".
languageNoLanguage code, e.g. "en" or "fr".
customCssNoCustom CSS injected into the public page as a <style> element. Overrides the theme's CSS custom properties (--brand, --background, --foreground, --card, --border, the status colors, and the .dark variant). Max 64 KB; @import is rejected.
isDefaultNoWhether this is the org's default status page (only one allowed).
visibilityNoVisibility setting. Allowed: "public", "private". Default "public".
autoPublishNoAutomatically publish incidents affecting this page's resources as public incidents. New pages default to true; pages that existed before this feature shipped default to false.
autoResolveNoWhat an auto-created publication does when its incident resolves. Allowed: "always", "if_untouched" (default — a publication a human has edited is left for them to close), "never".
descriptionNoOptional free-text description shown in the UI.
historyDaysNoDays of history to show on the page (default 90).
showAvailabilityNoDisplay availability percentage on the public page.
showResponseTimeNoDisplay response-time charts on the public page.
autoPublishDelaySecondsNoDebounce in seconds before an incident becomes public (default 60). 0 publishes immediately. An incident that resolves inside the delay is never published at all.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesStatus page UID.
nameNoDisplay name.
slugNoURL-friendly slug.
enabledNoWhether the public page is served.
createdAtNoRFC3339 creation timestamp.
isDefaultNoWhether this is the organization's default page.
visibilityNo"public", "private" or "password".
historyPeriodNoHistory window: "24h", "7d", "30d" or "90d".

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by disclosing concrete side effects and constraints: duplicate slugs are rejected with a conflict rather than merged, the first page auto-becomes default and isDefault:true demotes the previous default, every page is seeded with a Services section and starts enabled/public, and it requires the mcp scope (mcp:read refused) plus user role.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences, front-loaded with the core action and conflict behavior before the follow-up routing and auth requirements. No filler, though the auth sentence is somewhat appended rather than integrated.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema already exists so return-value description is not needed, and the description covers the remaining gaps an agent would care about: conflict handling, default-page side effects, seeding, initial state, and authorization requirements.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 13 parameters in detail, establishing a baseline of 3. The description adds only marginal parameter meaning (isDefault demotion semantics, default-enabled/public state) beyond what the schema and annotations already carry.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Create a new status page for the organization') with the return value named, and it distinguishes itself from siblings by pointing to manage_status_page_section and update_status_page for the follow-up operations it does not cover.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to update_status_page and manage_status_page_section for later edits and section management, and the duplicate-slug rule implies this tool is only for first-time creation. There is no explicit 'do not use if the page already exists' exclusion, keeping it short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_checkDelete checkA
DestructiveIdempotent
Inspect

Soft-delete a monitoring check by UID or slug. The check stops running immediately, its active incidents are resolved and its scheduling jobs removed; historical results are kept. A check that other checks tunnel through is refused. To stop a check without losing it, use update_check with enabled:false instead. Returns {deleted: true, identifier}. Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesCheck UID or URL-friendly slug, e.g. "api-prod" or "63d49e55-97e3-4e8c-b7ab-c862de7a43f3".

Output Schema

ParametersJSON Schema
NameRequiredDescription
deletedYesAlways true on success.
identifierYesThe UID or slug that was deleted.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (destructiveHint/idempotentHint) by enumerating exactly what happens: check stops, active incidents resolved, scheduling jobs removed, historical results kept. It also discloses the auth requirements (mcp scope, mcp:read refused, user role minimum) and the refusal case, which annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and outcome, then layers in the caveat and alternative. Every clause carries distinct information (side effects, refusal rule, alternative tool, auth) with no padding or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be detailed, yet the description still names them. Combined with side-effect disclosure, refusal semantics, alternative routing and auth preconditions, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single identifier parameter is fully documented with examples in the schema, so the description only restates 'by UID or slug'. It adds no syntax or format detail beyond the structured field, which is the expected baseline here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Soft-delete a monitoring check') plus the accepted identifier forms (UID or slug). It is clearly distinguishable from siblings like update_check and get_check, and 'soft-delete' signals the mutation semantics up front.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative ('To stop a check without losing it, use update_check with enabled:false instead') and states the exclusion condition (checks other checks tunnel through are refused). Both when-to-use and when-not-to-use are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_status_pageDelete status pageA
DestructiveIdempotent
Inspect

Soft-delete a status page by UID or slug: the page disappears from the API and the public site, taking its sections and resources with it, and its uploaded brand assets are deleted. There is no undelete — use update_status_page with enabled:false to take a page down without destroying it. Returns {deleted: true, identifier}. Use delete_status_page_section or delete_status_page_resource to remove part of a page instead. Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesStatus page UID or URL-friendly slug, e.g. "public".

Output Schema

ParametersJSON Schema
NameRequiredDescription
deletedYesAlways true on success.
identifierYesThe identifier that was deleted.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true and idempotentHint=true, and the description goes well beyond them: it discloses the soft-delete semantics, the cascade (sections and resources go with it), that uploaded brand assets are physically deleted, that there is no undelete, and the auth requirement (mcp scope, mcp:read refused, user role). This is exactly the additional context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action and its cascade, then the alternative, then the return shape, then auth — every clause carries distinct information with no filler despite the length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers destructive scope, irreversibility, cascading effects, auth prerequisites, alternatives, and even the return value (redundant given the output schema, but harmless). Nothing an agent needs before invoking this irreversible operation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single identifier parameter is fully documented in the schema, including the slug example. The description's 'by UID or slug' restates what the schema already says, adding no new syntax or format detail. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Soft-delete a status page by UID or slug') and immediately distinguishes itself from siblings by naming update_status_page with enabled:false as the non-destructive alternative. An agent can identify this tool's role without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when-not to use it ('There is no undelete — use update_status_page with enabled:false') and routes partial deletions to section/resource tools. The only nit is that it names delete_status_page_section/delete_status_page_resource while the actual siblings are manage_status_page_section/manage_status_page_resource, but the intent is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnose_checkDiagnose checkA
Read-onlyIdempotent
Inspect

Return everything an operator would want to look at to diagnose a single check's current state in one call: current status, recent raw results across regions, any active incident, and the most recent resolved incident. Use this instead of chaining list_results + list_incidents when a human asks "what's wrong with check X?". Returns {check, freshness, regionalIssue, recentResults, activeIncident, lastResolvedIncident} — freshness and regionalIssue are omitted when there is nothing to report, the incidents are null when there are none. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesCheck UID or slug (e.g. "api-prod" or a UUID).
recentResultsLimitNoRecent raw results per region (1-20, default 5).

Output Schema

ParametersJSON Schema
NameRequiredDescription
checkYes
freshnessNoOne sentence per silent region naming it and since when it has gone quiet; empty when every region is reporting.
recentResultsYesNewest-first raw results, trimmed to recentResultsLimit per region; includes region, output and durationMs.
regionalIssueNoOne sentence describing the regional issue (some, but fewer than the quorum, of the check's regions failing); empty when there is none.
activeIncidentYesCurrently-open incident for the check, or null when none is open.
lastResolvedIncidentYesMost recently resolved incident for the check, or null when there is none.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), yet the description adds genuinely new context: the return envelope keys, that freshness and regionalIssue are omitted when empty and incidents are null when none exist, and the auth requirement ('works with mcp:read tokens'). That is exactly the kind of behavioral detail annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then the usage rule, then the return shape and auth note in a logical order. The return-shape sentence is dense with parenthetical qualifiers, slightly overlong, but every sentence carries distinct information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description is not obligated to explain return values, yet it briefly summarizes the envelope and its omission semantics. Combined with the usage rule and auth note, an agent has everything needed to invoke this correctly on the first try.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so identifier (UID or slug) and recentResultsLimit (1-20, default 5) are already fully documented in the schema. The description references 'check X' generically and adds no format, default, or constraint detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (diagnose) plus resource (a single check) and enumerates exactly what it aggregates: current status, recent raw results across regions, active incident, and last resolved incident. It explicitly distinguishes itself from the aggregation siblings list_results + list_incidents, so an agent can separate it from the many list_*/get_* tools without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use rule ('when a human asks "what's wrong with check X?"') and names the alternative it replaces (chaining list_results + list_incidents). The selection condition is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_checkGet checkA
Read-onlyIdempotent
Inspect

Get a single check's metadata by UID or slug; ask for extras with with=lastResult,lastStatusChange. For a full triage briefing (current status + recent results + active incidents), prefer diagnose_check; to search by name or label, use list_checks. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
withNoComma-separated extra fields: lastResult — most recent result lastStatusChange — when status last changed Example: "lastResult,lastStatusChange".
identifierYesCheck UID or URL-friendly slug, e.g. "api-prod" or "63d49e55-97e3-4e8c-b7ab-c862de7a43f3".

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesCheck UID.
nameNoHuman-readable name.
slugNoURL-friendly slug.
typeNoCheck type, e.g. "http".
configNoCheck-specific configuration for the type.
labelsNoKey-value labels.
periodNoCheck interval as HH:MM:SS.
statusNoSynthesized status: up, down, validating, created or degraded.
enabledNoWhether the check runs.
regionsNoRegions the check runs from.
createdAtNoRFC3339 creation timestamp.
placementNo"pinned" or "auto".
descriptionNoFree-text description.
lastResultAtNoRFC3339 timestamp of the newest real result.
checkGroupUidNoCheck group UID, when the check belongs to a group.
statusChangedAtNoRFC3339 timestamp of the last status change.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false), and the description reinforces rather than contradicts them. It adds value annotations don't carry: the tool 'works with mcp:read tokens', which tells the agent about auth scope — useful for a read-only agent. It does not, however, describe pagination, error cases, or what 'metadata' excludes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero waste: the core operation and lookup key come first, then the extras hint, then the alternatives routing. Each clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-parameter read tool with full schema coverage and an output schema (so return shape need not be explained), the description covers purpose, routing, and auth scope completely. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented with format examples in the schema. The description's mention of `with=lastResult,lastStatusChange` restates what the schema property description already spells out, adding no new syntax or defaulting semantics. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get a single check's metadata') plus the lookup key ('by UID or slug'), which immediately separates it from list_checks and diagnose_check. An agent can identify this as the single-object retrieval tool without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names two alternatives and the conditions that select them: diagnose_check for a full triage briefing, list_checks for search by name or label. No inference is required to route between the three.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_incidentGet incidentA
Read-onlyIdempotent
Inspect

Get a single incident by UID; an unknown UID fails with an "incident not found" error. Returns the incident object — number, state, timestamps, failure counts — plus the check with with=check and up to 50 timeline events with with=events. include=["notifications"] adds the incident's notification attempts (one row per dispatch target with its delivery status, channel and recipient, newest first), filtered by status and capped by limit. Use list_incidents to search and filter across incidents, and diagnose_check for a check's full triage briefing. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
uidYesIncident UID returned by list_incidents or diagnose_check.
withNoComma-separated extra fields. "check" includes the underlying check; "events" includes up to 50 most-recent timeline events (status transitions, notifications, manual notes). Example: "check,events".
limitNoWith include=notifications: max attempts (1-500, default 20).
statusNoWith include=notifications: only attempts in this delivery status. Allowed: pending, sent, failed, cancelled, skipped.
includeNoExtra lists to return with the incident. An unknown value is an error.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesIncident UID.
kindNoWhat the incident is about: check, slo_burn or degraded.
checkNoUnderlying check, when requested with with=check.
stateNoactive or resolved.
titleNoCustom title, when one was set.
eventsNoTimeline events (status transitions, notifications, manual notes), newest first; present when with=events was passed.
numberNoShort per-org reference, e.g. 42.
checkUidNoUID of the check the incident is about.
checkNameNoName of that check.
checkSlugNoSlug of that check.
startedAtNoRFC3339 timestamp when the incident opened.
resolvedAtNoRFC3339 timestamp when it resolved; absent while active.
descriptionNoCustom description, when one was set.
failureCountNoNumber of failures recorded for the incident.
relapseCountNoNumber of times the incident reopened.
notificationsNoNotification attempts, newest first; present when include=notifications was passed.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, yet the description still adds real behavioral context: unknown UIDs produce an 'incident not found' error, notifications are returned newest-first one row per dispatch target, and read access requires mcp:read tokens. It stops short of describing pagination or truncation behavior for timeline events beyond the 50 cap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core operation, then qualification, then alternatives. The middle sentence is long and packs several clauses, but nearly every clause carries information an agent needs; little is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema already exists, the description need not explain return shapes, yet it still summarizes returns (number, state, timestamps, failure counts) and covers error behavior, auth scope, and the interaction among with/include/status/limit. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds relational meaning the schema states only per-field: it explains that with=check/with=events are opt-in extras, that include=["notifications"] is filtered by status and capped by limit, and that events are capped at 50 most-recent. This ties the parameters together rather than restating them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource and scope: 'Get a single incident by UID'. It immediately distinguishes itself from the sibling list_incidents ('Use list_incidents to search and filter across incidents') and names the exact identifier type the tool consumes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to alternatives with conditions: list_incidents for search/filter over many incidents, diagnose_check for a check's triage briefing. It also states the failure mode for an unknown UID, so the agent knows what to expect when guessing a UID.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_status_pageGet status pageA
Read-onlyIdempotent
Inspect

Get one status page by UID or slug and return it. with=sections embeds its sections and their resources. include adds lists next to the page fields: "sections" (section metadata, display order), "resources" (the resources of the section named by sectionIdentifier) and "incidents" (the customer-facing incident publications on the page, filtered by state and active). Use list_status_pages to browse every page, and manage_status_page_section / _resource / _incident to change them. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
withNo"sections" to include nested sections and their resources
stateNoWith include=incidents: only publications in this public state. Allowed: "investigating", "identified", "monitoring", "resolved".
activeNoWith include=incidents: when true, only publications that are not resolved.
includeNoExtra lists to return with the page. An unknown value is an error. Do not combine "sections" with with=sections.
identifierYesStatus page UID or URL-friendly slug, e.g. "public".
sectionIdentifierNoSection UID or slug whose resources include=resources returns (required with it).

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesStatus page UID.
nameNoDisplay name.
slugNoURL-friendly slug.
enabledNoWhether the public page is served.
sectionsNoSections; absent unless with=sections (nested resources included) or include=sections (section metadata only) was passed.
createdAtNoRFC3339 creation timestamp.
incidentsNoIncident publications on the page; present with include=incidents.
isDefaultNoWhether this is the organization's default page.
resourcesNoResources of the section named by sectionIdentifier; present with include=resources.
visibilityNo"public", "private" or "password".
historyPeriodNoHistory window: "24h", "7d", "30d" or "90d".

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/idempotent/non-destructive, but the description adds genuinely new context: the mcp:read token requirement and the behavioral effect of each include value (sections embed their resources; incidents are filtered by state and active). It stops short of describing pagination or error behavior for a missing identifier.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then the modifier semantics, then sibling routing – a sensible order with no filler. The include parentheticals are dense, but each clause carries real information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter read tool with an output schema present, the description covers the modifier interactions, filtering semantics, and auth scope, so nothing essential is missing. Return-value documentation is correctly delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description earns more by explaining what each include list actually returns (section metadata/display order, resources of sectionIdentifier, customer-facing incidents filtered by state and active) and by flagging the with=sections vs include=sections overlap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (get one status page by UID or slug) and immediately distinguishes itself from siblings by naming list_status_pages for browsing and the manage_status_page_* tools for mutation. An agent can route correctly without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternatives and the condition that selects them: browse with list_status_pages, change sections/resources/incidents with the manage_* tools. It also states the read-token scope, so the when-to-use picture is complete.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_check_groupsList check groupsA
Read-onlyIdempotent
Inspect

List all check groups for the organization. Check groups bundle related checks together for shared incident handling and dashboard organization, and each entry carries its slug, rolled-up status and check count. Returns {data: [...]}. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoCheck groups on this page.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, so the safety profile is covered. The description adds value beyond that by disclosing the auth scope ("works with mcp:read tokens") and enumerating the per-entry fields (slug, rolled-up status, check count), giving useful behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action and scope, followed by definitional and auth context. No redundant or wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety, an output schema present, and zero params, the description leaves nothing an agent needs missing. It even names the return shape, which is a bonus rather than a necessity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to document; baseline 4 applies. The description correctly implies a no-input, organization-scoped call.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("List all check groups") and further defines what a check group is, distinguishing it from the sibling list_checks/list_check_types. An agent can tell exactly what this returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the scope phrase "for the organization," but there is no explicit when-to-use/when-not guidance and the strong sibling alternatives (list_checks, list_check_types) are never mentioned. Adequate but with clear gaps.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_checksList checksA
Read-onlyIdempotent
Inspect

List monitoring checks for the organization, optionally filtered by name/slug substring, labels, or check group. Returns {data, pagination}; pass pagination.cursor back as cursor for the next page. Use this for browsing or filtering a fleet of checks. To investigate a single check's current health, use diagnose_check instead; if you already know its UID or slug, get_check is more direct. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
qNoCase-insensitive substring match on check name or slug, e.g. "api".
withNoComma-separated extra fields: lastResult — most recent result for each check lastStatusChange — when each check last changed status Example: "lastResult,lastStatusChange".
limitNoMax results (1-100, default 20).
cursorNoOpaque pagination cursor returned by a previous response. Omit on the first page.
labelsNoLabel filter as a JSON object. Returns checks that have ALL of the given labels with matching values (AND semantics). Example: {"env": "production", "team": "api"}.
checkGroupUidNoFilter to checks in this group (UID or slug), e.g. "core-services".

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoChecks on this page.
paginationNoCursor pagination state for the filter.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive behavior. The description adds useful context by stating it works with mcp:read tokens and explaining pagination via pagination.cursor. It does not cover rate limits or edge cases, but with annotations and an output schema, the added detail is solid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then return/pagination, then usage guidance and alternatives. Four sentences with no wasted words, each earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given six optional parameters, an existing output schema, and rich annotations, the description is complete enough. It covers filtering, pagination, sibling alternatives, and token scope; return structure is left to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all six parameters are already well documented. The description only summarizes filter categories ('name/slug substring, labels, or check group') and pagination, adding little syntax or meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List monitoring checks'), scope ('for the organization'), and optional filters. Distinguishes from siblings by naming diagnose_check and get_check, so an agent can tell it apart without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says 'Use this for browsing or filtering a fleet of checks' and routes to diagnose_check for a single check's health or get_check when the UID/slug is known. This gives clear when-to-use and when-not-to-use guidance with named alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_check_typesList check typesA
Read-onlyIdempotent
Inspect

List all monitoring check types supported by this server (e.g. http, tcp, dns, icmp, ssl), or with type, the ready-made sample configs of that type. Call it without arguments first when you don't know what type to use: it returns {data: [...]}, one entry per type with its description, enabled state, period bounds and secretFields. Then call it with type=: it returns {data: [...]} with one entry per matching type carrying its samples, each a complete, valid config to clone and modify (much more reliable than guessing field names). Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeNoOptional check type whose sample configs to return (e.g. "http", "dns", "tcp", "icmp", "ssl").

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoWithout type: check types this server supports, with their activation status. With type: one entry per matching check type, carrying its sample configs.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the read-only, idempotent, non-destructive profile, but the description adds the auth requirement (works with mcp:read tokens) and the shape/contents of each return entry (description, enabled state, period bounds, secretFields). The return-shape detail partly duplicates the output schema, so this is strong but not purely additive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The key guidance (no-args-first, then type-scoped) is front-loaded and each clause carries information. It is somewhat dense and repeats the {data: [...]} return shape twice, but there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, annotations covering the safety profile, and a single fully-documented optional parameter, the description provides everything an agent needs: both invocation modes, the recommended order, and the auth scope.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, but the description adds real meaning: it explains that 'type' selects which type's ready-made sample configs are returned and that each sample is a complete, valid config to clone. That is more than the schema's bare example list conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (monitoring check types) and clearly distinguishes its two behaviors: a no-argument listing of supported types versus a type-scoped return of sample configs. An agent can tell exactly what this tool does and how it differs from siblings like list_checks.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit sequencing rule: call it without arguments first when the type is unknown, then call it with type=<chosen type>. It also motivates the pattern (samples are reliable configs to clone rather than guessing field names), which is actionable when-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_incidentsList incidentsA
Read-onlyIdempotent
Inspect

List internal incidents (active or resolved) for the organization, filtered by check, state, or time range. Returns {data, pagination} — total, size, and a cursor naming the last row of a full page; the cursor is not read back on the next call yet, so move forward by narrowing since/until. Use diagnose_check for one check's incidents plus current health in one call, and get_status_page include=incidents for the customer-facing entries on a status page. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
sizeNoMax results (1-100, default 20).
withNoComma-separated extra fields: check — include the underlying check (slug, type, config) Example: "check".
sinceNoLower bound on incident start time (RFC3339), e.g. "2026-05-03T00:00:00Z".
stateNoComma-separated incident states. Allowed: active, resolved. Example: "active" or "active,resolved".
untilNoUpper bound on incident start time (RFC3339), e.g. "2026-05-04T00:00:00Z".
cursorNoOpaque pagination cursor returned by a previous response. Omit on the first page.
checkUidNoComma-separated check UIDs or slugs to filter by, e.g. "api-prod,db-prod".

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoIncidents on this page.
paginationNoPage state for the filter.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, but the description adds non-obvious behavior: the cursor returned in the response is not read back on the next call yet, so advancing requires narrowing since/until, plus it discloses that mcp:read tokens suffice. Both are genuinely beyond what the structured fields convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, purpose-front-loaded, and each block earns its place (filters, pagination caveat, alternatives, auth). The 'Returns {data, pagination}' clause mildly duplicates the existing output schema, which keeps it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, 7-param, zero-required list tool with an output schema, the description covers purpose, filters, pagination behavior, sibling routing, and auth scope. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents size, with, since, until, state, cursor, and checkUid in detail. The description only summarizes the filter axes (check, state, time range), which maps onto the schema without adding format or edge-case detail. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (internal incidents), plus scope: organization-wide, active or resolved, filterable by check/state/time. An agent can distinguish it from get_incident (single) and from the status-page tools without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes to alternatives with conditions: diagnose_check when you want one check's incidents plus current health in a single call, and get_status_page include=incidents for the customer-facing entries. This is when-to-use guidance naming the sibling that wins in each case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_regionsList regionsA
Read-onlyIdempotent
Inspect

List monitoring regions available to the organization (e.g. eu-west-1, us-east-1). Returns {data: [...]} — each region's slug, label and per-region metadata — plus defaultRegions, the org's default placement set. Use these slugs in the regions array of create_check or update_check. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoRegions available to this organization.
defaultRegionsNoThe org's default region slugs, used when a check has no explicit regions.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so safety is covered structurally. The description adds auth-specific detail the annotations do not carry ('works with mcp:read tokens') plus the defaultRegions payload, which is genuinely new behavioral context. Minor overlap with readOnlyHint keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what is listed, then the return shape, then the downstream consumer. Every sentence earns its place; the 'Read-only' clause is mildly redundant given readOnlyHint but is justified by the token-scope information it adds.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only listing tool with annotations and an output schema, the agent has everything needed: what comes back, the meaning of the slugs, and where those slugs are consumed. Nothing required for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4 and there is no syntax the description could add. It correctly spends its words on output semantics (slug/label/metadata, defaultRegions) instead of inventing parameter detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List monitoring regions available to the organization') and grounds it with concrete slug examples (eu-west-1, us-east-1), so it is immediately distinguishable from sibling lists like list_checks or list_check_types. The return shape (slug, label, metadata, defaultRegions) further pins down exactly what is being listed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'Use these slugs in the regions array of create_check or update_check' names the consuming sibling calls and the exact argument they feed. There is no explicit when-not or exclusion, but the usage context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_resultsList resultsA
Read-onlyIdempotent
Inspect

Query monitoring results (raw or aggregated) with filtering by check, type, status, region, period type, and time range. Use this for trend analysis or to inspect a specific window. For investigating a single check's current state, use diagnose_check instead. Returns {data, pagination, window, effectiveFilter}: data holds the result rows, window the time bounds actually queried, and effectiveFilter the period filter that ran after defaulting. Defaults: if periodType is omitted it falls back to "hour"; if periodStartAfter is omitted it falls back to a window matched to the finest periodType requested (raw=1h, hour=24h, day=30d, month=365d). Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
sizeNoMax results (1-100, default 20).
withNoComma-separated extra fields: durationMs — response time in ms durationMinMs — min response time in the bucket (aggregated rows only) durationMaxMs — max response time in the bucket (aggregated rows only) region — region the check ran in metrics — per-execution metrics output — full check output incl. error messages availabilityPct — uptime % (aggregated rows only) checkSlug — slug of the check checkName — human name of the check Example: "durationMs,output".
cursorNoOpaque pagination cursor returned by a previous response. Omit on the first page.
regionNoComma-separated region slugs, e.g. "eu-west-1,us-east-1".
statusNoComma-separated result statuses. Allowed: up, down, created, running, abandoned. "down" covers every genuine failure (down, timeout, error); "abandoned" is separate on purpose — it marks an attempt nothing was ever reported for, which is excluded from availability and is NOT downtime. Example: "down" or "down,abandoned".
checkUidNoComma-separated check UIDs or slugs to filter by, e.g. "api-prod,db-prod".
checkTypeNoComma-separated check types. Allowed: http, tcp, icmp, dns, heartbeat, email, domain, ssl, smtp, udp, ssh, pop3, imap, websocket, postgresql, ftp, sftp, js, mysql, redis, mongodb, mssql, oracle, clickhouse, grpc, kafka, mqtt, a2s, minecraft, rabbitmq, snmp, docker, browser, freebox_line, dnsbl, sip, kubernetes, ntp, rdp, vnc, prometheus, private-location, crawl, health. Example: "http,dns".
periodTypeNoComma-separated period types. Allowed: raw (single executions), hour, day, month (rollups). Defaults to "hour" when omitted. Example: "raw".
periodEndBeforeNoRFC3339 timestamp (exclusive upper bound), e.g. "2026-05-03T11:00:00Z".
periodStartAfterNoRFC3339 timestamp (inclusive lower bound), e.g. "2026-05-03T10:14:22Z". Defaults to a window matched to periodType when omitted (raw=1h, hour=24h, day=30d, month=365d).

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoResult rows on this page: raw executions or aggregated rollups.
windowNoTime window the server actually queried.
paginationNoCursor pagination for this filter.
effectiveFilterNoPeriod filter that actually ran, after the tool's defaulting.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive, so safety is covered; the description goes further by disclosing defaulting behavior (periodType falls back to 'hour', periodStartAfter falls back to a window matched to periodType) and the auth scope (mcp:read tokens). It stops short of describing rate limits or exact aggregation semantics, which keeps it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and routing before the return-shape and defaults detail. Minor redundancy: the periodType/periodStartAfter default rules are repeated from the schema descriptions, costing a little efficiency but not readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter read tool with an output schema and full annotation coverage, the description supplies everything needed: filtering scope, sibling routing, fallback defaults, and the auth profile. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all ten parameters. The description largely restates the periodType/periodStartAfter defaults that are already in the schema rather than adding new syntax or format meaning, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (Query) plus resource (monitoring results) with scope detail (raw or aggregated) and filtering dimensions named. It explicitly distinguishes itself from the diagnose_check sibling, so an agent can select correctly without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States the intended use cases ('trend analysis or to inspect a specific window') and names the alternative with the condition that selects it ('For investigating a single check's current state, use diagnose_check instead'). When-to-use and when-not are both explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_status_pagesList status pagesA
Read-onlyIdempotent
Inspect

List every status page in the organization, newest first, and return {data: [...]}. Use get_status_page for a single page by UID or slug (with=sections or include=sections for its contents). Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
dataNoStatus pages in the organization.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, but the description adds crucial auth context: 'works with mcp:read tokens'. Also specifies ordering (newest first) and response shape {data: [...]}, going beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences, front-loaded with purpose and return shape, second sentence routes to alternative. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless list tool with an output schema, the description provides ordering, return structure, auth scope, and sibling routing. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Zero parameters, so baseline is 4. The description mentions that get_status_page accepts include/sections parameters, which implies this tool does not; this is useful but not a parameter explanation for this tool itself.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (status pages) with scope (in the organization) and ordering (newest first). Distinguishes from sibling get_status_page by contrast. An agent can identify the correct tool immediately.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names get_status_page as the alternative for a single page and hints that include/sections parameters are for that tool. No exclusions or edge cases like empty results, but the routing is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

manage_status_page_incidentManage status page incidentA
Destructive
Inspect

Manage the customer-facing incidents a status page shows (publications), distinct from the internal incidents list_incidents returns. Titles and bodies are shown to CUSTOMERS: never paste probe output, error strings, internal hostnames or IPs. action=create publishes a hand-written incident (pageIdentifier, title). action=update edits a publication's title, severity or state (pageIdentifier, publicationUid; PATCH semantics). action=add_update appends a narrative entry (pageIdentifier, publicationUid, kind, bodyMarkdown); entries are append-only. action=publish relays an EXISTING internal incident (incidentUid, pageIdentifier) with a title templated from the page. action=unpublish removes a relayed incident from the page (incidentUid, publicationUid), keeping the row for audit. create, add_update and publish notify status-page subscribers (hourly cap) and every action reaches webhook connections. Read publications with get_status_page include=incidents. Annotated destructive and non-idempotent because delete is one of its actions. Every action requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNoUpdate kind (required). Allowed: "investigating", "identified", "monitoring", "resolved", "maintenance", "info". The first four also advance the publication's state.
stateNoInitial public state (default "investigating"). Allowed: "investigating", "identified", "monitoring", "resolved".
titleNoCustomer-facing title (required), e.g. "Payments API is degraded".
actionYesWhat to do with the customer-facing incident.
severityNoPublic badge severity. Allowed: "minor", "major", "critical".
incidentUidNoOptional UID of the internal incident this publication tracks.
bodyMarkdownNoOptional first narrative entry, in Markdown.
pageIdentifierNoStatus page UID or URL-friendly slug, e.g. "public".
publicationUidNoUID of the incident publication to act on.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidNoPublication UID.
kindNoUpdate kind, e.g. "investigating" or "resolved".
staleNoTrue when the linked incident has resolved while the entry is still open.
stateNoPublic state: investigating, identified, monitoring or resolved.
titleNoCustomer-facing title.
severityNoPublic severity: minor, major or critical; absent when unset.
createdAtNoRFC3339 creation timestamp.
updatedAtNoRFC3339 last-update timestamp.
resolvedAtNoRFC3339 timestamp when it was resolved; absent while open.
autoCreatedNoTrue when the publication was created by the auto-publish pipeline.
incidentUidNoLinked internal incident UID, when the publication tracks one.
publishedAtNoRFC3339 timestamp when the entry appeared on the page.
unpublishedNoAlways true on success.
bodyMarkdownNoUpdate body in Markdown.
humanTouchedNoTrue once an operator edited it, which stops auto-resolve.
statusPageUidNoUID of the status page the publication lives on.
publicationUidNoUID of the publication removed from the page.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses the customer-visible blast radius of titles/bodies, that create/add_update/publish notify subscribers under an hourly cap, that every action hits webhook connections, that unpublish preserves rows for audit, and the exact auth requirements (mcp scope, mcp:read refused, user role minimum). This is unusually rich operational context for a destructive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The safety warning about customer-visible content is front-loaded, and every subsequent sentence is an action-to-parameter mapping rather than filler. It is dense and long, but nearly all of it earns its place; only mild compaction is possible.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-action, 9-parameter mutation tool with an output schema and existing annotations, the description supplies everything else an agent needs: action routing, parameter binding per action, side effects, permissions, and audit behavior. Nothing material is left unspecified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so 3 is the baseline, but the description adds real value by mapping parameters to actions (pageIdentifier+title for create, publicationUid for update, kind+bodyMarkdown for add_update, incidentUid for publish/unpublish) and by stating PATCH semantics and append-only behavior for add_update. It does not restate enum values, which the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (manage) and a precisely scoped resource: 'the customer-facing incidents a status page shows (publications)'. It explicitly distinguishes that resource from the internal incidents returned by list_incidents, so an agent can route correctly without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Enumerates each action with its required parameters (create, update with PATCH semantics, add_update append-only, publish relays an existing incident, unpublish removes while keeping the row for audit) and names the exact read companion: get_status_page include=incidents. It also names the alternative source for internal incidents (list_incidents), covering when-not-to-use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

manage_status_page_resourceManage status page resourceA
Destructive
Inspect

Pin, edit or unpin a resource (a check or a check group) in a status page section. action=create pins exactly one of checkUid or checkGroupUid and returns the resource. action=update edits one (resourceUid required; omitted fields are kept). action=delete unpins it, returning {deleted, identifier}; the check or group itself is untouched. Read a section's resources with get_status_page include=resources. Annotated destructive and non-idempotent because delete is one of its actions. Every action requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
actionYesWhat to do with the resource.
checkUidNoCheck UID or slug to pin (for example api-health). Mutually exclusive with checkGroupUid; exactly one is required.
positionNoDisplay position within the section
publicNameNoDisplay name for the public page (defaults to the check or group name)
explanationNoShort explanation rendered under the resource
resourceUidNoStatus page resource UID (get_status_page include=resources lists them).
checkGroupUidNoCheck group UID or slug to pin as one aggregated component. Mutually exclusive with checkUid; exactly one is required.
pageIdentifierYesStatus page UID or URL-friendly slug, e.g. "public".
sectionIdentifierYesStatus page section UID or URL-friendly slug, e.g. "api".

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidNoResource UID.
deletedNoAlways true on success.
checkUidNoPinned check UID, when the resource targets a check.
positionNoDisplay position within the section (smaller renders earlier).
identifierNoThe identifier that was deleted.
publicNameNoDisplay name shown on the public page.
explanationNoShort explanation rendered under the resource.
checkGroupUidNoPinned check group UID, when the resource targets a group.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=false; the description goes further by explaining *why* (delete is one of its actions) and clarifying the blast radius — unpinning leaves the underlying check or group untouched — plus the return shape {deleted, identifier} and the auth refusal mode for mcp:read tokens. That is substantive context beyond structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four dense sentences, front-loaded with the action semantics before the caveats, and no filler. It is on the longer side but each clause carries operational information (return values, scope requirement, role requirement).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter, three-mode mutation tool with an output schema available, the description covers action semantics, exclusivity rules, side effects, return shapes, and auth requirements. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds cross-parameter meaning the schema only hints at: exactly one of checkUid/checkGroupUid must be supplied for create, and resourceUid is required for update with omitted fields preserved. That ties parameters to action semantics usefully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb set (pin/edit/unpin) and the exact resource (a check or check group inside a status page section), then enumerates what each of the three action values does. An agent can distinguish this from manage_status_page_section and get_status_page without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the selecting condition for each mode of the single tool (create/update/delete), and explicitly routes the read case to a sibling: 'Read a section's resources with get_status_page include=resources.' Prerequisites are also given (mcp scope, user role).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

manage_status_page_sectionManage status page sectionA
Destructive
Inspect

Create, update or delete a section of a status page. action=create adds a section (name and slug required) and returns it. action=update edits one (sectionIdentifier required; omitted fields are kept) and returns it. action=delete permanently removes a section and every resource pinned in it, returning {deleted, identifier}. Read a page's sections with get_status_page include=sections. Annotated destructive and non-idempotent because delete is one of its actions. Every action requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoSection display name (required), e.g. "API services".
slugNoURL-friendly slug (required, unique within the page), e.g. "api".
actionYesWhat to do with the section.
positionNoDisplay position within the page (smaller renders earlier).
pageIdentifierYesStatus page UID or URL-friendly slug, e.g. "public".
sectionIdentifierNoStatus page section UID or URL-friendly slug, e.g. "api".

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidNoSection UID.
nameNoSection display name.
slugNoURL-friendly slug, unique within the page.
deletedNoAlways true on success.
positionNoDisplay position (smaller renders earlier).
selectorNoDynamic membership rule; absent on hand-curated sections.
identifierNoThe identifier that was deleted.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint and idempotentHint=false, but the description explains why (delete is one of the actions) and adds context annotations cannot: delete also removes every resource pinned in the section, update preserves omitted fields, and the exact return shapes. Auth requirements (scope and role) are disclosed as well.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose followed by one sentence per action, then sibling routing, annotation rationale, and prerequisites. Dense but every sentence carries distinct, load-bearing information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a multi-action mutation tool with an output schema, it covers the action semantics, conditional inputs, destructive side effects, sibling routing, and auth prerequisites. Nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so field meanings are already documented, but the description adds conditional requirements the schema cannot express — name/slug required only for create, sectionIdentifier only for update. It does not add format or example detail beyond what the schema provides, so it stops short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the resource (status page section) and breaks the verb into its three concrete actions, specifying exactly what each produces. It also distinguishes itself from get_status_page, telling the agent this is the mutation counterpart to that read tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Spells out the trigger condition for each action (create requires name/slug, update requires sectionIdentifier and keeps omitted fields, delete removes pinned resources) and names the alternative for reading. It further states the access conditions — mcp scope required, mcp:read refused, at least user role — so the agent can pre-check eligibility.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

probeProbe a targetA
Read-onlyIdempotent
Inspect

Explore a target and test a js check before create_check, without saving anything. kind=script runs a js check script exactly as a SolidPing worker would and returns status, output (with console) and metrics; env carries plaintext parameters and secrets only NAMES the secret parameters, which run empty. kind=fetch GETs a URL from the server. kind=browser snapshots a page to pick selectors for browser steps. Reaches the URL or script target you name. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
envNoPlaintext parameters exposed as env.NAME, e.g. {"BASE_URL": "https://acme.com"}.
urlNoAbsolute http(s) URL.
kindYesWhat to run. "script": run a js check script once (needs script). "fetch": HTTP GET url and return status, headers and the first 16 KB of the body. "browser": open url in the headless browser and return its accessibility-style tree with a CSS selector per element.
scriptNoThe js check script (a function body that returns {status, ...}).
secretsNoNames of the secret parameters the script reads; they run empty.
timeoutNoRun timeout as a duration string (default and max 30s).

Output Schema

ParametersJSON Schema
NameRequiredDescription
outputNoThe script's output object, with console output under `console`.
statusYesup, down, timeout or error, as a SolidPing worker would report it.
metricsNoThe script's metrics.
durationMsNoRun duration in milliseconds.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/idempotent/openWorld/destructive, yet the description adds real behavioral context: kind=script runs exactly as a worker would, secrets are supplied by NAME only and run empty, and kind=fetch executes server-side. These caveats materially affect how an agent constructs the call.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the purpose and no-save guarantee come first, then the kind-by-kind breakdown. Every sentence carries information relevant to invocation, though the kind explanations are somewhat tightly packed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-parameter, enum-bearing, nested-object tool with annotations and an output schema, the description covers the modes, the auth requirement, and the secrets caveat. Return shape is delegated correctly to the output schema, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes beyond the schema by explaining the semantics of `env` (plaintext parameters) and the security-relevant nuance that `secrets` are given by name and run empty, which is the kind of detail an agent must reason about.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('explore a target and test a js check') with the crucial scope qualifier 'without saving anything', and positions itself relative to create_check. An agent can distinguish it from create_check/run_check/validate_check without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames the tool as a pre-flight for create_check and states it is read-only with mcp:read tokens, which tells the agent when it is safe/appropriate. It does not explicitly contrast with sibling alternatives like validate_check or run_check, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_checkRun check nowAInspect

Run a check once, now, in every region, instead of waiting for its next period (use it right after a fix, or on a freshly created check). The run goes through the normal result path: it can open or resolve an incident like any scheduled run. Rate limited per check and per organization. Returns {requestedAt, regions: [{region, status}]} where status is queued (due now, or right after the run in progress); read the outcome with diagnose_check or list_results (a result with periodStart >= requestedAt). Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYesCheck UID or URL-friendly slug, e.g. "api-prod" or "63d49e55-97e3-4e8c-b7ab-c862de7a43f3".

Output Schema

ParametersJSON Schema
NameRequiredDescription
regionsYesOne entry per region.
requestedAtYesRFC3339 time the request was recorded.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, idempotentHint=false, destructiveHint=false. The description adds substantial extras: the run "can open or resolve an incident like any scheduled run" (a real side effect), rate limiting per check and per organization, the required mcp scope with mcp:read refused, and the minimum organization role.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: purpose first, then usage, side effects, limits, return shape, and auth. Nearly every sentence earns its place, though the inline return-shape literal is partly redundant given a dedicated output schema exists, and the single unbroken block is less scannable than it could be.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a non-idempotent action with incident side effects, the description covers the critical unknowns: side effects, rate limits, auth/scope requirements, and how to retrieve the eventual outcome. Nothing an agent needs to invoke this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already explains the UID-or-slug identifier format with examples. The description adds no further parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb, resource, and scope: "Run a check once, now, in every region, instead of waiting for its next period." This clearly separates it from sibling scheduling/CRUD tools (create_check, update_check, list_checks) and from read-only outcome tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the trigger conditions ("right after a fix, or on a freshly created check") and routes the agent to alternatives for reading the outcome: "read the outcome with diagnose_check or list_results (a result with periodStart >= requestedAt)." Both when-to-use and where-to-go-next are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_checkUpdate checkA
Idempotent
Inspect

Update an existing check by UID or slug and return the updated check. PATCH semantics — only the fields you pass are modified, others stay as-is. Use create_check to make a new check and delete_check to remove one; to pause without deleting, set enabled:false instead. Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew human-readable name, e.g. "API production".
slugNoNew URL-friendly slug, e.g. "api-prod".
configNoReplace check-specific config (full object — not merged).
labelsNoReplace labels object (empty object clears all). Example: {"env":"staging"}.
periodNoNew check interval as HH:MM:SS, e.g. "00:00:30" for 30 seconds.
enabledNoToggle whether the check runs. Set to false to pause the check, true to resume it.
regionsNoPin the check to exactly these regions, e.g. ["eu-west-1","us-east-1"] (placement becomes "pinned"). An empty array puts the check back on the default placement: automatic across regionCount healthy regions (unless the org's own default_regions names a private location, which pins it to those defaults). The check keeps running either way; use enabled: false to stop it.
placementNoSwitch the placement: "auto" lets the scheduler place the check (keeping its current region count and every current region still healthy) and move it off a region that goes dark; "pinned" freezes the current regions unless regions is also given.
failQuorumNoMulti-region quorum: how many of the check's regions must be failing, for the confirmation period, before it is down and an incident opens. "all", "majority" or a whole number such as "2" (clamped to the region count). The default is all regions for 1-2 regions and a majority for 3+. Fewer failing regions than the quorum is a "regional issue": the check shows warning and no incident opens. "all" keeps the per-result rule: any passing region resets the confirmation. Pass "default" to put the check back on the default.
identifierYesCheck UID or URL-friendly slug, e.g. "api-prod" or "63d49e55-97e3-4e8c-b7ab-c862de7a43f3".
regionPoolNoAutomatic placement only: candidate cloud region slugs; an empty array means any. Implies placement auto.
descriptionNoUpdated free-text description shown in the UI.
regionCountNoAutomatic placement only: how many regions run the check. Implies placement auto.
checkGroupUidNoMove to a different group (UID or slug). Pass an empty string to ungroup.
recoveryPeriodSecondsNoWall-clock seconds the check must stay UP before auto-resolving. Any failure inside the window resets the recovery clock. 0 = resolve immediately. Range 0–86400.
confirmationPeriodSecondsNoWall-clock seconds to wait after the first failure before opening an incident. 0 = open immediately. Range 0–86400 (one day).

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesCheck UID.
nameNoHuman-readable name.
slugNoURL-friendly slug.
typeNoCheck type, e.g. "http".
configNoCheck-specific configuration for the type.
labelsNoKey-value labels.
periodNoCheck interval as HH:MM:SS.
statusNoSynthesized status: up, down, validating, created or degraded.
enabledNoWhether the check runs.
regionsNoRegions the check runs from.
createdAtNoRFC3339 creation timestamp.
placementNo"pinned" or "auto".
descriptionNoFree-text description.
lastResultAtNoRFC3339 timestamp of the newest real result.
checkGroupUidNoCheck group UID, when the check belongs to a group.
statusChangedAtNoRFC3339 timestamp of the last status change.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover readOnly/idempotent/destructive flags, but the description adds value beyond them: PATCH semantics (unspecified fields are untouched) and an explicit authorization gate (mcp scope required, mcp:read tokens refused, at least user role). These are operational facts the annotations do not carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with the action and PATCH semantics, then alternatives, then the auth requirement. No filler or restated title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter mutation tool with full schema coverage, an output schema, and annotations, the description supplies exactly the missing pieces: mutation semantics, sibling routing, and permission requirements. Nothing an agent needs to call it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each of the 16 parameters is documented in the schema itself, so the baseline is 3. The description only echoes one parameter (enabled:false to pause) and adds no syntax or interaction detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (update) and resource (check), names the two supported identifiers (UID or slug), and describes the PATCH-style mutation semantics. It is immediately distinguishable from create_check, delete_check and get_check by name in the same sentence.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: use create_check to make one, delete_check to remove one, and set enabled:false to pause without deleting. That is a concrete when-to-use / when-not-to-use rule plus a named alternative for a common intent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_status_pageUpdate status pageA
Idempotent
Inspect

Update an existing status page by UID or slug and return the updated page. PATCH semantics — only fields you pass change, omitted fields keep their current values; the page must already exist and a slug that collides with another page is rejected. Use create_status_page to make a new page and delete_status_page to remove one instead. Requires the mcp scope (mcp:read tokens are refused) and at least the user role in the organization.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew display name, e.g. "Public status page".
slugNoNew URL-friendly slug, e.g. "public".
enabledNoEnable or disable the public-facing page.
languageNoLanguage code, e.g. "en" or "fr".
customCssNoCustom CSS injected into the public page as a <style> element (see create_status_page). Max 64 KB; @import is rejected. Pass an empty string to clear it.
isDefaultNoMark as the org's default page (only one allowed).
identifierYesStatus page UID or URL-friendly slug, e.g. "public".
visibilityNoVisibility setting. Allowed: "public", "private".
autoPublishNoAutomatically publish incidents affecting this page's resources as public incidents. New pages default to true; pages that existed before this feature shipped default to false.
autoResolveNoWhat an auto-created publication does when its incident resolves. Allowed: "always", "if_untouched" (default — a publication a human has edited is left for them to close), "never".
descriptionNoNew free-text description shown in the UI.
historyDaysNoDays of history to show on the page (default 90).
showAvailabilityNoToggle availability percentage on the public page.
showResponseTimeNoToggle response-time charts on the public page.
autoPublishDelaySecondsNoDebounce in seconds before an incident becomes public (default 60). 0 publishes immediately. An incident that resolves inside the delay is never published at all.

Output Schema

ParametersJSON Schema
NameRequiredDescription
uidYesStatus page UID.
nameNoDisplay name.
slugNoURL-friendly slug.
enabledNoWhether the public page is served.
createdAtNoRFC3339 creation timestamp.
isDefaultNoWhether this is the organization's default page.
visibilityNo"public", "private" or "password".
historyPeriodNoHistory window: "24h", "7d", "30d" or "90d".

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses PATCH semantics (omitted fields retain values), the slug-collision rejection behavior, and required auth ('mcp scope', 'mcp:read tokens are refused', 'at least the user role'). The annotations only assert idempotent/non-destructive/closed-world; the description supplies the operational constraints an agent must satisfy before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and update semantics before alternatives and auth, so the highest-value information comes first. Dense but no sentence is filler; the auth/precondition clause is compressed into the final sentence rather than padded out.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter mutation tool, the description covers purpose, patch semantics, preconditions, failure modes (slug collision), alternatives, and authorization, while the output schema and per-parameter schema descriptions handle the rest. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description meaningfully adds the update semantics for all 15 fields ('only fields you pass change, omitted fields keep their current values'), which is the single most important fact about how these parameters behave. It also clarifies that identifier accepts either a UID or a slug.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource combination ('Update an existing status page') and immediately scopes the target as 'by UID or slug'. It also names the sibling tools for the adjacent operations (create_status_page, delete_status_page), so the agent can distinguish it from them without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: 'Use create_status_page to make a new page and delete_status_page to remove one instead.' It also states the precondition that the page must already exist and that a slug collision is rejected, which is exactly the when-not-to-use guidance an agent needs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_checkValidate checkA
Read-onlyIdempotent
Inspect

Dry-run validate a check config without creating or changing anything — a pure read, no side effects. Returns {valid, fields, warnings}: valid is false exactly when fields lists the blocking findings (every one of them, not just the first), while warnings are advisory notes that never block. Use this before create_check when you've assembled a config from scratch or modified a sample, to catch problems early. Read-only: works with mcp:read tokens.

ParametersJSON Schema
NameRequiredDescriptionDefault
typeYesCheck type (e.g. "http", "dns", "tcp", "icmp", "ssl").
configYesCheck-specific config to validate (e.g., {"url": "https://example.com"}).

Output Schema

ParametersJSON Schema
NameRequiredDescription
validYesTrue when the config would be accepted; false when at least one blocking finding exists.
fieldsNoBlocking findings; absent when there are none (valid stays true).
warningsNoAdvisory findings that never block; absent when there are none.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/idempotent/destructive annotations, it adds that validation is a pure read with no side effects, that valid is false exactly when fields lists all blocking findings, that warnings never block, and that it works with mcp:read tokens. These details clarify behavior and auth requirements usefully.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and usage, and each sentence carries useful information. However, the explicit return-value explanation is somewhat redundant because an output schema exists, so it is efficient rather than maximally lean.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter validation tool with rich annotations, complete schema coverage, and an output schema, the description supplies purpose, usage context, safety behavior, and auth scope. Nothing essential for correct invocation appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents the required type and config parameters. The description adds only the framing of validating an assembled or modified config, without new parameter-level syntax or format detail, matching the baseline for high-coverage schemas.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a precise verb and resource: 'Dry-run validate a check config without creating or changing anything — a pure read, no side effects.' It clearly distinguishes validate_check from sibling mutation tools like create_check and update_check by emphasizing dry-run validation with no changes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use the tool: 'before create_check when you've assembled a config from scratch or modified a sample, to catch problems early.' This gives the agent a concrete pre-create validation workflow and names the sibling it should precede.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 47 tool updatesv0.38.5
    • Changedcreate_check8 fields changed
      • changedInput schema / properties / config / description
        Previous value: -"Check-specific config. Shape depends on type. Example for http: {\"url\": \"https://example.com\", \"method\": \"GET\"}. Use get_check_type_samples to discover the shape for other types."New value: +"Check-specific config. Shape depends on type. Example for http: {\"url\": \"https://example.com\", \"method\": \"GET\"}. Use list_check_types with type to discover the shape for other types."
      • addedInput schema / properties / failQuorum
        Added value: +{
        +  "description": "Multi-region quorum: how many of the check's regions must be failing, for the confirmation period, before it is down and an incident opens. \"all\", \"majority\" or a whole number such as \"2\" (clamped to the region count). The default is all regions for 1-2 regions and a majority for 3+. Fewer failing regions than the quorum is a \"regional issue\": the check shows warning and no incident opens. \"all\" keeps the per-result rule: any passing region resets the confirmation. Omit for the default.",
        +  "type": "string"
        +}
      • addedInput schema / properties / placement
        Added value: +{
        +  "description": "\"pinned\" or \"auto\". Omit to infer it: regions given means pinned, otherwise auto. \"auto\" cannot be combined with regions. Private (@) regions are pinned-only.",
        +  "type": "string"
        +}
      • addedInput schema / properties / regionCount
        Added value: +{
        +  "description": "Automatic placement only: how many regions run the check (default 2, capped by the eligible regions and the org's checks-per-minute limit; the response carries a PLACEMENT_REGION_COUNT_REDUCED warning when reduced). Implies placement auto.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / regionPool
        Added value: +{
        +  "description": "Automatic placement only: the cloud region slugs the scheduler may choose from, e.g. [\"paris\",\"gravelines\"]. Omit for any cloud region. Implies placement auto.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / regions / description
        Previous value: -"Region slugs to run the check from, e.g. [\"eu-west-1\",\"us-east-1\"]. Defaults to all org regions when omitted."New value: +"Region slugs to pin the check to, e.g. [\"eu-west-1\",\"us-east-1\"]. An explicit list means placement \"pinned\": the check runs from exactly these regions and is never moved. When omitted, the check is placed automatically (placement \"auto\"): the scheduler picks regionCount healthy regions from the org's default_regions, then the system default, then every other declared region, and moves the check off a region that goes dark. (An org whose own default_regions names a private location keeps pinned checks on those defaults.)"
      • changedInput schema / properties / type / description
        Previous value: -"Check type. Allowed: http, tcp, icmp, dns, ssl, heartbeat, domain. Inferred from config if omitted."New value: +"Check type. Allowed: http, tcp, icmp, dns, heartbeat, email, domain, ssl, smtp, udp, ssh, pop3, imap, websocket, postgresql, ftp, sftp, js, mysql, redis, mongodb, mssql, oracle, clickhouse, grpc, kafka, mqtt, a2s, minecraft, rabbitmq, snmp, docker, browser, freebox_line, dnsbl, sip, kubernetes, ntp, rdp, vnc, prometheus, private-location, crawl, health. Inferred from config if omitted."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "checkGroupUid": {
        +      "description": "Check group UID, when the check belongs to a group.",
        +      "type": "string"
        +    },
        +    "config": {
        +      "description": "Check-specific configuration for the type.",
        +      "type": "object"
        +    },
        +    "createdAt": {
        +      "description": "RFC3339 creation timestamp.",
        +      "type": "string"
        +    },
        +    "description": {
        +      "description": "Free-text description.",
        +      "type": "string"
        +    },
        +    "enabled": {
        +      "description": "Whether the check runs.",
        +      "type": "boolean"
        +    },
        +    "labels": {
        +      "description": "Key-value labels.",
        +      "type": "object"
        +    },
        +    "lastResultAt": {
        +      "description": "RFC3339 timestamp of the newest real result.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "Human-readable name.",
        +      "type": "string"
        +    },
        +    "period": {
        +      "description": "Check interval as HH:MM:SS.",
        +      "type": "string"
        +    },
        +    "placement": {
        +      "description": "\"pinned\" or \"auto\".",
        +      "type": "string"
        +    },
        +    "regions": {
        +      "description": "Regions the check runs from.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "slug": {
        +      "description": "URL-friendly slug.",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Synthesized status: up, down, validating, created or degraded.",
        +      "type": "string"
        +    },
        +    "statusChangedAt": {
        +      "description": "RFC3339 timestamp of the last status change.",
        +      "type": "string"
        +    },
        +    "type": {
        +      "description": "Check type, e.g. \"http\".",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Check UID.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedcreate_incident_publication
    • Removedcreate_integration
    • Removedcreate_maintenance_window
    • Changedcreate_status_page2 fields changed
      • changedInput schema / properties / visibility / description
        Previous value: -"Visibility setting. Allowed: \"public\", \"private\". Default depends on system config."New value: +"Visibility setting. Allowed: \"public\", \"private\". Default \"public\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "createdAt": {
        +      "description": "RFC3339 creation timestamp.",
        +      "type": "string"
        +    },
        +    "enabled": {
        +      "description": "Whether the public page is served.",
        +      "type": "boolean"
        +    },
        +    "historyPeriod": {
        +      "description": "History window: \"24h\", \"7d\", \"30d\" or \"90d\".",
        +      "type": "string"
        +    },
        +    "isDefault": {
        +      "description": "Whether this is the organization's default page.",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "Display name.",
        +      "type": "string"
        +    },
        +    "slug": {
        +      "description": "URL-friendly slug.",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Status page UID.",
        +      "type": "string"
        +    },
        +    "visibility": {
        +      "description": "\"public\", \"private\" or \"password\".",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedcreate_status_page_incident
    • Removedcreate_status_page_incident_update
    • Removedcreate_status_page_resource
    • Removedcreate_status_page_section
    • Changeddelete_check1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "deleted": {
        +      "description": "Always true on success.",
        +      "type": "boolean"
        +    },
        +    "identifier": {
        +      "description": "The UID or slug that was deleted.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "deleted",
        +    "identifier"
        +  ],
        +  "type": "object"
        +}
    • Removeddelete_incident_publication
    • Removeddelete_maintenance_window
    • Changeddelete_status_page1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "deleted": {
        +      "description": "Always true on success.",
        +      "type": "boolean"
        +    },
        +    "identifier": {
        +      "description": "The identifier that was deleted.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "deleted",
        +    "identifier"
        +  ],
        +  "type": "object"
        +}
    • Removeddelete_status_page_resource
    • Removeddelete_status_page_section
    • Changeddiagnose_check1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "activeIncident": {
        +      "description": "Currently-open incident for the check, or null when none is open.",
        +      "properties": {
        +        "checkUid": {
        +          "description": "UID of the check the incident belongs to.",
        +          "type": "string"
        +        },
        +        "kind": {
        +          "description": "What the incident is about: check, slo_burn or degraded.",
        +          "type": "string"
        +        },
        +        "number": {
        +          "description": "Short per-org reference, rendered as #42.",
        +          "type": "integer"
        +        },
        +        "resolvedAt": {
        +          "description": "RFC3339 resolution timestamp; absent while the incident is open.",
        +          "type": "string"
        +        },
        +        "startedAt": {
        +          "description": "RFC3339 timestamp of the incident's onset.",
        +          "type": "string"
        +        },
        +        "state": {
        +          "description": "Incident state, e.g. active or resolved.",
        +          "type": "string"
        +        },
        +        "uid": {
        +          "description": "Incident UID.",
        +          "type": "string"
        +        }
        +      },
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    },
        +    "check": {
        +      "properties": {
        +        "checkGroupUid": {
        +          "description": "Check group UID, when the check belongs to a group.",
        +          "type": "string"
        +        },
        +        "config": {
        +          "description": "Check-specific configuration for the type.",
        +          "type": "object"
        +        },
        +        "createdAt": {
        +          "description": "RFC3339 creation timestamp.",
        +          "type": "string"
        +        },
        +        "description": {
        +          "description": "Free-text description.",
        +          "type": "string"
        +        },
        +        "enabled": {
        +          "description": "Whether the check runs.",
        +          "type": "boolean"
        +        },
        +        "labels": {
        +          "description": "Key-value labels.",
        +          "type": "object"
        +        },
        +        "lastResultAt": {
        +          "description": "RFC3339 timestamp of the newest real result.",
        +          "type": "string"
        +        },
        +        "name": {
        +          "description": "Human-readable name.",
        +          "type": "string"
        +        },
        +        "period": {
        +          "description": "Check interval as HH:MM:SS.",
        +          "type": "string"
        +        },
        +        "placement": {
        +          "description": "\"pinned\" or \"auto\".",
        +          "type": "string"
        +        },
        +        "regions": {
        +          "description": "Regions the check runs from.",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        },
        +        "slug": {
        +          "description": "URL-friendly slug.",
        +          "type": "string"
        +        },
        +        "status": {
        +          "description": "Synthesized status: up, down, validating, created or degraded.",
        +          "type": "string"
        +        },
        +        "statusChangedAt": {
        +          "description": "RFC3339 timestamp of the last status change.",
        +          "type": "string"
        +        },
        +        "type": {
        +          "description": "Check type, e.g. \"http\".",
        +          "type": "string"
        +        },
        +        "uid": {
        +          "description": "Check UID.",
        +          "type": "string"
        +        }
        +      },
        +      "required": [
        +        "uid"
        +      ],
        +      "type": "object"
        +    },
        +    "freshness": {
        +      "description": "One sentence per silent region naming it and since when it has gone quiet; empty when every region is reporting.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "lastResolvedIncident": {
        +      "description": "Most recently resolved incident for the check, or null when there is none.",
        +      "properties": {
        +        "checkUid": {
        +          "description": "UID of the check the incident belongs to.",
        +          "type": "string"
        +        },
        +        "kind": {
        +          "description": "What the incident is about: check, slo_burn or degraded.",
        +          "type": "string"
        +        },
        +        "number": {
        +          "description": "Short per-org reference, rendered as #42.",
        +          "type": "integer"
        +        },
        +        "resolvedAt": {
        +          "description": "RFC3339 resolution timestamp; absent while the incident is open.",
        +          "type": "string"
        +        },
        +        "startedAt": {
        +          "description": "RFC3339 timestamp of the incident's onset.",
        +          "type": "string"
        +        },
        +        "state": {
        +          "description": "Incident state, e.g. active or resolved.",
        +          "type": "string"
        +        },
        +        "uid": {
        +          "description": "Incident UID.",
        +          "type": "string"
        +        }
        +      },
        +      "type": [
        +        "object",
        +        "null"
        +      ]
        +    },
        +    "recentResults": {
        +      "description": "Newest-first raw results, trimmed to recentResultsLimit per region; includes region, output and durationMs.",
        +      "items": {
        +        "properties": {
        +          "availabilityPct": {
        +            "description": "Uptime % for the bucket (with=availabilityPct, aggregated rows only).",
        +            "type": "number"
        +          },
        +          "checkName": {
        +            "description": "Check name (with=checkName).",
        +            "type": "string"
        +          },
        +          "checkSlug": {
        +            "description": "Check slug (with=checkSlug).",
        +            "type": "string"
        +          },
        +          "checkUid": {
        +            "description": "UID of the check this result belongs to.",
        +            "type": "string"
        +          },
        +          "durationMs": {
        +            "description": "Response time in ms (with=durationMs).",
        +            "type": "number"
        +          },
        +          "periodStart": {
        +            "description": "RFC3339 start of the period (raw: execution time).",
        +            "type": "string"
        +          },
        +          "periodType": {
        +            "description": "Aggregation level: raw, hour, day or month.",
        +            "type": "string"
        +          },
        +          "region": {
        +            "description": "Region the check ran in (with=region).",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Result status: up, down, created, running, abandoned…",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Result UID (time-ordered).",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "regionalIssue": {
        +      "description": "One sentence describing the regional issue (some, but fewer than the quorum, of the check's regions failing); empty when there is none.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "check",
        +    "recentResults",
        +    "activeIncident",
        +    "lastResolvedIncident"
        +  ],
        +  "type": "object"
        +}
    • Changedget_check1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "checkGroupUid": {
        +      "description": "Check group UID, when the check belongs to a group.",
        +      "type": "string"
        +    },
        +    "config": {
        +      "description": "Check-specific configuration for the type.",
        +      "type": "object"
        +    },
        +    "createdAt": {
        +      "description": "RFC3339 creation timestamp.",
        +      "type": "string"
        +    },
        +    "description": {
        +      "description": "Free-text description.",
        +      "type": "string"
        +    },
        +    "enabled": {
        +      "description": "Whether the check runs.",
        +      "type": "boolean"
        +    },
        +    "labels": {
        +      "description": "Key-value labels.",
        +      "type": "object"
        +    },
        +    "lastResultAt": {
        +      "description": "RFC3339 timestamp of the newest real result.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "Human-readable name.",
        +      "type": "string"
        +    },
        +    "period": {
        +      "description": "Check interval as HH:MM:SS.",
        +      "type": "string"
        +    },
        +    "placement": {
        +      "description": "\"pinned\" or \"auto\".",
        +      "type": "string"
        +    },
        +    "regions": {
        +      "description": "Regions the check runs from.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "slug": {
        +      "description": "URL-friendly slug.",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Synthesized status: up, down, validating, created or degraded.",
        +      "type": "string"
        +    },
        +    "statusChangedAt": {
        +      "description": "RFC3339 timestamp of the last status change.",
        +      "type": "string"
        +    },
        +    "type": {
        +      "description": "Check type, e.g. \"http\".",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Check UID.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedget_check_type_samples
    • Changedget_incident4 fields changed
      • addedInput schema / properties / include
        Added value: +{
        +  "description": "Extra lists to return with the incident. An unknown value is an error.",
        +  "items": {
        +    "enum": [
        +      "notifications"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "With include=notifications: max attempts (1-500, default 20).",
        +  "type": "integer"
        +}
      • addedInput schema / properties / status
        Added value: +{
        +  "description": "With include=notifications: only attempts in this delivery status. Allowed: pending, sent, failed, cancelled, skipped.",
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "check": {
        +      "description": "Underlying check, when requested with with=check.",
        +      "type": "object"
        +    },
        +    "checkName": {
        +      "description": "Name of that check.",
        +      "type": "string"
        +    },
        +    "checkSlug": {
        +      "description": "Slug of that check.",
        +      "type": "string"
        +    },
        +    "checkUid": {
        +      "description": "UID of the check the incident is about.",
        +      "type": "string"
        +    },
        +    "description": {
        +      "description": "Custom description, when one was set.",
        +      "type": "string"
        +    },
        +    "events": {
        +      "description": "Timeline events (status transitions, notifications, manual notes), newest first; present when with=events was passed.",
        +      "items": {
        +        "properties": {
        +          "actorName": {
        +            "description": "Display name of the acting user, when known.",
        +            "type": "string"
        +          },
        +          "actorType": {
        +            "description": "Who acted: system or user.",
        +            "type": "string"
        +          },
        +          "createdAt": {
        +            "description": "RFC3339 timestamp of the event.",
        +            "type": "string"
        +          },
        +          "eventType": {
        +            "description": "Event type, e.g. \"incident.created\".",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Event UID.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "failureCount": {
        +      "description": "Number of failures recorded for the incident.",
        +      "type": "integer"
        +    },
        +    "kind": {
        +      "description": "What the incident is about: check, slo_burn or degraded.",
        +      "type": "string"
        +    },
        +    "notifications": {
        +      "description": "Notification attempts, newest first; present when include=notifications was passed.",
        +      "items": {
        +        "properties": {
        +          "channelType": {
        +            "description": "Delivery channel, e.g. email or slack.",
        +            "type": "string"
        +          },
        +          "connection": {
        +            "description": "Targeted integration {uid, name, type}, or null when the target was a user.",
        +            "properties": {
        +              "name": {
        +                "description": "Integration name.",
        +                "type": "string"
        +              },
        +              "type": {
        +                "description": "Integration type, e.g. email or webhook.",
        +                "type": "string"
        +              },
        +              "uid": {
        +                "description": "Integration UID.",
        +                "type": "string"
        +              }
        +            },
        +            "type": [
        +              "object",
        +              "null"
        +            ]
        +          },
        +          "createdAt": {
        +            "description": "RFC3339 timestamp when the attempt was recorded.",
        +            "type": "string"
        +          },
        +          "error": {
        +            "description": "Delivery error; absent when there was none.",
        +            "type": "string"
        +          },
        +          "eventType": {
        +            "description": "Incident event that triggered the attempt.",
        +            "type": "string"
        +          },
        +          "incident": {
        +            "description": "Incident context {uid, title, state, startedAt}; absent unless the query filled it.",
        +            "properties": {
        +              "startedAt": {
        +                "description": "RFC3339 incident start.",
        +                "type": "string"
        +              },
        +              "state": {
        +                "description": "Incident state: active or resolved.",
        +                "type": "string"
        +              },
        +              "title": {
        +                "description": "Incident title.",
        +                "type": "string"
        +              },
        +              "uid": {
        +                "description": "Incident UID.",
        +                "type": "string"
        +              }
        +            },
        +            "type": "object"
        +          },
        +          "incidentUid": {
        +            "description": "Incident the attempt belongs to.",
        +            "type": "string"
        +          },
        +          "messageId": {
        +            "description": "Provider message ID; absent when the channel did not return one.",
        +            "type": "string"
        +          },
        +          "repeatIndex": {
        +            "description": "Escalation repeat round; absent for direct sends.",
        +            "type": "integer"
        +          },
        +          "sentAt": {
        +            "description": "RFC3339 timestamp when it was delivered; absent until sent.",
        +            "type": "string"
        +          },
        +          "skipReason": {
        +            "description": "Why the attempt was skipped; absent when it was not skipped.",
        +            "type": "string"
        +          },
        +          "source": {
        +            "description": "What triggered it, e.g. check_connection, escalation_user or escalation_schedule.",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Delivery status: pending, sent, failed, cancelled or skipped.",
        +            "type": "string"
        +          },
        +          "stepUid": {
        +            "description": "Escalation step that produced the attempt; absent for direct sends.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Notification row UID.",
        +            "type": "string"
        +          },
        +          "user": {
        +            "description": "Targeted user {uid, name}, or null when the target was a connection.",
        +            "properties": {
        +              "name": {
        +                "description": "User display name.",
        +                "type": "string"
        +              },
        +              "uid": {
        +                "description": "User UID.",
        +                "type": "string"
        +              }
        +            },
        +            "type": [
        +              "object",
        +              "null"
        +            ]
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "number": {
        +      "description": "Short per-org reference, e.g. 42.",
        +      "type": "integer"
        +    },
        +    "relapseCount": {
        +      "description": "Number of times the incident reopened.",
        +      "type": "integer"
        +    },
        +    "resolvedAt": {
        +      "description": "RFC3339 timestamp when it resolved; absent while active.",
        +      "type": "string"
        +    },
        +    "startedAt": {
        +      "description": "RFC3339 timestamp when the incident opened.",
        +      "type": "string"
        +    },
        +    "state": {
        +      "description": "active or resolved.",
        +      "type": "string"
        +    },
        +    "title": {
        +      "description": "Custom title, when one was set.",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Incident UID.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedget_maintenance_window
    • Changedget_status_page5 fields changed
      • addedInput schema / properties / active
        Added value: +{
        +  "description": "With include=incidents: when true, only publications that are not resolved.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / include
        Added value: +{
        +  "description": "Extra lists to return with the page. An unknown value is an error. Do not combine \"sections\" with with=sections.",
        +  "items": {
        +    "enum": [
        +      "sections",
        +      "resources",
        +      "incidents"
        +    ],
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / sectionIdentifier
        Added value: +{
        +  "description": "Section UID or slug whose resources include=resources returns (required with it).",
        +  "type": "string"
        +}
      • addedInput schema / properties / state
        Added value: +{
        +  "description": "With include=incidents: only publications in this public state. Allowed: \"investigating\", \"identified\", \"monitoring\", \"resolved\".",
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "createdAt": {
        +      "description": "RFC3339 creation timestamp.",
        +      "type": "string"
        +    },
        +    "enabled": {
        +      "description": "Whether the public page is served.",
        +      "type": "boolean"
        +    },
        +    "historyPeriod": {
        +      "description": "History window: \"24h\", \"7d\", \"30d\" or \"90d\".",
        +      "type": "string"
        +    },
        +    "incidents": {
        +      "description": "Incident publications on the page; present with include=incidents.",
        +      "items": {
        +        "properties": {
        +          "autoCreated": {
        +            "description": "True when the publication was created by the auto-publish pipeline.",
        +            "type": "boolean"
        +          },
        +          "createdAt": {
        +            "description": "RFC3339 creation timestamp.",
        +            "type": "string"
        +          },
        +          "humanTouched": {
        +            "description": "True once an operator edited it, which stops auto-resolve.",
        +            "type": "boolean"
        +          },
        +          "incidentUid": {
        +            "description": "Linked internal incident UID, when the publication tracks one.",
        +            "type": "string"
        +          },
        +          "publishedAt": {
        +            "description": "RFC3339 timestamp when the entry appeared on the page.",
        +            "type": "string"
        +          },
        +          "resolvedAt": {
        +            "description": "RFC3339 timestamp when it was resolved; absent while open.",
        +            "type": "string"
        +          },
        +          "severity": {
        +            "description": "Public severity: minor, major or critical; absent when unset.",
        +            "type": "string"
        +          },
        +          "stale": {
        +            "description": "True when the linked incident has resolved while the entry is still open.",
        +            "type": "boolean"
        +          },
        +          "state": {
        +            "description": "Public state: investigating, identified, monitoring or resolved.",
        +            "type": "string"
        +          },
        +          "statusPageUid": {
        +            "description": "UID of the status page the publication lives on.",
        +            "type": "string"
        +          },
        +          "title": {
        +            "description": "Customer-facing title.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Publication UID.",
        +            "type": "string"
        +          },
        +          "updatedAt": {
        +            "description": "RFC3339 last-update timestamp.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "isDefault": {
        +      "description": "Whether this is the organization's default page.",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "Display name.",
        +      "type": "string"
        +    },
        +    "resources": {
        +      "description": "Resources of the section named by sectionIdentifier; present with include=resources.",
        +      "items": {
        +        "properties": {
        +          "checkGroupUid": {
        +            "description": "Pinned check group UID, when the resource targets a group.",
        +            "type": "string"
        +          },
        +          "checkUid": {
        +            "description": "Pinned check UID, when the resource targets a check.",
        +            "type": "string"
        +          },
        +          "explanation": {
        +            "description": "Short explanation rendered under the resource.",
        +            "type": "string"
        +          },
        +          "position": {
        +            "description": "Display position within the section (smaller renders earlier).",
        +            "type": "integer"
        +          },
        +          "publicName": {
        +            "description": "Display name shown on the public page.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Resource UID.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "sections": {
        +      "description": "Sections; absent unless with=sections (nested resources included) or include=sections (section metadata only) was passed.",
        +      "items": {
        +        "properties": {
        +          "name": {
        +            "description": "Section display name.",
        +            "type": "string"
        +          },
        +          "position": {
        +            "description": "Display position (smaller renders earlier).",
        +            "type": "integer"
        +          },
        +          "resources": {
        +            "description": "Pinned checks and groups of the section.",
        +            "items": {
        +              "properties": {
        +                "checkGroupUid": {
        +                  "description": "Pinned check group UID, when the resource targets a group.",
        +                  "type": "string"
        +                },
        +                "checkUid": {
        +                  "description": "Pinned check UID, when the resource targets a check.",
        +                  "type": "string"
        +                },
        +                "explanation": {
        +                  "description": "Short explanation rendered under the resource.",
        +                  "type": "string"
        +                },
        +                "position": {
        +                  "description": "Display position within the section (smaller renders earlier).",
        +                  "type": "integer"
        +                },
        +                "publicName": {
        +                  "description": "Display name shown on the public page.",
        +                  "type": "string"
        +                },
        +                "uid": {
        +                  "description": "Resource UID.",
        +                  "type": "string"
        +                }
        +              },
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "selector": {
        +            "description": "Dynamic membership rule; absent on hand-curated sections.",
        +            "type": "object"
        +          },
        +          "slug": {
        +            "description": "URL-friendly slug, unique within the page.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Section UID.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "slug": {
        +      "description": "URL-friendly slug.",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Status page UID.",
        +      "type": "string"
        +    },
        +    "visibility": {
        +      "description": "\"public\", \"private\" or \"password\".",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedincident_notifications_list
    • Changedlist_check_groups1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Check groups on this page.",
        +      "items": {
        +        "properties": {
        +          "checkCount": {
        +            "description": "Number of member checks.",
        +            "type": "integer"
        +          },
        +          "createdAt": {
        +            "description": "RFC3339 creation timestamp.",
        +            "type": "string"
        +          },
        +          "description": {
        +            "description": "Free-text description, when set.",
        +            "type": "string"
        +          },
        +          "escalationPolicyUid": {
        +            "description": "Group-level escalation policy member checks inherit, when set.",
        +            "type": "string"
        +          },
        +          "memberStatusCounts": {
        +            "description": "Per-status count of enabled member checks, e.g. {\"up\": 3, \"down\": 1}.",
        +            "type": "object"
        +          },
        +          "name": {
        +            "description": "Human-readable name.",
        +            "type": "string"
        +          },
        +          "slug": {
        +            "description": "URL-friendly slug.",
        +            "type": "string"
        +          },
        +          "sortOrder": {
        +            "description": "Display order among the org's groups.",
        +            "type": "integer"
        +          },
        +          "status": {
        +            "description": "Rollup of enabled member checks' statuses, recomputed on every read.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Check group UID.",
        +            "type": "string"
        +          },
        +          "updatedAt": {
        +            "description": "RFC3339 last-update timestamp.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlist_check_types2 fields changed
      • addedInput schema / properties / type
        Added value: +{
        +  "description": "Optional check type whose sample configs to return (e.g. \"http\", \"dns\", \"tcp\", \"icmp\", \"ssl\").",
        +  "type": "string"
        +}
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Without type: check types this server supports, with their activation status. With type: one entry per matching check type, carrying its sample configs.",
        +      "items": {
        +        "properties": {
        +          "advisory": {
        +            "description": "Extra availability caveat for an enabled type; absent when there is none.",
        +            "type": "string"
        +          },
        +          "checkType": {
        +            "description": "Check type the samples belong to, e.g. \"http\".",
        +            "type": "string"
        +          },
        +          "defaultPeriodSeconds": {
        +            "description": "Default check interval in seconds; absent when there is no default.",
        +            "type": "integer"
        +          },
        +          "description": {
        +            "description": "Human-readable description of what the type monitors.",
        +            "type": "string"
        +          },
        +          "disabledReason": {
        +            "description": "Why the type is disabled; absent when there is nothing to say.",
        +            "type": "string"
        +          },
        +          "enabled": {
        +            "description": "Whether the type is available on this server.",
        +            "type": "boolean"
        +          },
        +          "labels": {
        +            "description": "Category labels for the type.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "maxPeriodSeconds": {
        +            "description": "Maximum check interval in seconds; absent when unbounded.",
        +            "type": "integer"
        +          },
        +          "minPeriodSeconds": {
        +            "description": "Minimum check interval in seconds; absent when unbounded.",
        +            "type": "integer"
        +          },
        +          "samples": {
        +            "description": "Ready-made configs to clone and modify.",
        +            "items": {
        +              "properties": {
        +                "config": {
        +                  "description": "Complete, valid config for the check type.",
        +                  "type": "object"
        +                },
        +                "name": {
        +                  "description": "Human-readable sample name.",
        +                  "type": "string"
        +                },
        +                "periodSeconds": {
        +                  "description": "Suggested check interval in seconds.",
        +                  "type": "integer"
        +                },
        +                "slug": {
        +                  "description": "URL-friendly sample slug.",
        +                  "type": "string"
        +                }
        +              },
        +              "type": "object"
        +            },
        +            "type": "array"
        +          },
        +          "secretFields": {
        +            "description": "Top-level config keys the type stores encrypted.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "supportsIpVersion": {
        +            "description": "The type honors the shared ipVersion config key.",
        +            "type": "boolean"
        +          },
        +          "supportsTunnel": {
        +            "description": "The type can run through an SSH check's tunnel.",
        +            "type": "boolean"
        +          },
        +          "type": {
        +            "description": "Check type identifier, e.g. \"http\".",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlist_checks1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Checks on this page.",
        +      "items": {
        +        "properties": {
        +          "checkGroupUid": {
        +            "description": "Check group UID, when the check belongs to a group.",
        +            "type": "string"
        +          },
        +          "config": {
        +            "description": "Check-specific configuration for the type.",
        +            "type": "object"
        +          },
        +          "createdAt": {
        +            "description": "RFC3339 creation timestamp.",
        +            "type": "string"
        +          },
        +          "description": {
        +            "description": "Free-text description.",
        +            "type": "string"
        +          },
        +          "enabled": {
        +            "description": "Whether the check runs.",
        +            "type": "boolean"
        +          },
        +          "labels": {
        +            "description": "Key-value labels.",
        +            "type": "object"
        +          },
        +          "lastResultAt": {
        +            "description": "RFC3339 timestamp of the newest real result.",
        +            "type": "string"
        +          },
        +          "name": {
        +            "description": "Human-readable name.",
        +            "type": "string"
        +          },
        +          "period": {
        +            "description": "Check interval as HH:MM:SS.",
        +            "type": "string"
        +          },
        +          "placement": {
        +            "description": "\"pinned\" or \"auto\".",
        +            "type": "string"
        +          },
        +          "regions": {
        +            "description": "Regions the check runs from.",
        +            "items": {
        +              "type": "string"
        +            },
        +            "type": "array"
        +          },
        +          "slug": {
        +            "description": "URL-friendly slug.",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Synthesized status: up, down, validating, created or degraded.",
        +            "type": "string"
        +          },
        +          "statusChangedAt": {
        +            "description": "RFC3339 timestamp of the last status change.",
        +            "type": "string"
        +          },
        +          "type": {
        +            "description": "Check type, e.g. \"http\".",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Check UID.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "pagination": {
        +      "description": "Cursor pagination state for the filter.",
        +      "properties": {
        +        "cursor": {
        +          "description": "Opaque cursor for the next page; absent on the last page.",
        +          "type": "string"
        +        },
        +        "limit": {
        +          "description": "Page size used for this response.",
        +          "type": "integer"
        +        },
        +        "total": {
        +          "description": "Total checks matching the filter.",
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlist_incidents1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Incidents on this page.",
        +      "items": {
        +        "properties": {
        +          "check": {
        +            "description": "Underlying check, when requested with with=check.",
        +            "type": "object"
        +          },
        +          "checkName": {
        +            "description": "Name of that check.",
        +            "type": "string"
        +          },
        +          "checkSlug": {
        +            "description": "Slug of that check.",
        +            "type": "string"
        +          },
        +          "checkUid": {
        +            "description": "UID of the check the incident is about.",
        +            "type": "string"
        +          },
        +          "description": {
        +            "description": "Custom description, when one was set.",
        +            "type": "string"
        +          },
        +          "failureCount": {
        +            "description": "Number of failures recorded for the incident.",
        +            "type": "integer"
        +          },
        +          "kind": {
        +            "description": "What the incident is about: check, slo_burn or degraded.",
        +            "type": "string"
        +          },
        +          "number": {
        +            "description": "Short per-org reference, e.g. 42.",
        +            "type": "integer"
        +          },
        +          "relapseCount": {
        +            "description": "Number of times the incident reopened.",
        +            "type": "integer"
        +          },
        +          "resolvedAt": {
        +            "description": "RFC3339 timestamp when it resolved; absent while active.",
        +            "type": "string"
        +          },
        +          "startedAt": {
        +            "description": "RFC3339 timestamp when the incident opened.",
        +            "type": "string"
        +          },
        +          "state": {
        +            "description": "active or resolved.",
        +            "type": "string"
        +          },
        +          "title": {
        +            "description": "Custom title, when one was set.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Incident UID.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "pagination": {
        +      "description": "Page state for the filter.",
        +      "properties": {
        +        "cursor": {
        +          "description": "UID of the last incident on a full page; not applied when passed back.",
        +          "type": "string"
        +        },
        +        "size": {
        +          "description": "Page size used for this response.",
        +          "type": "integer"
        +        },
        +        "total": {
        +          "description": "Total incidents matching the filter.",
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "type": "object"
        +}
    • Removedlist_integrations
    • Removedlist_maintenance_windows
    • Changedlist_regions1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Regions available to this organization.",
        +      "items": {
        +        "properties": {
        +          "capabilities": {
        +            "description": "Live worker capabilities, e.g. {\"ipv6\": \"yes\"} (\"yes\", \"no\" or \"unknown\").",
        +            "type": "object"
        +          },
        +          "emoji": {
        +            "description": "Region emoji shown in the UI.",
        +            "type": "string"
        +          },
        +          "name": {
        +            "description": "Human-readable region label.",
        +            "type": "string"
        +          },
        +          "offlineSince": {
        +            "description": "RFC3339 timestamp of when the region went dark — the last time its workers were seen.",
        +            "type": "string"
        +          },
        +          "private": {
        +            "description": "Whether the region is an org-private location served by deported agents.",
        +            "type": "boolean"
        +          },
        +          "slug": {
        +            "description": "Region slug to pass in create_check/update_check; private regions are \"@\"-prefixed.",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "\"online\" or \"offline\" for cloud regions; omitted for private ones.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "defaultRegions": {
        +      "description": "The org's default region slugs, used when a check has no explicit regions.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
    • Changedlist_results2 fields changed
      • changedInput schema / properties / checkType / description
        Previous value: -"Comma-separated check types. Allowed: http, tcp, icmp, dns, ssl, heartbeat, domain. Example: \"http,dns\"."New value: +"Comma-separated check types. Allowed: http, tcp, icmp, dns, heartbeat, email, domain, ssl, smtp, udp, ssh, pop3, imap, websocket, postgresql, ftp, sftp, js, mysql, redis, mongodb, mssql, oracle, clickhouse, grpc, kafka, mqtt, a2s, minecraft, rabbitmq, snmp, docker, browser, freebox_line, dnsbl, sip, kubernetes, ntp, rdp, vnc, prometheus, private-location, crawl, health. Example: \"http,dns\"."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Result rows on this page: raw executions or aggregated rollups.",
        +      "items": {
        +        "properties": {
        +          "availabilityPct": {
        +            "description": "Uptime % for the bucket (with=availabilityPct, aggregated rows only).",
        +            "type": "number"
        +          },
        +          "checkName": {
        +            "description": "Check name (with=checkName).",
        +            "type": "string"
        +          },
        +          "checkSlug": {
        +            "description": "Check slug (with=checkSlug).",
        +            "type": "string"
        +          },
        +          "checkUid": {
        +            "description": "UID of the check this result belongs to.",
        +            "type": "string"
        +          },
        +          "durationMs": {
        +            "description": "Response time in ms (with=durationMs).",
        +            "type": "number"
        +          },
        +          "periodStart": {
        +            "description": "RFC3339 start of the period (raw: execution time).",
        +            "type": "string"
        +          },
        +          "periodType": {
        +            "description": "Aggregation level: raw, hour, day or month.",
        +            "type": "string"
        +          },
        +          "region": {
        +            "description": "Region the check ran in (with=region).",
        +            "type": "string"
        +          },
        +          "status": {
        +            "description": "Result status: up, down, created, running, abandoned…",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Result UID (time-ordered).",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "effectiveFilter": {
        +      "description": "Period filter that actually ran, after the tool's defaulting.",
        +      "properties": {
        +        "periodEndBefore": {
        +          "description": "Applied upper bound (RFC3339); absent when not requested.",
        +          "type": "string"
        +        },
        +        "periodStartAfter": {
        +          "description": "Applied lower bound (RFC3339); set by the default when not requested.",
        +          "type": "string"
        +        },
        +        "periodType": {
        +          "description": "Period types queried, e.g. [\"hour\"].",
        +          "items": {
        +            "type": "string"
        +          },
        +          "type": "array"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "pagination": {
        +      "description": "Cursor pagination for this filter.",
        +      "properties": {
        +        "cursor": {
        +          "description": "Opaque cursor for the next page; absent on the last page.",
        +          "type": "string"
        +        },
        +        "size": {
        +          "description": "Page size used for this response.",
        +          "type": "integer"
        +        }
        +      },
        +      "type": "object"
        +    },
        +    "window": {
        +      "description": "Time window the server actually queried.",
        +      "properties": {
        +        "clamped": {
        +          "description": "True when the server moved periodStartAfter forward (raw requests are clamped to the raw-retention band).",
        +          "type": "boolean"
        +        },
        +        "periodEndBefore": {
        +          "description": "Effective exclusive upper bound (RFC3339); absent when the query has none.",
        +          "type": "string"
        +        },
        +        "periodStartAfter": {
        +          "description": "Effective inclusive lower bound (RFC3339); absent when the query has none.",
        +          "type": "string"
        +        }
        +      },
        +      "type": "object"
        +    }
        +  },
        +  "type": "object"
        +}
    • Removedlist_status_page_incidents
    • Removedlist_status_page_resources
    • Removedlist_status_page_sections
    • Changedlist_status_pages1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "data": {
        +      "description": "Status pages in the organization.",
        +      "items": {
        +        "properties": {
        +          "createdAt": {
        +            "description": "RFC3339 creation timestamp.",
        +            "type": "string"
        +          },
        +          "enabled": {
        +            "description": "Whether the public page is served.",
        +            "type": "boolean"
        +          },
        +          "historyPeriod": {
        +            "description": "History window: \"24h\", \"7d\", \"30d\" or \"90d\".",
        +            "type": "string"
        +          },
        +          "isDefault": {
        +            "description": "Whether this is the organization's default page.",
        +            "type": "boolean"
        +          },
        +          "name": {
        +            "description": "Display name.",
        +            "type": "string"
        +          },
        +          "slug": {
        +            "description": "URL-friendly slug.",
        +            "type": "string"
        +          },
        +          "uid": {
        +            "description": "Status page UID.",
        +            "type": "string"
        +          },
        +          "visibility": {
        +            "description": "\"public\", \"private\" or \"password\".",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "type": "object"
        +}
    • Addedmanage_status_page_incident
    • Addedmanage_status_page_resource
    • Addedmanage_status_page_section
    • Addedprobe
    • Addedrun_check
    • Removedset_maintenance_window_checks
    • Changedupdate_check7 fields changed
      • changedInput schema / properties / enabled / description
        Previous value: -"Toggle whether the check runs."New value: +"Toggle whether the check runs. Set to false to pause the check, true to resume it."
      • addedInput schema / properties / failQuorum
        Added value: +{
        +  "description": "Multi-region quorum: how many of the check's regions must be failing, for the confirmation period, before it is down and an incident opens. \"all\", \"majority\" or a whole number such as \"2\" (clamped to the region count). The default is all regions for 1-2 regions and a majority for 3+. Fewer failing regions than the quorum is a \"regional issue\": the check shows warning and no incident opens. \"all\" keeps the per-result rule: any passing region resets the confirmation. Pass \"default\" to put the check back on the default.",
        +  "type": "string"
        +}
      • addedInput schema / properties / placement
        Added value: +{
        +  "description": "Switch the placement: \"auto\" lets the scheduler place the check (keeping its current region count and every current region still healthy) and move it off a region that goes dark; \"pinned\" freezes the current regions unless regions is also given.",
        +  "type": "string"
        +}
      • addedInput schema / properties / regionCount
        Added value: +{
        +  "description": "Automatic placement only: how many regions run the check. Implies placement auto.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / regionPool
        Added value: +{
        +  "description": "Automatic placement only: candidate cloud region slugs; an empty array means any. Implies placement auto.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / regions / description
        Previous value: -"Replace region list, e.g. [\"eu-west-1\",\"us-east-1\"]. Pass an empty array to run from no regions (effectively pauses execution)."New value: +"Pin the check to exactly these regions, e.g. [\"eu-west-1\",\"us-east-1\"] (placement becomes \"pinned\"). An empty array puts the check back on the default placement: automatic across regionCount healthy regions (unless the org's own default_regions names a private location, which pins it to those defaults). The check keeps running either way; use enabled: false to stop it."
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "checkGroupUid": {
        +      "description": "Check group UID, when the check belongs to a group.",
        +      "type": "string"
        +    },
        +    "config": {
        +      "description": "Check-specific configuration for the type.",
        +      "type": "object"
        +    },
        +    "createdAt": {
        +      "description": "RFC3339 creation timestamp.",
        +      "type": "string"
        +    },
        +    "description": {
        +      "description": "Free-text description.",
        +      "type": "string"
        +    },
        +    "enabled": {
        +      "description": "Whether the check runs.",
        +      "type": "boolean"
        +    },
        +    "labels": {
        +      "description": "Key-value labels.",
        +      "type": "object"
        +    },
        +    "lastResultAt": {
        +      "description": "RFC3339 timestamp of the newest real result.",
        +      "type": "string"
        +    },
        +    "name": {
        +      "description": "Human-readable name.",
        +      "type": "string"
        +    },
        +    "period": {
        +      "description": "Check interval as HH:MM:SS.",
        +      "type": "string"
        +    },
        +    "placement": {
        +      "description": "\"pinned\" or \"auto\".",
        +      "type": "string"
        +    },
        +    "regions": {
        +      "description": "Regions the check runs from.",
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "slug": {
        +      "description": "URL-friendly slug.",
        +      "type": "string"
        +    },
        +    "status": {
        +      "description": "Synthesized status: up, down, validating, created or degraded.",
        +      "type": "string"
        +    },
        +    "statusChangedAt": {
        +      "description": "RFC3339 timestamp of the last status change.",
        +      "type": "string"
        +    },
        +    "type": {
        +      "description": "Check type, e.g. \"http\".",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Check UID.",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedupdate_maintenance_window
    • Changedupdate_status_page1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "createdAt": {
        +      "description": "RFC3339 creation timestamp.",
        +      "type": "string"
        +    },
        +    "enabled": {
        +      "description": "Whether the public page is served.",
        +      "type": "boolean"
        +    },
        +    "historyPeriod": {
        +      "description": "History window: \"24h\", \"7d\", \"30d\" or \"90d\".",
        +      "type": "string"
        +    },
        +    "isDefault": {
        +      "description": "Whether this is the organization's default page.",
        +      "type": "boolean"
        +    },
        +    "name": {
        +      "description": "Display name.",
        +      "type": "string"
        +    },
        +    "slug": {
        +      "description": "URL-friendly slug.",
        +      "type": "string"
        +    },
        +    "uid": {
        +      "description": "Status page UID.",
        +      "type": "string"
        +    },
        +    "visibility": {
        +      "description": "\"public\", \"private\" or \"password\".",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "uid"
        +  ],
        +  "type": "object"
        +}
    • Removedupdate_status_page_incident
    • Removedupdate_status_page_resource
    • Removedupdate_status_page_section
    • Changedvalidate_check1 field changed
      • changedOutput schema / (root)
        Previous value: -nullNew value: +{
        +  "properties": {
        +    "fields": {
        +      "description": "Blocking findings; absent when there are none (valid stays true).",
        +      "items": {
        +        "properties": {
        +          "code": {
        +            "description": "Stable machine-readable rule code, e.g. \"SLUG_TAKEN\"; absent when there is none.",
        +            "type": "string"
        +          },
        +          "message": {
        +            "description": "Human-readable description of the finding.",
        +            "type": "string"
        +          },
        +          "name": {
        +            "description": "Field the finding is about, e.g. \"config\" or \"slug\".",
        +            "type": "string"
        +          },
        +          "severity": {
        +            "description": "error, warning or info; absent means error.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "valid": {
        +      "description": "True when the config would be accepted; false when at least one blocking finding exists.",
        +      "type": "boolean"
        +    },
        +    "warnings": {
        +      "description": "Advisory findings that never block; absent when there are none.",
        +      "items": {
        +        "properties": {
        +          "code": {
        +            "description": "Stable machine-readable rule code, e.g. \"SLUG_TAKEN\"; absent when there is none.",
        +            "type": "string"
        +          },
        +          "message": {
        +            "description": "Human-readable description of the finding.",
        +            "type": "string"
        +          },
        +          "name": {
        +            "description": "Field the finding is about, e.g. \"config\" or \"slug\".",
        +            "type": "string"
        +          },
        +          "severity": {
        +            "description": "error, warning or info; absent means error.",
        +            "type": "string"
        +          }
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "valid"
        +  ],
        +  "type": "object"
        +}
  2. 42 tool updatesv0.32.1
    • First observedcreate_check
    • First observedcreate_incident_publication
    • First observedcreate_integration
    • First observedcreate_maintenance_window
    • First observedcreate_status_page
    • First observedcreate_status_page_incident
    • First observedcreate_status_page_incident_update
    • First observedcreate_status_page_resource
    • First observedcreate_status_page_section
    • First observeddelete_check
    • First observeddelete_incident_publication
    • First observeddelete_maintenance_window
    • First observeddelete_status_page
    • First observeddelete_status_page_resource
    • First observeddelete_status_page_section
    • First observeddiagnose_check
    • First observedget_check
    • First observedget_check_type_samples
    • First observedget_incident
    • First observedget_maintenance_window
    • First observedget_status_page
    • First observedincident_notifications_list
    • First observedlist_check_groups
    • First observedlist_check_types
    • First observedlist_checks
    • First observedlist_incidents
    • First observedlist_integrations
    • First observedlist_maintenance_windows
    • First observedlist_regions
    • First observedlist_results
    • First observedlist_status_page_incidents
    • First observedlist_status_page_resources
    • First observedlist_status_page_sections
    • First observedlist_status_pages
    • First observedset_maintenance_window_checks
    • First observedupdate_check
    • First observedupdate_maintenance_window
    • First observedupdate_status_page
    • First observedupdate_status_page_incident
    • First observedupdate_status_page_resource
    • First observedupdate_status_page_section
    • First observedvalidate_check

TDQS

A4.4/5.0

Scored across 23 tools

Disambiguation5/5

Each tool targets a distinct resource and action, and the descriptions actively cross-reference each other (e.g. get_check vs diagnose_check vs list_results; list_incidents vs manage_status_page_incident for internal vs customer-facing incidents). The few superficially similar pairs are explicitly delineated, leaving little room for misselection.

Naming Consistency4/5

Nearly all tools follow a predictable verb_noun pattern (list_checks, get_check, create_check, update_check, delete_check, get_status_page, etc.). Minor deviations exist: the bare verb 'probe' breaks the pattern, and the manage_status_page_* tools use a 'manage' verb instead of the create/update/delete convention used elsewhere.

Tool Count4/5

At 23 tools the surface sits on the heavier end, but the domain genuinely spans several resource families (checks, results, incidents, status pages, sections, resources, publications), so most tools earn their place. A few consolidation candidates (e.g. the three manage_status_page_* tools) keep it just short of ideal.

Completeness4/5

Checks have full CRUD plus validate/run/diagnose, status pages and their sub-resources have full lifecycle coverage, and results/incidents/regions/types are sensibly read-only. Minor gaps exist (check groups are list-only, and internal incident state changes aren't exposed), but these are largely consistent with the domain's generated/read-mostly nature.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for Uptrack uptime monitoring. Manage monitors and incidents from AI agents like Claude, ChatGPT, and Cursor.
    7 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for Uptimepage uptime monitoring. An LLM client can read your monitors and incidents, run a check on demand, and post incident updates. Writes need an OAuth login and a scoped token, and each one is logged.
    47
    AGPL 3.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Official Hyperping MCP server for uptime, API, cron and server monitoring. 26 tools covering monitors, outages and timelines, uptime, response time, MTTR and MTTA, on-call schedules and escalation policies, over a remote Streamable HTTP endpoint with Bearer token auth and no install.
    1
    MIT