Skip to content

Connect an AI assistant with the MCP server

View as Markdown

HostTracker runs a hosted Model Context Protocol (MCP) server. Connect it to an AI assistant and the assistant can operate your account from a conversation: run a live check, list what is down, pause a monitor, schedule maintenance, publish a status page incident or wire up a webhook. Every tool is a thin wrapper over the REST API v2, so it can do exactly what your credential allows and nothing more.

Endpoint https://mcp.host-tracker.com/mcp
Transport Streamable HTTP. Nothing to install or run locally.
Sign-in OAuth 2.1 (sign in and approve, recommended) or an Authorization: Bearer <token> header with an API token
Plan Your plan must include API access - see Rate limits and quotas
Request limit 60 requests per minute per client IP address on the MCP endpoint, plus your plan’s API quota
Paging List tools take limit (1-50, default 20) and cursor
Time Every timestamp in and out is Unix seconds

With OAuth there is no token to copy. The client opens HostTracker’s sign-in page, then a consent card that lists exactly what the assistant will be allowed to do. You press Approve and the client handles the rest: access tokens are short-lived (about an hour) and refreshed silently.

  • If the client does not ask for specific scopes, the connection gets check + monitor:read (run instant checks, read monitors, uptime and incidents).
  • The account scope family is never offered to connected apps.
  • To widen an OAuth connection later, remove and re-add the connector and approve the wider set - scopes on an existing connection cannot be widened silently.
  • To cut a connection off, open Integrations -> API -> Connected apps and click Revoke. Its refresh chain dies immediately; the last access token expires within the hour.

Claude.ai and Claude Desktop: Settings -> Connectors -> Add custom connector -> paste https://mcp.host-tracker.com/mcp -> Connect. Sign in if asked, press Approve on the consent card, and the connector shows as connected.

Claude Code:

Terminal window
claude mcp add --transport http hosttracker https://mcp.host-tracker.com/mcp

Then run /mcp, pick hosttracker and choose Authenticate. The browser opens the sign-in and consent page; Claude Code listens on a localhost port for the redirect, which is normal.

ChatGPT: in developer mode, open connectors and add https://mcp.host-tracker.com/mcp. ChatGPT shows its “link account” step after the first call, which opens the same sign-in and consent page.

Any other client with an OAuth-capable connector dialog needs only the URL.

Use a token for clients that only send static headers, for CI, or when you want a hand-picked scope set and expiration.

  1. Open Integrations -> API in the app (/integrations/api) and create a token.
  2. Tick only the scopes the assistant needs (table below). Scope leaves do not imply each other: monitor:write does not grant monitor:read. A bare family name (monitor) covers every leaf in it.
  3. Set a short expiration and, if the client runs from a fixed address, an IP allow-list. A token cannot be revoked before it expires.
  4. Copy the token - it is shown once.
You want the assistant to… Scopes
Run instant checks check
See monitors, uptime, results and incidents monitor:read
Create, edit, pause or delete monitors and maintenance windows; comment incidents monitor:write
See who is notified about what contact:read, subs:read
Manage contacts and contact groups contact:write (plus contact:read to list them)
Subscribe or unsubscribe contacts to monitors monitor:write
Manage webhooks webhook:read, webhook:write
Manage status pages and publish incidents on them statuspage:read, statuspage:write
Read account usage, limits and quota account:read (API tokens only - OAuth connections never get it)

There is no reason to grant account:write: the MCP server refuses every write under /account whatever the token allows.

Project-scoped, in .mcp.json at the repository root:

{
"mcpServers": {
"hosttracker": {
"type": "http",
"url": "https://mcp.host-tracker.com/mcp",
"headers": { "Authorization": "Bearer YOUR_HOSTTRACKER_API_TOKEN" }
}
}
}

Or from the command line, which writes the same entry:

Terminal window
claude mcp add --transport http hosttracker https://mcp.host-tracker.com/mcp \
--header "Authorization: Bearer YOUR_HOSTTRACKER_API_TOKEN"

Check it with claude mcp list. Inside a session the tools appear prefixed, for example hosttracker_run_instant_check.

The Desktop connector dialog is OAuth-only, so a token goes through the mcp-remote bridge. Settings -> Developer -> Edit config opens claude_desktop_config.json:

{
"mcpServers": {
"hosttracker": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.host-tracker.com/mcp",
"--header", "Authorization:${HT_AUTH}"],
"env": { "HT_AUTH": "Bearer YOUR_HOSTTRACKER_API_TOKEN" }
}
}
}

