fettle-mcp
Fettle uptime monitoring (https://fettle.sh) for any MCP client — manage monitors, incidents, heartbeats, maintenance windows and status page incidents from Claude, Cursor or Codex.
npm · fingerprint 130336426dfdb5cf9dc0e620 · repository · RSS
49tools
2recorded versions
3dtracked
changed 1d ago
What changed
Changed 2026-10-29 13:07 UTC
6 descriptions rewritten.
--- pinned/bulk_update_monitor_tags +++ observed/bulk_update_monitor_tags { "annotations": { "destructiveHint": false, - "description": "Add and/or remove tags across up to 300 monitors in one call, all or nothing: each monitor ends with (its tags | add) - remove. Use it to retag a fleet; to replace one monitor's whole tag list use update_monitor, to rename or drop a tag everywhere (heartbeats too) use rename_tag or delete_tag. Requires a key with the write scope. At least one of add or remove is required, and they must not share a tag (422). A monitor that would end with more than 10 tags rejects the whole call (422). Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates. Returns monitors_updated. Example: {\"monitor_ids\": [\"<id from list_monitors>\", \"<id from list_monitors>\"], \"add\": [\"env:prod\"], \"remove\": [\"env:staging\"]}", + "description": "Add and/or remove tags across up to 300 monitors in one call, all or nothing: each monitor ends with (its tags | add) - remove. Use it to retag a fleet; to replace one monitor's whole tag list use update_monitor, to rename or drop a tag everywhere (heartbeats too) use rename_tag or delete_tag. Requires a key with the write scope. At least one of add or remove is required, and they must not share a tag (422). A monitor that would end with more than 10 tags rejects the whole call (422). Each tag is trimmed, lowercased and deduplicated on write, at most 50 characters of a-z, 0-9 and : _ . / -, starting with a letter or digit. Reuse names from list_tags rather than inventing near-duplicates. Returns monitors_updated. Calls are limited to 10 per minute per calling address for an API key, per user for an app connection (never per key or organization); past that it is a 429 with the seconds to wait. Example: {\"monitor_ids\": [\"<id from list_monitors>\", \"<id from list_monitors>\"], \"add\": [\"env:prod\"], \"remove\": [\"env:staging\"]}", "inputSchema": { "additionalProperties": false, "properties": {
--- pinned/check_now +++ observed/check_now { "annotations": { "destructiveHint": false, - "description": "Queue one existing monitor to run on the scheduler's next tick instead of waiting out its interval, for example to confirm a fix. It returns the monitor record, not a check result: call get_monitor or list_check_results a moment later for the outcome. To probe a target that has no monitor yet use check_target; to restart a paused monitor use resume_monitor. Requires a key with the write scope. A repeat call for the same monitor within 30 seconds, or a call on a paused monitor, is a silent no-op that returns it unchanged. Calls are limited to 10 per minute per calling address (not per key or organization); past that it is a 429 with the seconds to wait, so pace a run over many monitors.", + "description": "Queue one existing monitor to run on the scheduler's next tick instead of waiting out its interval, for example to confirm a fix. It returns the monitor record, not a check result: call get_monitor or list_check_results a moment later for the outcome. To probe a target that has no monitor yet use check_target; to restart a paused monitor use resume_monitor. Requires a key with the write scope. A repeat call for the same monitor within 30 seconds, or a call on a paused monitor, is a silent no-op that returns it unchanged. Calls are limited to 10 per minute per calling address for an API key, per user for an app connection (never per key or organization); past that it is a 429 with the seconds to wait, so pace a run over many monitors.", "inputSchema": { "additionalProperties": false, "properties": {
--- pinned/check_target +++ observed/check_target { "annotations": { "destructiveHint": false, - "description": "Run one real check of a target from one region chosen by Fettle, without creating anything. It reports status (up, down, error or unknown), region, response_time_ms, status_code, error and failure_kind. unknown means no definite answer came back, not a failure. Use it before create_monitor to catch a typo or an unreachable host; a down result does not stop you creating the monitor. For a monitor that already exists use check_now. Requires a key with the write scope. It is rate limited per calling address: a 429 whose retry_after says how many seconds to wait. Example: {\"type\": \"HTTP\", \"target\": \"https://api.example.com/health\"}", + "description": "Run one real check of a target from one region chosen by Fettle, without creating anything. It reports status (up, down, error or unknown), region, response_time_ms, status_code, error and failure_kind. unknown means no definite answer came back, not a failure. Use it before create_monitor to catch a typo or an unreachable host; a down result does not stop you creating the monitor. For a monitor that already exists use check_now. Requires a key with the write scope. It is rate limited per calling address for an API key, per user for an app connection: a 429 whose retry_after says how many seconds to wait. Example: {\"type\": \"HTTP\", \"target\": \"https://api.example.com/health\"}", "inputSchema": { "additionalProperties": false, "properties": {
--- pinned/create_status_page_incident +++ observed/create_status_page_incident { "annotations": { "destructiveHint": false, - "description": "Open a new incident on a status page with its first message, to tell the page's visitors about an outage. It is public and emails the page's confirmed subscribers: confirm the wording with the user before calling. Any status but RESOLVED emails every confirmed subscriber at once; RESOLVED records an already closed incident (a postmortem) and emails nobody. To add to an existing incident use post_status_page_update. Requires a key with the write scope. Returns the incident. Example: {\"page_id\": \"<id from list_status_pages>\", \"title\": \"API errors\", \"body\": \"We are investigating elevated error rates.\"}", + "description": "Open a new incident on a status page with its first message, to tell the page's visitors about an outage. It is public and emails the page's confirmed subscribers: confirm the wording with the user before calling. Any status but RESOLVED emails every confirmed subscriber at once; RESOLVED records an already closed incident (a postmortem) and emails nobody. To add to an existing incident use post_status_page_update. Requires a key with the write scope. Returns the incident. Calls are limited to 10 per minute, shared by create_status_page_incident and post_status_page_update, per calling address for an API key, per user for an app connection (never per key or organization); past that it is a 429 with the seconds to wait. Example: {\"page_id\": \"<id from list_status_pages>\", \"title\": \"API errors\", \"body\": \"We are investigating elevated error rates.\"}", "inputSchema": { "additionalProperties": false, "properties": {
--- pinned/post_status_page_update +++ observed/post_status_page_update { "annotations": { "destructiveHint": false, - "description": "Add a message to an existing status page incident and set its status; RESOLVED closes it. It is public and emails the page's confirmed subscribers: confirm the wording with the user before calling. Every confirmed subscriber gets the update, except that resolving an incident they were never told about stays silent. To open a new incident use create_status_page_incident; to fix only the title, silently, use update_status_page_incident. Requires a key with the write scope. A resolved incident accepts only further RESOLVED updates; any other status is a 409. Returns the incident. Example: {\"page_id\": \"<id from list_status_pages>\", \"incident_id\": \"<id from list_status_page_incidents>\", \"status\": \"RESOLVED\", \"body\": \"Fixed; error rates are back to normal.\"}", + "description": "Add a message to an existing status page incident and set its status; RESOLVED closes it. It is public and emails the page's confirmed subscribers: confirm the wording with the user before calling. Every confirmed subscriber gets the update, except that resolving an incident they were never told about stays silent. To open a new incident use create_status_page_incident; to fix only the title, silently, use update_status_page_incident. Requires a key with the write scope. A resolved incident accepts only further RESOLVED updates; any other status is a 409. Returns the incident. Calls are limited to 10 per minute, shared by create_status_page_incident and post_status_page_update, per calling address for an API key, per user for an app connection (never per key or organization); past that it is a 429 with the seconds to wait. Example: {\"page_id\": \"<id from list_status_pages>\", \"incident_id\": \"<id from list_status_page_incidents>\", \"status\": \"RESOLVED\", \"body\": \"Fixed; error rates are back to normal.\"}", "inputSchema": { "additionalProperties": false, "properties": {
--- pinned/update_heartbeat +++ observed/update_heartbeat { "annotations": { "destructiveHint": false, - "description": "Change one heartbeat's name, timing, channels or tags; only the fields you pass change. A new period or grace applies from the next ping: the current deadline (overdue_at) is not recomputed. To stop or restart late alerts use pause_heartbeat or resume_heartbeat instead; ping_url never changes. Requires a key with the write scope. An invalid argument is a 422 naming it; never send null. Returns the heartbeat. Example: {\"heartbeat_id\": \"<id from list_heartbeats>\", \"grace_seconds\": 7200}", + "description": "Change one heartbeat's name, timing, channels or tags; only the fields you pass change. A new period or grace moves the current deadline (overdue_at) at once, counted from the last ping; a heartbeat with no running deadline (no ping or start since it was created or resumed, paused, or already down) is left without one. If the new deadline has already passed, the heartbeat is reported late on the next sweep. To stop or restart late alerts use pause_heartbeat or resume_heartbeat instead; ping_url never changes. Requires a key with the write scope. An invalid argument is a 422 naming it; never send null. Returns the heartbeat. Example: {\"heartbeat_id\": \"<id from list_heartbeats>\", \"grace_seconds\": 7200}", "inputSchema": { "additionalProperties": false, "properties": {
Current tools
Show all 49 tool fingerprints
acknowledge_incident
bulk_create_monitors
bulk_pause_monitors
bulk_resume_monitors
bulk_update_monitor_tags
bulk_update_monitors
check_now
check_target
create_heartbeat
create_maintenance_window
create_monitor
create_status_page_incident
delete_heartbeat
delete_maintenance_window
delete_monitor
delete_status_page_incident
delete_tag
get_exposed_ports_preset
get_heartbeat
get_incident
get_maintenance_window
get_monitor
get_plan_usage
get_response_time_by_region
get_status_page
get_uptime_daily
get_uptime_summary
list_active_maintenance
list_channels
list_check_results
list_heartbeats
list_incidents
list_maintenance_windows
list_monitors
list_regions
list_status_page_incidents
list_status_pages
list_tags
pause_heartbeat
pause_monitor
post_status_page_update
preview_maintenance_window
rename_tag
resume_heartbeat
resume_monitor
update_heartbeat
update_maintenance_window
update_monitor
update_status_page_incident
Watch this server yourself
If you run this server, put the proxy in front of it. It pins these exact fingerprints on first connect and stops the session if they move.
npx -y mcp-pin@0.2.3 -- <your fettle-mcp command>
Or subscribe to this page's RSS feed to be told when it changes.
Badge
The badge states one fact about time and nothing else. It never claims a server is safe.
[](https://mcp-pin.gautamkhosla.com/servers/921b2b3ec6e826e8.html)