fettle-mcp 0.7.1 → 0.7.2

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
@@ -226,7 +226,7 @@ humans and for clients that do not surface server instructions.
226
226
  <!-- prettier-ignore-start -->
227
227
  <!-- agent-guide:start -->
228
228
  ```text
229
- 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.
229
+ Fettle is an uptime monitoring service. The tools see only the caller'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.
230
230
 
231
231
  FINDING THINGS
232
232
  - list_monitors: one short row per monitor, to find ids. Filters are JSON arrays. Broken now: status ["DOWN", "DEGRADED"]. Certificates expiring first: type ["SSL"], sort "ssl_expiry".
@@ -262,12 +262,12 @@ OUTAGES
262
262
  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.
263
263
 
264
264
  ERRORS (start of a failed call's text)
265
- - "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.
266
- - "This tool requires/needs an API key with write scope": the key is read-only; tell the user.
265
+ - "Authentication failed": the credential is missing, revoked or expired, the address is not allowed, or its user lost access. Do not retry; tell the user.
266
+ - "This tool requires an API key with write scope" or "needs write access": read-only; tell the user.
267
267
  - "Invalid argument(s)": names each failing field. "Invalid request:": the rule broken. Fix, retry.
268
- - "Forbidden:": a plan limit, an unknown region, or the key's user lacks the permission; the reason says which.
268
+ - "Forbidden:": a plan limit, an unknown region, or the user's role; the reason says which.
269
269
  - "Not found:": no such id in this organization.
270
- - "Rate limited": wait the seconds given, then retry. All API keys share the organization's per-minute budget.
270
+ - "Rate limited": wait the seconds given, then retry. All API keys and app connections share the organization's per-minute budget.
271
271
  - "Tool '<name>' failed: the API returned 5xx": server fault, retry once later.
272
272
  - "Tool '<name>' does not accept argument(s)": drop the ones named.
273
273
  - "Request failed with status N": read the reason, do not retry unchanged.
@@ -323,8 +323,10 @@ There is no OAuth on either channel yet; both authenticate with an API key.
323
323
 
324
324
  Tool calls spend the same per-organization request budget as the REST API — the
325
325
  plan's limit, not a separate one. A rate-limited call comes back saying how many
326
- seconds to wait. `check_now` also has its own cap of 10 calls per minute per
327
- calling address. `get_plan_usage` shows the organization's request budget as
326
+ seconds to wait. Some tools also have their own cap per calling address:
327
+ `check_now` and `bulk_update_monitor_tags` 10 calls per minute each,
328
+ `create_status_page_incident` and `post_status_page_update` 10 per minute
329
+ between them, and `check_target` its own limit. `get_plan_usage` shows the organization's request budget as
328
330
  `limits.api_rate_limit_per_minute`. Plan limits are listed at
329
331
  https://fettle.sh/pricing.
330
332
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "instructions": "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.\n\nFINDING THINGS\n- list_monitors: one short row per monitor, to find ids. Filters are JSON arrays. Broken now: status [\"DOWN\", \"DEGRADED\"]. Certificates expiring first: type [\"SSL\"], sort \"ssl_expiry\".\n- tag filters lists; tag_match \"all\" (default) needs every tag, \"any\" one of them.\n- Pages: page from 1, size 1..100 (default 25).\n\nPLAN LIMITS\nCall 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.\n\nCREATING MONITORS\n- check_target probes a target once before create_monitor.\n- regions: unless the user names some, use every limits.allowed_regions code, up to max_regions; SSL, DNS and port-list TCP take one.\n- After create, tell the user the interval and regions chosen; offer to change the interval (update_monitor).\n- bulk_create_monitors creates up to 100, all or nothing.\n- type and target never change after create.\n- channel_ids: ids from list_channels. Empty or omitted on create alerts every verified, active channel. Email is not a channel: every alert also emails the creator of the monitor or heartbeat.\n- update tools change only the fields you pass; omit one to keep it, never send null. A monitor's config is replaced whole: resend every config field to keep.\n- Exposed ports on a server: follow get_exposed_ports_preset.\n\nMANY MONITORS AT ONCE\nFind 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.\n\nTAGS\nCall 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.\n\nHEARTBEATS\nA 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.\n\nMAINTENANCE\nBefore 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.\n\nOUTAGES\nlist_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.\n\nERRORS (start of a failed call's text)\n- \"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.\n- \"This tool requires/needs an API key with write scope\": the key is read-only; tell the user.\n- \"Invalid argument(s)\": names each failing field. \"Invalid request:\": the rule broken. Fix, retry.\n- \"Forbidden:\": a plan limit, an unknown region, or the key's user lacks the permission; the reason says which.\n- \"Not found:\": no such id in this organization.\n- \"Rate limited\": wait the seconds given, then retry. All API keys share the organization's per-minute budget.\n- \"Tool '<name>' failed: the API returned 5xx\": server fault, retry once later.\n- \"Tool '<name>' does not accept argument(s)\": drop the ones named.\n- \"Request failed with status N\": read the reason, do not retry unchanged.\n",
3
+ "instructions": "Fettle is an uptime monitoring service. The tools see only the caller'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.\n\nFINDING THINGS\n- list_monitors: one short row per monitor, to find ids. Filters are JSON arrays. Broken now: status [\"DOWN\", \"DEGRADED\"]. Certificates expiring first: type [\"SSL\"], sort \"ssl_expiry\".\n- tag filters lists; tag_match \"all\" (default) needs every tag, \"any\" one of them.\n- Pages: page from 1, size 1..100 (default 25).\n\nPLAN LIMITS\nCall 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.\n\nCREATING MONITORS\n- check_target probes a target once before create_monitor.\n- regions: unless the user names some, use every limits.allowed_regions code, up to max_regions; SSL, DNS and port-list TCP take one.\n- After create, tell the user the interval and regions chosen; offer to change the interval (update_monitor).\n- bulk_create_monitors creates up to 100, all or nothing.\n- type and target never change after create.\n- channel_ids: ids from list_channels. Empty or omitted on create alerts every verified, active channel. Email is not a channel: every alert also emails the creator of the monitor or heartbeat.\n- update tools change only the fields you pass; omit one to keep it, never send null. A monitor's config is replaced whole: resend every config field to keep.\n- Exposed ports on a server: follow get_exposed_ports_preset.\n\nMANY MONITORS AT ONCE\nFind 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.\n\nTAGS\nCall 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.\n\nHEARTBEATS\nA 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.\n\nMAINTENANCE\nBefore 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.\n\nOUTAGES\nlist_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.\n\nERRORS (start of a failed call's text)\n- \"Authentication failed\": the credential is missing, revoked or expired, the address is not allowed, or its user lost access. Do not retry; tell the user.\n- \"This tool requires an API key with write scope\" or \"needs write access\": read-only; tell the user.\n- \"Invalid argument(s)\": names each failing field. \"Invalid request:\": the rule broken. Fix, retry.\n- \"Forbidden:\": a plan limit, an unknown region, or the user's role; the reason says which.\n- \"Not found:\": no such id in this organization.\n- \"Rate limited\": wait the seconds given, then retry. All API keys and app connections share the organization's per-minute budget.\n- \"Tool '<name>' failed: the API returned 5xx\": server fault, retry once later.\n- \"Tool '<name>' does not accept argument(s)\": drop the ones named.\n- \"Request failed with status N\": read the reason, do not retry unchanged.\n",
4
4
  "tools": [
5
5
  {
6
6
  "name": "list_monitors",
@@ -2262,7 +2262,7 @@
2262
2262
  {
2263
2263
  "name": "check_now",
2264
2264
  "title": "Check a monitor now",
2265
- "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.",
2265
+ "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.",
2266
2266
  "scope": "write",
2267
2267
  "input_schema": {
2268
2268
  "type": "object",
@@ -2513,7 +2513,7 @@
2513
2513
  {
2514
2514
  "name": "bulk_update_monitor_tags",
2515
2515
  "title": "Retag several monitors at once",
2516
- "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\"]}",
2516
+ "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\"]}",
2517
2517
  "scope": "write",
2518
2518
  "input_schema": {
2519
2519
  "type": "object",
@@ -3924,7 +3924,7 @@
3924
3924
  {
3925
3925
  "name": "update_heartbeat",
3926
3926
  "title": "Update a heartbeat monitor",
3927
- "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}",
3927
+ "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}",
3928
3928
  "scope": "write",
3929
3929
  "input_schema": {
3930
3930
  "type": "object",
@@ -6436,7 +6436,7 @@
6436
6436
  {
6437
6437
  "name": "create_status_page_incident",
6438
6438
  "title": "Post an incident on a status page",
6439
- "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.\"}",
6439
+ "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.\"}",
6440
6440
  "scope": "write",
6441
6441
  "input_schema": {
6442
6442
  "type": "object",
@@ -6604,7 +6604,7 @@
6604
6604
  {
6605
6605
  "name": "post_status_page_update",
6606
6606
  "title": "Post an update to a status page incident",
6607
- "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.\"}",
6607
+ "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.\"}",
6608
6608
  "scope": "write",
6609
6609
  "input_schema": {
6610
6610
  "type": "object",
@@ -7064,7 +7064,7 @@
7064
7064
  {
7065
7065
  "name": "check_target",
7066
7066
  "title": "Probe a target before creating a monitor",
7067
- "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\"}",
7067
+ "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\"}",
7068
7068
  "scope": "write",
7069
7069
  "input_schema": {
7070
7070
  "type": "object",
package/dist/errors.js CHANGED
@@ -32,6 +32,17 @@ function extractMessage(body) {
32
32
  }
33
33
  return "";
34
34
  }
35
+ /**
36
+ * Drop trailing dots and whitespace so a caller can append its own full stop.
37
+ *
38
+ * Mirrors core's `_trim_sentence_end` (`message.rstrip(". \t\r\n")`): server
39
+ * messages often end in a full stop already, and appending ours would give
40
+ * "..". The character set is kept identical to core's so both channels render
41
+ * the same message the same way.
42
+ */
43
+ function trimSentenceEnd(message) {
44
+ return message.replace(/[. \t\r\n]+$/, "");
45
+ }
35
46
  /**
36
47
  * Turn a FastAPI/pydantic `detail` list into a sentence naming each field.
37
48
  *
@@ -98,14 +109,14 @@ export function describeFailure(statusCode, body, headers = null) {
98
109
  "read-only key. Create a write-scoped key in Settings → API Keys at " +
99
110
  "https://fettle.sh and restart the MCP client with it.");
100
111
  }
101
- return `Forbidden: ${message || "the API key is not permitted to perform this action"}.`;
112
+ return `Forbidden: ${trimSentenceEnd(message) || "the API key is not permitted to perform this action"}.`;
102
113
  }
103
114
  if (statusCode === 404) {
104
115
  return (
105
116
  // Same text as core's remote channel. Naming list tools here went stale as
106
117
  // soon as new id sources shipped; each tool's description says where its
107
118
  // ids come from.
108
- `Not found: ${message || "the requested resource does not exist"}. ` +
119
+ `Not found: ${trimSentenceEnd(message) || "the requested resource does not exist"}. ` +
109
120
  "Check the id and try again.");
110
121
  }
111
122
  if (statusCode === 422) {
@@ -113,7 +124,7 @@ export function describeFailure(statusCode, body, headers = null) {
113
124
  if (Array.isArray(detail)) {
114
125
  return describeValidationErrors(detail);
115
126
  }
116
- return (`Invalid request: ${message || "the arguments failed validation"}. ` +
127
+ return (`Invalid request: ${trimSentenceEnd(message) || "the arguments failed validation"}. ` +
117
128
  "Check the argument values and retry.");
118
129
  }
119
130
  if (statusCode === 429) {
@@ -125,7 +136,7 @@ export function describeFailure(statusCode, body, headers = null) {
125
136
  return "Rate limited: too many requests. Slow down and retry shortly.";
126
137
  }
127
138
  return (`Request failed with status ${statusCode}: ` +
128
- `${message || "no further detail was provided"}.`);
139
+ `${trimSentenceEnd(message) || "no further detail was provided"}.`);
129
140
  }
130
141
  /**
131
142
  * Describe a request that never produced a response at all.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH;;;;;;GAMG;AACH,MAAM,0BAA0B,GAAG,iCAAiC,CAAC;AAErE,SAAS,cAAc,CAAC,IAAsB;IAC5C,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IACD,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,OAAe;IACtC,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,wBAAwB,CAAC,MAAiB;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAChD,SAAS;QACX,CAAC;QACD,MAAM,SAAS,GAAG,KAAyC,CAAC;QAC5D,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,MAAM,UAAU,GAAG,GAAG;aACnB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,MAAM,CAAC;aACxE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACvE,MAAM,GAAG,GAAG,OAAO,SAAS,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC;QAC7E,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,uEAAuE,CAAC;IACjF,CAAC;IACD,OAAO,yBAAyB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC;AAClF,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,iBAAiB,CACxB,IAAsB,EACtB,OAAuB;IAEvB,MAAM,QAAQ,GAAG,IAAI,EAAE,WAAW,CAAC;IACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9D,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/C,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAC7B,UAAkB,EAClB,IAAsB,EACtB,UAA0B,IAAI;IAE9B,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO,CACL,iEAAiE;YACjE,kEAAkE;YAClE,qEAAqE;YACrE,sDAAsD,CACvD,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAC,EAAE,CAAC;YACjD,OAAO,CACL,yEAAyE;gBACzE,qEAAqE;gBACrE,uDAAuD,CACxD,CAAC;QACJ,CAAC;QACD,OAAO,cAAc,eAAe,CAAC,OAAO,CAAC,IAAI,qDAAqD,GAAG,CAAC;IAC5G,CAAC;IAED,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,OAAO;QACL,2EAA2E;QAC3E,yEAAyE;QACzE,iBAAiB;QACjB,cAAc,eAAe,CAAC,OAAO,CAAC,IAAI,uCAAuC,IAAI;YACrF,6BAA6B,CAC9B,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC;QAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,CACL,oBAAoB,eAAe,CAAC,OAAO,CAAC,IAAI,iCAAiC,IAAI;YACrF,sCAAsC,CACvC,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,CACL,2DAA2D,UAAU,GAAG;gBACxE,UAAU,CACX,CAAC;QACJ,CAAC;QACD,OAAO,+DAA+D,CAAC;IACzE,CAAC;IAED,OAAO,CACL,8BAA8B,UAAU,IAAI;QAC5C,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,gCAAgC,GAAG,CACnE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAe,EAAE,KAAc;IACtE,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,OAAO,CACL,qCAAqC,OAAO,KAAK,MAAM,kBAAkB;QACzE,8DAA8D;QAC9D,wDAAwD,CACzD,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fettle-mcp",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "mcpName": "sh.fettle/mcp",
5
5
  "description": "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.",
6
6
  "keywords": [