Quit and restart Desktop completely. Node.js 18 or newer must be on the PATH the desktop app sees.

~/.cursor/mcp.json (all projects) or .cursor/mcp.json (one project):

{
"mcpServers": {
"hosttracker": {
"url": "https://mcp.host-tracker.com/mcp",
"headers": { "Authorization": "Bearer YOUR_HOSTTRACKER_API_TOKEN" }
}
}
}

.vscode/mcp.json in the workspace. The inputs block keeps the token out of the file - VS Code prompts for it once and stores it in its secret storage:

{
"inputs": [
{ "type": "promptString", "id": "ht-token", "description": "HostTracker API token", "password": true }
],
"servers": {
"hosttracker": {
"type": "http",
"url": "https://mcp.host-tracker.com/mcp",
"headers": { "Authorization": "Bearer ${input:ht-token}" }
}
}
}

~/.codeium/windsurf/mcp_config.json:

{
"mcpServers": {
"hosttracker": {
"serverUrl": "https://mcp.host-tracker.com/mcp",
"headers": { "Authorization": "Bearer YOUR_HOSTTRACKER_API_TOKEN" }
}
}
}

Some Windsurf versions use url instead of serverUrl; if the entry is ignored, try the other key.

Any client that can dial a streamable-HTTP MCP endpoint and send a static header works:

URL https://mcp.host-tracker.com/mcp
Header Authorization: Bearer YOUR_HOSTTRACKER_API_TOKEN

A client that can launch a command but not send headers can use the bridge:

Terminal window
npx -y mcp-remote https://mcp.host-tracker.com/mcp --header "Authorization:${HT_AUTH}"

with HT_AUTH set to Bearer YOUR_HOSTTRACKER_API_TOKEN in the environment.

This handshake needs no token and proves the endpoint is reachable from your machine:

Terminal window
curl -sS https://mcp.host-tracker.com/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-06-18","capabilities":{},
"clientInfo":{"name":"curl","version":"1"}}}'

The reply is a text/event-stream frame whose data line carries serverInfo. Then ask the assistant: “use hosttracker to run an http check on example.com”.

65 tools: 63 curated ones (one API call each, small argument sets) plus a guarded generic door for everything else. The scope is what your token or OAuth connection needs.

The tools take flat, simple arguments. Three shapes matter, and getting them wrong is the most common reason a call fails:

  • Lists are comma-separated strings, not JSON arrays. tags="prod,eu", monitorIds="ID1,ID2", alertTypes="down,up", events="monitor.down,monitor.up", componentIds="C1,C2". Passing ["a","b"] to one of these is refused by the client or the server before anything runs.
  • Arguments whose name ends in Json take a JSON document as a string. settingsJson="{\"keywords\":\"Checkout\"}", itemsJson="[{\"contact\":\"ID\",\"events\":[\"down\"]}]". Inside that string the members are exactly the REST API’s members.
  • Timestamps are Unix seconds (integers) and intervals are seconds.

A tool has only the arguments listed below. No tool takes an items or a scope argument, and none takes a raw JSON array or object: where the REST body has one, the tool either takes a ...Json string or builds it for you from comma-separated arguments (create_webhook builds scope from tags or monitorIds). Anything a tool does not expose is reachable through api_request.

List tools take limit 1-50 (default 20; out-of-range values are clamped, not refused) and cursor from the previous answer. Keep calling with the cursor until the answer has no continuation line.

Tool What it does Scope
run_instant_check Runs a one-off check from HostTracker’s locations, polls up to about 30 s and returns per-location results plus the public result-page URL. A check still running comes back partial with the dbId and id to poll. check
get_check_result Fetches the current results of an instant check. check
list_check_types Lists the instant-check types and the device profiles a page-load (waterfall) check can emulate. none

run_instant_check

Argument Type Required Meaning
url string yes The site or host, e.g. example.com or https://example.com.
type string no (default http) A type token from list_check_types: http, ping, port, trace, dns, dnsbl, whois, webRisk, crawl, waterfall (pageSpeed is accepted as an alias).
pools string, comma-separated no (default everywhere) Pool ids to run from, e.g. westeurope,northamerica. An unknown id is refused with the valid ones. (The tool’s own example says europe; there is no europe pool - see Location pool ids.)
device string no Device-emulation profile for a waterfall check, from list_check_types.
strictTls boolean no (default false) http only: fail the check on an untrusted, incomplete, mismatched or self-signed certificate.

