fettle-mcp 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -96,27 +96,96 @@ claude mcp add fettle --env FETTLE_API_KEY=fettle_your_key_here -- npx -y fettle
96
96
 
97
97
  ## Tools
98
98
 
99
- | Tool | Scope | What it does |
100
- | -------------------------- | ----- | ------------------------------------------------------------------------------------------- |
101
- | `list_monitors` | read | List monitors compactly (status, target, tags, SSL expiry), filtered by type, status, tags. |
102
- | `list_tags` | read | List every tag in the organization with how many monitors and heartbeats carry it. |
103
- | `get_monitor` | read | Read one monitor's full configuration and current status by id. |
104
- | `create_monitor` | write | Create a monitor that checks a URL, host or port on a schedule. |
105
- | `update_monitor` | write | Change an existing monitor's settings. |
106
- | `pause_monitor` | write | Stop checking a monitor without deleting it — use before planned downtime. |
107
- | `resume_monitor` | write | Resume checks on a paused monitor. |
108
- | `delete_monitor` | write | Soft-delete a monitor: it stops being checked and leaves the monitor list. |
109
- | `check_now` | write | Re-arm a monitor to run on the next scheduler tick instead of waiting out its interval. |
110
- | `bulk_update_monitor_tags` | write | Add and/or remove tags across up to 300 monitors in one call. |
111
- | `bulk_create_monitors` | write | Create up to 100 monitors in one call — all of them or none. |
112
- | `get_plan_usage` | read | The organization's plan, its limits, and how much of each is used. |
113
- | `get_exposed_ports_preset` | read | Database and admin ports that should not be reachable from the internet. |
114
- | `get_uptime_summary` | read | Uptime, average response time and incident counts over 24h / 7d / 30d at once. |
115
- | `list_incidents` | read | List incidents, optionally filtered by monitor, status, cause or period. |
116
- | `acknowledge_incident` | write | Acknowledge an open incident so repeat notifications stop. |
117
- | `list_heartbeats` | read | List heartbeat (cron / dead-man's-switch) monitors and when each was last pinged. |
118
- | `create_heartbeat` | write | Create a heartbeat monitor and get the URL a scheduled job should ping. |
119
- | `list_status_pages` | read | List status pages, with each page's slug and whether it is published. |
99
+ 49 tools, grouped by what they work on. Read-scope keys can call the `read` ones; everything marked `write` needs a write-scope key.
100
+
101
+ ### Monitors
102
+
103
+ | Tool | Scope | What it does |
104
+ | -------------------------- | ----- | --------------------------------------------------------------------------------------------- |
105
+ | `list_monitors` | read | List monitors compactly (status, target, tags, SSL expiry), filtered by type, status, tags. |
106
+ | `get_monitor` | read | Read one monitor's full configuration and current status by id. |
107
+ | `check_target` | write | Probe a target once from one region before creating a monitor for it. |
108
+ | `create_monitor` | write | Create a monitor that checks a URL, host or port on a schedule. |
109
+ | `bulk_create_monitors` | write | Create up to 100 monitors in one call — all of them or none. |
110
+ | `update_monitor` | write | Change an existing monitor's settings. |
111
+ | `bulk_update_monitors` | write | Set the same interval, regions, channels or thresholds on up to 100 monitors, all or nothing. |
112
+ | `pause_monitor` | write | Stop checking a monitor without deleting it — use before planned downtime. |
113
+ | `bulk_pause_monitors` | write | Pause up to 100 monitors in one call, all or nothing. |
114
+ | `resume_monitor` | write | Resume checks on a paused monitor. |
115
+ | `bulk_resume_monitors` | write | Resume up to 100 paused monitors in one call, all or nothing. |
116
+ | `delete_monitor` | write | Soft-delete a monitor: it stops being checked and leaves the monitor list. |
117
+ | `check_now` | write | Re-arm a monitor to run on the next scheduler tick instead of waiting out its interval. |
118
+ | `get_exposed_ports_preset` | read | Database and admin ports that should not be reachable from the internet. |
119
+
120
+ ### Results and uptime
121
+
122
+ | Tool | Scope | What it does |
123
+ | ----------------------------- | ----- | ------------------------------------------------------------------------------------------ |
124
+ | `get_uptime_summary` | read | Uptime, average response time and incident counts over 24h / 7d / 30d at once. |
125
+ | `get_uptime_daily` | read | A monitor's uptime for each UTC day, oldest first. |
126
+ | `get_response_time_by_region` | read | A monitor's average response time over 24h, 7d or 30d, one series per region. |
127
+ | `list_check_results` | read | Individual check results of a monitor, newest first, filtered by region, status or period. |
128
+
129
+ ### Incidents
130
+
131
+ | Tool | Scope | What it does |
132
+ | ---------------------- | ----- | ------------------------------------------------------------------------ |
133
+ | `list_incidents` | read | List incidents, optionally filtered by monitor, status, cause or period. |
134
+ | `get_incident` | read | Read one incident with its cause and every alert attempt. |
135
+ | `acknowledge_incident` | write | Acknowledge an open incident so repeat notifications stop. |
136
+
137
+ ### Heartbeats
138
+
139
+ | Tool | Scope | What it does |
140
+ | ------------------ | ----- | --------------------------------------------------------------------------------- |
141
+ | `list_heartbeats` | read | List heartbeat (cron / dead-man's-switch) monitors and when each was last pinged. |
142
+ | `get_heartbeat` | read | Read one heartbeat, including its ping URL and when it will be reported late. |
143
+ | `create_heartbeat` | write | Create a heartbeat monitor and get the URL a scheduled job should ping. |
144
+ | `update_heartbeat` | write | Change a heartbeat's name, period, grace, channels or tags. |
145
+ | `pause_heartbeat` | write | Pause a heartbeat: it is not reported late and its pings are ignored. |
146
+ | `resume_heartbeat` | write | Resume a paused heartbeat. |
147
+ | `delete_heartbeat` | write | Delete a heartbeat for good; its ping URL stops working. |
148
+
149
+ ### Maintenance windows
150
+
151
+ | Tool | Scope | What it does |
152
+ | ---------------------------- | ----- | ----------------------------------------------------------------------------------- |
153
+ | `list_maintenance_windows` | read | List maintenance windows (one-time or recurring, organization-wide or per monitor). |
154
+ | `list_active_maintenance` | read | The maintenance windows in effect right now. |
155
+ | `get_maintenance_window` | read | Read one maintenance window with its next three occurrences. |
156
+ | `preview_maintenance_window` | write | Show the next three occurrences a schedule would produce, without saving it. |
157
+ | `create_maintenance_window` | write | Create a window that silences alerts, once or on an iCal RRULE schedule. |
158
+ | `update_maintenance_window` | write | Change a maintenance window. |
159
+ | `delete_maintenance_window` | write | Delete a maintenance window; alerts resume at once. |
160
+
161
+ ### Tags
162
+
163
+ | Tool | Scope | What it does |
164
+ | -------------------------- | ----- | ---------------------------------------------------------------------------------- |
165
+ | `list_tags` | read | List every tag in the organization with how many monitors and heartbeats carry it. |
166
+ | `bulk_update_monitor_tags` | write | Add and/or remove tags across up to 300 monitors in one call. |
167
+ | `rename_tag` | write | Rename a tag on every monitor and heartbeat that carries it. |
168
+ | `delete_tag` | write | Remove a tag from every monitor and heartbeat that carries it. |
169
+
170
+ ### Status pages
171
+
172
+ | Tool | Scope | What it does |
173
+ | ----------------------------- | ----- | --------------------------------------------------------------------------------------------- |
174
+ | `list_status_pages` | read | List status pages, with each page's slug and whether it is published. |
175
+ | `get_status_page` | read | Read one status page with its groups and components. |
176
+ | `list_status_page_incidents` | read | List a status page's incidents, posted by a person or opened by Fettle, with their timelines. |
177
+ | `create_status_page_incident` | write | Open an incident on a status page with a first message. |
178
+ | `post_status_page_update` | write | Add a message to a status page incident and set its status; RESOLVED closes it. |
179
+ | `update_status_page_incident` | write | Rename a status page incident; subscribers are not notified. |
180
+ | `delete_status_page_incident` | write | Remove an incident and its timeline from a status page. |
181
+
182
+ ### Organization and platform
183
+
184
+ | Tool | Scope | What it does |
185
+ | ---------------- | ----- | --------------------------------------------------------------------------- |
186
+ | `get_plan_usage` | read | The organization's plan, its limits, and how much of each is used. |
187
+ | `list_channels` | read | List notification channels (id, type, label, verified) to bind to monitors. |
188
+ | `list_regions` | read | List the check regions and the codes the regions argument takes. |
120
189
 
121
190
  The list is not written by hand. It is generated in the Fettle backend from one
122
191
  registry and served at
@@ -133,53 +202,49 @@ humans and for clients that do not surface server instructions.
133
202
  <!-- prettier-ignore-start -->
134
203
  <!-- agent-guide:start -->
135
204
  ```text
136
- Fettle is an uptime monitoring service. The tools see only the API key's organization: monitors (create, edit, pause, delete, check, tag), heartbeats (create, list), incidents (list, acknowledge), status pages (list). No tool edits, pauses or deletes a heartbeat, manages a status page, or lists or manages notification channels: send the user to https://dashboard.fettle.sh. Each tool's description lists its arguments, limits and errors.
205
+ Fettle is an uptime monitoring service. The tools see only the API key's organization: monitors, heartbeats, maintenance windows, incidents, status page incidents, tags, channels (read), regions. Channels, status pages, members, API keys and billing are managed only in the dashboard (https://dashboard.fettle.sh). Read a tool's description (arguments, limits, errors) before its first call.
137
206
 
138
207
  FINDING THINGS
139
- - list_monitors gives one short row per monitor; use it to find ids. get_monitor returns one monitor's full config and state, get_uptime_summary its uptime over 24h, 7d and 30d.
140
- - Broken right now: list_monitors with status ["DOWN", "DEGRADED"]. List filters are JSON arrays, not repeated arguments. Monitor statuses: PENDING (no verdict yet), UP, DEGRADED, DOWN, PAUSED.
141
- - Certificates expiring first: list_monitors with type ["SSL"] and sort "ssl_expiry".
208
+ - list_monitors gives one short row per monitor; use it to find ids. Filters are JSON arrays. Broken now: status ["DOWN", "DEGRADED"]. Certificates expiring first: type ["SSL"], sort "ssl_expiry".
209
+ - tag filters lists; tag_match "all" (default) needs every tag, "any" one of them.
142
210
  - Lists are paginated: page from 1, size 1..100 (default 25).
143
- - tag filters a list. On list_monitors tag_match "all" (default) needs every tag, "any" one of them; list_heartbeats always needs every tag.
144
211
 
145
212
  PLAN LIMITS
146
- Call get_plan_usage before creating monitors or heartbeats: the plan, its limits (null means no limit) and current usage. Paused monitors count toward the monitor limit. interval_seconds is 30..86400, but the plan sets a minimum (min_interval_seconds); an interval below 60 seconds also uses the fast-interval quota (max_fast_monitors); a monitor may use at most max_regions regions, picked from allowed_regions. A broken limit or an unknown region code is a 403 naming it: change the request or tell the user the limit; never retry it unchanged.
213
+ Call get_plan_usage before creating anything: limits (null means none) and usage. A broken limit or an unknown region is a 403 naming it: change the request or tell the user; never retry it unchanged.
147
214
 
148
215
  CREATING MONITORS
149
- - create_monitor creates one; bulk_create_monitors up to 100, all or nothing: one bad item, or a batch over the plan's limits, creates nothing.
150
- - target: HTTP takes a URL (https:// is added when the scheme is missing). PING, SSL, TCP and DNS take a public hostname or IP, no :port or path; the port goes in config. localhost and non-public addresses (private, loopback, link-local...) are a 422. type and target never change after create.
151
- - is_active false creates a monitor paused; resume_monitor starts it.
152
- - confirmation_threshold (1..10, default 3): how many checks in a row must fail in every region before the monitor goes DOWN and an incident opens. notification_cooldown_seconds (60..86400, default 1800) only holds back a duplicate first alert, never the recovery. Reminders for an open, unacknowledged incident follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means none).
153
- - channel_ids binds notification channels by id (get_monitor shows a monitor's channel_ids). An empty binding alerts every verified, active channel. On create omit it or pass []; on update [] clears the binding and omitting it keeps it.
154
- - update_monitor changes only the fields you pass. Never send null: omit a field to keep it. config is the exception: it replaces the whole config, so send every config field you want to keep.
155
-
156
- CONFIG BY TYPE
157
- - HTTP, all optional: method (default GET), expected_status_codes (default [200]), keyword (case-sensitive text the body must contain; not with HEAD), follow_redirects and verify_ssl (default true), request_headers, request_body (POST, PUT, PATCH, DELETE only).
158
- - PING, optional: packet_count 1..20 (default 4).
159
- - SSL, optional: warn_before_days 1..365 (default 14), port (default 443). One region.
160
- - TCP, config required: port or ports, not both; expected_state "open" (default) or "closed", lowercase.
161
- - DNS, config required: record_type (A, AAAA, CNAME, MX, TXT, NS); expected_value optional. One region.
162
-
163
- EXPOSED PORTS ON A SERVER
164
- Read get_exposed_ports_preset. Create ONE TCP monitor on the server's public hostname or IP with config {"ports": [the preset ports], "expected_state": "closed"}: 1..20 distinct ports, one region, interval_seconds at least 300. It counts as one monitor and fails when any listed port accepts a connection.
216
+ - check_target probes a target once before create_monitor. list_regions names the region codes.
217
+ - bulk_create_monitors creates up to 100, all or nothing.
218
+ - type and target never change after create.
219
+ - channel_ids: ids from list_channels. Empty or omitted on create alerts every verified, active channel. Email is not a channel: every alert also goes to the account email of whoever created the monitor or heartbeat.
220
+ - update tools change only the fields you pass. Never send null; omit a field to keep it. A monitor's config is replaced whole: send every config field you want to keep.
221
+ - Exposed ports on a server: follow get_exposed_ports_preset.
222
+
223
+ MANY MONITORS AT ONCE
224
+ Find ids with list_monitors, then bulk_pause_monitors, bulk_resume_monitors or bulk_update_monitors (interval, timeout, regions, channels, threshold, cooldown) for up to 100 ids, all or nothing. bulk_update_monitor_tags adds or removes tags on up to 300. There is no bulk delete.
165
225
 
166
226
  TAGS
167
- Call list_tags first and reuse existing names. Tags are trimmed, lowercased and deduplicated; at most 10 per monitor or heartbeat, each at most 50 characters of a-z 0-9 : _ . / - starting with a letter or digit.
227
+ Call list_tags first and reuse names. Tags are flat labels such as env:prod, trimmed, lowercased and deduplicated; at most 10 per item. rename_tag and delete_tag act on every monitor and heartbeat.
168
228
 
169
229
  HEARTBEATS
170
- A heartbeat waits for a scheduled job to call its ping_url. It is never reported late before its first successful ping. After that an alert fires period_seconds + grace_seconds after the last ping; ping_url + "/start" also restarts the clock, ping_url + "/fail" marks it DOWN at once. Job every N seconds, alert after T seconds of silence: period_seconds = N, grace_seconds = T - N.
230
+ A job calls ping_url when it succeeds. Job every N seconds, alert after T seconds of silence: period_seconds = N, grace_seconds = T - N. Never late before its first success ping. ping_url + "/start" restarts the clock, ping_url + "/fail" marks it DOWN at once.
231
+
232
+ MAINTENANCE
233
+ Before a deploy or reboot, create_maintenance_window (scope ORG or MONITOR) instead of pausing monitors: checks keep running, but no incident opens and no alert goes out. Not for heartbeats. preview_maintenance_window shows a schedule's next occurrences; list_active_maintenance shows what is silenced now.
171
234
 
172
- INCIDENTS
173
- list_incidents lists monitor and heartbeat incidents, newest first. An incident resolves itself when its monitor or heartbeat recovers; pausing a monitor closes it silently. acknowledge_incident stops repeat alerts; the recovery alert still goes out.
235
+ OUTAGES
236
+ list_monitors status ["DOWN"] -> list_check_results (status code, error, region per check) -> get_incident. acknowledge_incident stops repeat alerts; the recovery alert still goes out. create_status_page_incident and post_status_page_update can email the page's subscribers: confirm the text with the user first.
174
237
 
175
238
  ERRORS (start of a failed call's text)
176
- - "Authentication failed": the key is missing, unknown, revoked, expired, not allowed from this address, or its creator lost access. Do not retry; tell the user.
177
- - "Invalid argument(s)": names each failing field by path, for example 'monitors.3.target'. "Invalid request:": the rule the request broke. Fix, retry.
178
- - "Forbidden:": a plan limit or unknown region; the reason says which. A message about write scope: the key is read-only, and every tool that changes something needs the write scope.
239
+ - "Authentication failed": the key is missing, revoked or expired, the address is not allowed, or its creator lost access. Do not retry; tell the user.
240
+ - "This tool requires/needs an API key with write scope": the key is read-only; tell the user.
241
+ - "Invalid argument(s)": names each failing field. "Invalid request:": the rule broken. Fix, retry.
242
+ - "Forbidden:": a plan limit, an unknown region, or the key's user lacks the permission; the reason says which.
179
243
  - "Not found:": no such id in this organization.
180
- - "Rate limited": wait the seconds given, then retry. Every tool call counts toward the organization's per-minute budget (get_plan_usage limits.api_rate_limit_per_minute); check_now also has its own cap of 10 per minute per calling address.
181
- - "Tool 'x' failed: the API returned 5xx": server fault, retry once later. "Tool 'x' does not accept argument(s)": drop the ones named.
182
- - "Request failed with status N": any other refusal; read the reason, do not retry unchanged.
244
+ - "Rate limited": wait the seconds given, then retry. All API key calls share the organization's per-minute budget.
245
+ - "Tool '<name>' failed: the API returned 5xx": server fault, retry once later.
246
+ - "Tool '<name>' does not accept argument(s)": drop the ones named.
247
+ - "Request failed with status N": read the reason, do not retry unchanged.
183
248
 
184
249
  ```
185
250
  <!-- agent-guide:end -->
@@ -237,7 +302,7 @@ client: most clients read MCP config only at launch.
237
302
  **`Authentication failed`** — the key is wrong, revoked, or from a deleted
238
303
  organization. Create a fresh one in Settings → API Keys.
239
304
 
240
- **`This tool needs an API key with write scope`** — the key is read-only. Create
305
+ **`This tool requires an API key with write scope`** — the key is read-only. Create
241
306
  a write-scoped key; there is no way to widen an existing key's scope.
242
307
 
243
308
  **The assistant does not see the tools** — restart the client, then confirm