get_check_result

Argument Type Required Meaning
dbId integer yes The dbId run_instant_check returned.
id string (GUID) yes The check id run_instant_check returned.

list_check_types takes no arguments.

Tool What it does Scope
list_monitors Lists monitors; filters combine with AND. monitor:read
get_monitor Reads one monitor with its full configuration. monitor:read
create_monitor Creates one monitor (POST /monitor). Adds no subscriptions: attach contacts afterwards with subscribe_contact. monitor:write
update_monitor Changes only the arguments you pass (PATCH /monitor/{id}). monitor:write
delete_monitor Deletes one monitor and its subscriptions. Preview first, then confirmed=true. monitor:write
pause_monitor Stops checking and alerting until resumed (sets enabled: false). monitor:write
resume_monitor Resumes a paused monitor (sets enabled: true). monitor:write
copy_monitor Copies a monitor to one or more new addresses. Many addresses answer with a job id. monitor:write
bulk_create_monitors Validates a batch; with submit=true creates it as an asynchronous job. monitor:write
bulk_update_monitors Applies one patch to every monitor a filter selects; validates unless submit=true. monitor:write
bulk_delete_monitors Deletes every monitor a filter selects; validates unless confirmed=true and expectedCount are both sent. monitor:write
list_monitor_types Lists every monitor type with its label, minimum interval and whether your plan can create it. none (a token adds your limits)

list_monitors

Argument Type Required Meaning
q string no Free-text search over name and url.
state string, comma-separated no up, down, paused, maintenance.
type string, comma-separated no Monitor type tokens, e.g. http,ping.
tag string, comma-separated no Tags; a monitor matches when it carries any of them.
id string, comma-separated no Monitor ids.
sort string no name, state, type, interval, lastChange, url, tags or created; add :desc or :asc, e.g. lastChange:desc.
limit, cursor integer, string no Paging (1-50, default 20).

get_monitor

Argument Type Required Meaning
id string yes The monitor id.
expand string, comma-separated no (default settings,uptime) Extra blocks: settings, uptime, lastResult, lastIncident, subscription, maintenance, attached, spans.
from, to integer (Unix seconds) no Window for uptime and spans.

create_monitor

Argument Type Required Meaning
type string yes Monitor type token: http, api, ping, port, cntCheck, waterfall, tran, sslExp, domainExp, dnsbl, webRisk, database, snmp, counter (list_monitor_types is the live list).
url string for most types The address to monitor. A Counter monitor may carry settings.probeUrl instead.
name string no (default: the url) Display name.
interval integer, seconds no (default: the account’s default cadence) Check interval. Must be one of the account’s allowed intervals and not below the type’s floor.
tags string, comma-separated no Tags for the new monitor.
pools string, comma-separated yes for HTTP, API, ping, port, content check, page speed and transaction Location pool ids, e.g. westeurope,easteurope,northamerica, or allworld for everywhere. Unlike the app, the API applies no account default. Refused for types that run on HostTracker’s own network (SSL expiry, domain expiry, DNSBL, Web Risk, database, SNMP, counter).
enabled boolean no (default true) false creates it paused.
settingsJson string, JSON object per type Type-specific settings with their v2 names, e.g. {"keywords":"Checkout","keywordMode":"PresentAny"}. Fields per type: Monitor fields by type.
dryRun boolean no true validates and previews, creating nothing.

update_monitor

Argument Type Required Meaning
id string yes The monitor id.
name, url string no New name or address.
interval integer, seconds no New interval.
tags string, comma-separated no Replaces the whole tag set. Do not combine with addTags/removeTags.
addTags string, comma-separated no Tags to add, keeping the others.
removeTags string, comma-separated no Tags to remove, keeping the others.
pools string, comma-separated no Replaces the location pools.
settingsJson string, JSON object no Settings to change; members you leave out keep their stored values.

The type cannot be changed, and enabled is changed with pause_monitor / resume_monitor.

delete_monitor, pause_monitor, resume_monitor

Argument Type Required Meaning
id string yes The monitor id.
confirmed boolean delete_monitor only (default false) Without it the tool only shows the monitor it would delete.

copy_monitor

Argument Type Required Meaning
id string yes The monitor to copy from.
urls string, comma-separated yes The new addresses, one copy each.
includeAlerts boolean no (default true) Copy the alert subscriptions.
includeReports boolean no (default true) Copy the report subscriptions.
includeMaintenance boolean no (default true) Copy the maintenance-window coverage.
name string no (default: the address) Name for the copies.

bulk_create_monitors

Argument Type Required Meaning
itemsJson string, JSON array yes Monitor definitions, each shaped like a POST /monitor body: [{"type":"http","url":"a.com","locations":{"pools":["allworld"]}}].
defaultsJson string, JSON object no Members applied to every item, e.g. {"interval":300,"tags":["prod"]}.
submit boolean no (default false) false returns the validation report only; true creates the batch as a job.
idempotencyKey string no (generated) Reuse it on a retry so the batch is not created twice.

bulk_update_monitors

Argument Type Required Meaning
filterJson string, JSON object yes The selection: any of monitorIds, tags, types, states, enabled, q, e.g. {"tags":["prod"]}.
patchJson string, JSON object one of patchJson / operation The change applied to each selected monitor, e.g. {"interval":300} or {"addTags":["eu"]}.
operation string one of patchJson / operation resetStats clears the statistics instead of patching.
submit boolean no (default false) false returns the count and a sample only; true applies it as a job.
idempotencyKey string no (generated) Reuse it on a retry.

bulk_delete_monitors

Argument Type Required Meaning
filterJson string, JSON object yes The selection, as for bulk_update_monitors.
expectedCount integer to delete The matched count the validation step reported.
confirmed boolean to delete (default false) Needed together with expectedCount. Without both, the tool only validates.
idempotencyKey string no (generated) Reuse it on a retry.

list_monitor_types takes no arguments.

Tool What it does Scope
get_uptime_summary Uptime, SLA and response-time figures over a window (GET /monitor/result/summary). monitor:read
list_monitor_results One monitor’s raw check results, newest first. monitor:read
list_incidents Down-episodes across the account or chosen monitors, newest first. monitor:read
get_incident One incident with the transitions that opened and closed it. monitor:read
comment_incident Sets a note on an incident; it replaces any previous one. monitor:write

get_uptime_summary

Argument Type Required Meaning
monitor string, comma-separated yes Monitor ids, up to 500. For a whole-account figure pass monitor="" together with groupBy="account".
from, to integer (Unix seconds) no (default: the last 30 days) The window.
bucket string no (default none) none (one row per monitor), hour, day, week or month.
groupBy string no (default monitor) monitor or account (one row for the whole selection; window up to 30 days).
sla number no A target percentage, e.g. 99.9; adds slaMet and errorBudgetSecRemaining.
metrics string, comma-separated no responseTime, dns, connect, tls, ttfb, transfer.
limit, cursor integer, string no Paging.

This tool has no expand and no sort argument. Rows come back ordered by monitor id, not by uptime - sort them yourself (see Sort a summary). For incident counts per row, call the API through api_request with expand=incidentCounts.

list_monitor_results

Argument Type Required Meaning
monitorId string yes The monitor id.
from, to integer (Unix seconds) no The window (at most 30 days).
state string, comma-separated no up, down.
location string, comma-separated no Location (agent) ids from list_locations(agents=true). The tool text says names; the API takes ids.
expand string, comma-separated no metrics, recheck.
limit, cursor integer, string no Paging.

list_incidents

Argument Type Required Meaning
monitor string, comma-separated no (default: the whole account) Monitor ids.
state string, comma-separated no open, resolved.
severity string, comma-separated no minor, major, critical.
from, to integer (Unix seconds) no Incidents that overlap this window (not clipped to it).
limit, cursor integer, string no Paging.

get_incident: id (string, required - the incident id), expand (string, comma-separated, optional: monitor, recheck). comment_incident: id (string, required), comment (string, required - replaces any previous comment).

Tool What it does Scope
list_maintenance Lists windows. monitor:read
create_maintenance Schedules a window over an explicit list of monitors (POST /maintenance). monitor:write
update_maintenance Changes only what you pass. monitor:write
delete_maintenance Cancels a window. Cancelling an active window makes its monitors alert again at once. monitor:write

list_maintenance

Argument Type Required Meaning
state string, comma-separated no scheduled, active, finished.
monitor string, comma-separated no Monitor ids.
from, to integer (Unix seconds) no The window.
limit, cursor integer, string no Paging.

create_maintenance

Argument Type Required Meaning
name string yes Window name.
from integer (Unix seconds) yes Start instant.
monitorIds string, comma-separated yes The monitors it covers - a fixed list; there is no tag selector.
durationSec integer one of durationSec / to Length in seconds.
to integer (Unix seconds) one of durationSec / to End instant. Sending both is refused.
timezone string no (default UTC) IANA zone, e.g. Europe/Berlin; matters for weekly windows.
suppressAlerts boolean no Suppress alerts. See the note below.
suppressStats boolean no Exclude the window from uptime statistics.
weekDays string, comma-separated no Makes it a weekly window, e.g. Saturday,Sunday.

When you send neither suppressAlerts nor suppressStats, the window suppresses alerts only. When you send either one, the other counts as false - so for “silence alerts and exclude from statistics” send both suppressAlerts=true and suppressStats=true. Sending both as false is refused.

update_maintenance

Argument Type Required Meaning
id string yes The window id.
name, timezone string no New name or zone.
from, to integer (Unix seconds) no New start or end.
durationSec integer no New length.
monitorIds string, comma-separated no Replaces the coverage.
enabled boolean no Switch the window off or on without deleting it.

This tool cannot change the suppression flags, the weekly days or showOnStatusPage; use api_request with PATCH /maintenance/{id} for those.

delete_maintenance: id (string, required), confirmed (boolean, default false - without it the tool only shows the window).

Tool What it does Scope
list_contacts Lists contacts. An unconfirmed contact receives nothing until confirmed. contact:read
get_contact Reads one contact. contact:read
create_contact Meant to create an email, sms, voiceCall or webPush contact - see the caution below. contact:write
update_contact Partially updates a contact. Changing the address re-triggers confirmation. contact:write
delete_contact Deletes a contact and every subscription it had. Preview first, then confirmed=true. contact:write
send_contact_confirmation Sends (or resends) the confirmation code. The code is never returned to the assistant - ask the person for it. contact:write
confirm_contact Confirms a contact with the code it received. contact:write
test_contact Sends a real test alert to a confirmed contact and reports how delivery ended. SMS and voice may cost balance. contact:write
list_contact_groups Lists contact groups. contact:read
create_contact_group Creates a named set of contacts, each with the events it should receive. contact:write
update_contact_group Renames a group and/or replaces its membership. contact:write
delete_contact_group Deletes a group; the contacts themselves stay. contact:write

list_contacts

Argument Type Required Meaning
q string no Free-text search over name and address.
type string, comma-separated no Contact types, e.g. email,sms.
confirmed boolean no true only confirmed, false only unconfirmed.
id string, comma-separated no Contact ids.
limit, cursor integer, string no Paging.

get_contact: id (string, required), expand (string, comma-separated, optional: subscription, template, group).

create_contact

Argument Type Required Meaning
type string yes email, sms, voiceCall or webPush.
address string yes An email address, or a phone number in international format.
name string no Display name.
language string no Message language code, e.g. en.
alertDelay integer, minutes no Delay before an alert is sent to this contact (one of the published delay steps).

update_contact

Argument Type Required Meaning
id string yes The contact id.
name, address, language string no New values. A new address must be confirmed again.
alertDelay integer, minutes no New alert delay.
groupedAlerts boolean no Group several alerts into one message.

delete_contact: id (string, required), confirmed (boolean, default false). send_contact_confirmation: id (string, required). confirm_contact: id (string, required), code (string, required - the 5-digit code the person received). test_contact: id (string, required), alertType (string, optional: up, down or repeatedlyDown). list_contact_groups: limit, cursor.

create_contact_group

Argument Type Required Meaning
name string yes Group name.
itemsJson string, JSON array yes The members: [{"contact":"CONTACT_ID","events":["down","up"]}]. Events: up, down, repeatedlyDown, daily, weekly, monthly, quarterly, yearly.

Example: create_contact_group(name="On-call", itemsJson="[{\"contact\":\"ID1\",\"events\":[\"down\",\"up\"]},{\"contact\":\"ID2\",\"events\":[\"down\",\"up\"]}]"). A group does not subscribe anyone by itself - see Contact groups.

update_contact_group: id (string, required), name (string, optional), itemsJson (string, JSON array, optional - replaces the whole membership). delete_contact_group: id (string, required), confirmed (boolean, default false).

Tool What it does Scope
list_subscriptions Who is notified about what. subs:read
subscribe_contact Subscribes one contact to one monitor (PUT /monitor/{id}/alert/{contactId} and/or .../report/{contactId}). monitor:write
unsubscribe_contact Removes one contact’s subscription to one monitor. monitor:write

list_subscriptions

Argument Type Required Meaning
kind string no (default alert) alert or report.
monitorId, contactId string, comma-separated no Filter by monitor ids and/or contact ids.
monitorQuery, contactQuery string no Free-text search over monitors or contacts.
limit, cursor integer, string no Paging.

subscribe_contact

Argument Type Required Meaning
monitorId string yes The monitor id.
contactId string yes The contact id.
alertTypes string, comma-separated one of alertTypes / frequencies up, down, repeatedlyDown. Replaces this pair’s alert set.
frequencies string, comma-separated one of alertTypes / frequencies daily, weekly, monthly, quarterly, yearly (email contacts). Replaces this pair’s report set.

unsubscribe_contact: monitorId, contactId (strings, required), kind (string, optional: alert, report or both, default both).

For many monitors x contacts at once there is no curated tool: use api_request with POST /alert/bulk or POST /report/bulk (both need confirmed=true, see The confirmation rule), or repeat subscribe_contact per pair.

Tool What it does Scope
list_webhooks Lists webhooks with their enabled state and recent failure count. webhook:read
create_webhook Registers an https webhook for chosen events. The signing secret is returned once. webhook:write
update_webhook Changes url, events, monitor scope, name or enabled state. Re-enabling clears the failure counter. webhook:write
delete_webhook Unregisters a webhook; pending deliveries are dropped. Preview first, then confirmed=true. webhook:write
test_webhook Sends a synthetic delivery and reports the endpoint’s answer. webhook:write
list_webhook_deliveries Recent deliveries of one webhook with outcome and attempts. webhook:read
redeliver_webhook Resends a recorded delivery with the same delivery id. webhook:write

create_webhook

Argument Type Required Meaning
url string yes The public https endpoint.
events string, comma-separated yes Event names, e.g. monitor.down,monitor.up. The list is in Webhook events.
name string no Display name.
monitorIds string, comma-separated no Deliver only for these monitors.
tags string, comma-separated no Deliver only for monitors carrying these tags.

Send at most one of monitorIds and tags; with neither, the webhook covers the whole account. Sending both is refused by the API (a scope names exactly one form). There is no scope argument - the tool builds the REST scope object from these two. Example: create_webhook(url="https://hooks.example.com/ht", events="monitor.down,monitor.up", tags="prod", name="Prod down/up").

update_webhook

Argument Type Required Meaning
id string yes The webhook id.
url, name string no New endpoint or name.
events string, comma-separated no Replaces the event set.
enabled boolean no Enable or disable deliveries.
monitorIds string, comma-separated no Replaces the scope with these monitors. To scope by tags or back to the whole account, use api_request with PATCH /webhook/{id} and a scope object.

delete_webhook: id, confirmed (default false). test_webhook: id, eventName (optional, e.g. monitor.down). redeliver_webhook: id, deliveryId (the d_... id from list_webhook_deliveries). list_webhooks: limit, cursor.

list_webhook_deliveries

Argument Type Required Meaning
id string yes The webhook id.
outcome string, comma-separated no pending, delivered, failed, dropped.
eventName string, comma-separated no Event names.
from, to integer (Unix seconds) no The window.
limit, cursor integer, string no Paging.
Tool What it does Scope
list_status_pages Lists your status pages. statuspage:read
get_status_page Reads one page with its settings and components. statuspage:read
create_status_page Creates a page. It is public at its slug immediately. statuspage:write
update_status_page Changes the title and/or settings. statuspage:write
delete_status_page Deletes a page with its components, incidents and subscribers. Preview first, then confirmed=true. statuspage:write
create_status_page_incident Publishes an incident or a scheduled maintenance on a page and notifies its subscribers. statuspage:write
add_status_page_incident_update Appends an update to an incident’s timeline and moves its state. Notifies subscribers. statuspage:write

create_status_page

Argument Type Required Meaning
slug string yes The page’s permanent address; must be unique.
title string yes Title shown to visitors.
componentsJson string, JSON array no [{"monitorId":"ID","name":"API","group":"Core"}].
settingsJson string, JSON object no Page settings with their v2 names, e.g. {"slaTarget":99.9,"showGroups":true,"features":["barCharts","uptimePercent"]} - see Create a status page.

update_status_page

Argument Type Required Meaning
id string yes The page id.
title string no New title.
settingsJson string, JSON object no Settings to change. They are merged field by field: members you leave out keep their values, and only features replaces its whole set. (The tool’s own text says it replaces the settings object; it does not.)

Components are replaced with api_request and PUT /statuspage/{id}/component.

create_status_page_incident

Argument Type Required Meaning
id string yes The status page id.
title string yes Headline.
message string yes The first timeline message.
state string no (default investigating) investigating, identified, monitoring or resolved.
kind string no (default incident) incident or maintenance.
impact string no minor or major.
componentIds string, comma-separated no Component ids from get_status_page - "C1,C2", not a JSON array.
scheduledStart, scheduledEnd integer (Unix seconds) for kind="maintenance" The planned window.
idempotencyKey string no (generated) Reuse it on a retry so the post is not published twice.

add_status_page_incident_update

Argument Type Required Meaning
id string yes The status page id.
incidentId string yes The incident id.
message string yes The update text.
state string yes investigating, identified, monitoring or resolved.
idempotencyKey string no (generated) Reuse it on a retry.

get_status_page: id. delete_status_page: id, confirmed (default false). list_status_pages: limit, cursor.

Tool What it does Scope
generate_report Requests an uptime report over monitors and a time range; answers with a job id. monitor:write (the tool’s text says monitor:read; the API requires write)
list_report_types Lists report types, formats, sections and schedules. none
get_job One asynchronous job: state, progress and per-item results. the scope of the job’s operation
wait_for_job Polls a job for up to about 30 s; call again if it is still running. the scope of the job’s operation
cancel_job Cancels a queued or running job. Finished items are not rolled back. the scope of the job’s operation
resume_job Continues a job whose state is interrupted. the scope of the job’s operation
get_account Identity, package, usage, limits and status flags. Read-only. account:read (a token; OAuth connections never get it)
get_account_quota API quota headroom and the scopes the current token carries - the first call to make after a 403. account:read
get_account_usage How many monitors, contacts, reports and maintenance windows the account uses out of its plan. account:read
list_locations Location pools (and with agents=true, individual locations). none

generate_report

Argument Type Required Meaning
monitorIds string, comma-separated yes Up to 500 monitors.
from, to integer (Unix seconds) no (default: the last 30 days) The range.
format string no (default pdf) pdf, csv, xml or html.
sections string, comma-separated no (default stats) state, stats, outages, incidents, log.
timezone string no IANA zone the report is rendered in.
language string no Report language code, e.g. en.
idempotencyKey string no (generated) Reuse it on a retry.

get_job: id (string, required), limit (1-50, default 20 per-item results), cursor. wait_for_job, cancel_job, resume_job: id (string, required). list_report_types, get_account, get_account_quota and get_account_usage take no arguments.

list_locations

Argument Type Required Meaning
agents boolean no (default false) true lists individual locations instead of pools.
country string, comma-separated no ISO country codes (with agents=true).
pool string, comma-separated no Pool ids (with agents=true).
limit, cursor integer, string no (default 50) Paging.

pools arguments take pool ids from list_locations (REST GET /agent/pool). The ones most requests need:

Pool id Where
allworld Every location
westeurope Western Europe
easteurope Eastern Europe
northamerica North America
southamerica South America
asia Asia
australia Australia
africa Africa

There is no single europe pool: for “Europe” send westeurope,easteurope. The app’s default for a new monitor, when the account has no defaults of its own, is westeurope,easteurope,northamerica. The pool list is data, not a fixed enum - an account may also see private pools of its own - so confirm an id with list_locations when in doubt; an unknown id is refused with 422 unknown_pool and the list of valid ones. A selection with too few locations answers 422 insufficient_agents. See Monitoring locations.

Tool What it does Scope
describe_api Searches the real v2 operations (paths, parameters, body members) so a call can be built from the contract. none
api_request Calls any v2 operation no curated tool covers. The method and path must match a real operation. the operation’s own scope

describe_api: search (string, optional - a path or operation-id fragment such as /alert, statuspage, createWebhook; omit it to list every path).

api_request

Argument Type Required Meaning
method string yes GET, POST, PATCH, PUT or DELETE.
path string yes The v2 path with ids filled in, e.g. /monitor/ID/incident. No host, no version prefix.
query string no A query string (limit=10&state=down) or a flat JSON object of parameters.
bodyJson string, JSON no The request body, for POST/PATCH/PUT.
idempotencyKey string no Sent as the Idempotency-Key header. Not generated for you - pass one wherever the operation requires it (below).
confirmed boolean no (default false) Must be true for the calls the confirmation rule covers.

api_request refuses a call before sending anything unless confirmed=true when:

  • the method is DELETE (any path), or
  • the method is POST, PATCH or PUT and the path contains /bulk and does not end in /validate.

No v2 path ends in /validate - the dry runs are spelled ...-validate - so today the second rule covers every bulk door and its dry run:

Needs confirmed=true through api_request What it is
POST /alert/bulk, POST /report/bulk Many alert or report subscriptions in one transaction (answers directly, no job, no dry run)
POST /monitor/bulk, POST /monitor/bulk-update, POST /monitor/bulk-delete Bulk monitor jobs
POST /contact/bulk, POST /contact/bulk-delete Bulk contact jobs
POST /monitor/bulk-validate, /monitor/bulk-update-validate, /monitor/bulk-delete-validate, /contact/bulk-validate, /contact/bulk-delete-validate The read-only dry runs (they change nothing, but the rule still asks for confirmed=true)
every DELETE Deletes, unsubscribes, cancelling a maintenance window

A ?dryRun=true in query does not exempt a call - only the method and path are checked. Every other call (GET, and writes such as POST /contact, PUT /monitor/{id}/alert/{contactId}, PATCH /statuspage/{id}) runs without confirmed. The refusal says the call was not executed; show the user what it will do, then repeat it with confirmed=true. For monitor bulk work prefer the curated bulk_*_monitors tools: they run the dry run for you without any confirmation flag.

Operations that need idempotencyKey through api_request (the API answers 400 idempotency_key_required otherwise): POST /monitor/bulk, /monitor/bulk-update, /monitor/bulk-delete, /contact/bulk, /contact/bulk-delete, POST /monitor/report, POST /monitor/{id}/reset-stats, POST /statuspage/{id}/incident, POST /statuspage/{id}/incident/{incidentId}/timeline, POST /contact for an email, sms or voiceCall contact, and POST /monitor when the body carries inline contacts. Sending a key on any other write is harmless.

Writes under /account are always refused, whatever the token allows.

  • Deletes preview first. Every single-resource delete tool deletes nothing on its first call - it returns the live resource so the assistant can confirm with you. Only a repeat call with confirmed=true deletes, and the API then returns a receipt of what was removed. api_request does not preview: without confirmed=true it refuses a DELETE or bulk call outright and sends nothing.
  • Bulk writes validate first. The bulk tools return the validation report; the write needs submit=true, and a bulk delete also needs confirmed=true plus the validated expectedCount. If the selection changed in between, the API refuses with 409 selection_mismatch and deletes nothing.
  • Async work returns a job. Bulk operations, multi-address copies and report generation answer with a job id; poll it with wait_for_job.
  • Publishing is real. Status page incidents and updates go to the public page and to its subscribers at once. Contact tests and confirmations send real messages.
  • Errors come back as tool results. A missing scope, a quota, a validation refusal or a blacklisted URL returns an actionable message naming the problem code. Retry-After is passed through as a value; the server never retries or waits on its own.
  • Untrusted content is fenced. Text a monitored target or a third-party endpoint controls (check errors, webhook response excerpts) is wrapped and length-capped so it cannot pass instructions to the assistant.

These refusals are built into the server and apply whatever your token allows:

  • Any write under /account (profile, email, country, default pools). Account reads stay open.
  • Payments, packages and plan changes, passwords, sign-in and account recovery - none of these are on the API.
  • Minting or revoking API tokens. A token cannot mint another token.
  • Every call is refused for permissions. The refusal names the required and granted scopes. On OAuth, remove and re-add the connector and approve the wider set. On a token, run get_account_quota to see its scopes, then mint a new token - scopes cannot be added to an existing one.
  • The client connects but lists no tools. The client probably dropped the Authorization header; test the same token with curl and a tools/list call.
  • The consent page says the app is not registered. The client’s registration expired (registrations with no approved connection are cleaned up after about 30 days). Remove and re-add the connector.
  • Rate-limit or quota messages. The endpoint limits requests per client IP, and your plan’s API quota applies to the token. The message says which one bound and, when known, when it resets.
  • mcp-remote starts and exits. Usually Node.js older than 18, a header argument split on its space (pass it as Authorization:${HT_AUTH} with the value in the environment), or a stale session under ~/.mcp-auth, which you can delete.
  • A corporate proxy breaks the stream. Streamable HTTP holds a long-lived response; allow mcp.host-tracker.com through without buffering.
  • A token leaked. Tokens cannot be revoked before they expire. Remove it from every client, mint a replacement with a short expiration, and contact [email protected] (never include the token itself).