fettle-mcp 0.6.1 → 0.7.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
@@ -10,7 +10,7 @@ Ask your assistant to create a monitor, look up why one went down, acknowledge a
10
10
  incident or pause checks before a deploy — it calls the same public API you would.
11
11
 
12
12
  ```
13
- "Add an HTTP monitor for https://api.acme.dev, check it every minute from all regions."
13
+ "Add an HTTP monitor for https://api.acme.dev, check it every 5 minutes from Europe."
14
14
  "Which of my monitors had incidents this week?"
15
15
  "Pause the checkout monitor — we're deploying for the next 20 minutes."
16
16
  ```
@@ -229,19 +229,21 @@ humans and for clients that do not surface server instructions.
229
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.
230
230
 
231
231
  FINDING THINGS
232
- - 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".
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".
233
233
  - tag filters lists; tag_match "all" (default) needs every tag, "any" one of them.
234
- - Lists are paginated: page from 1, size 1..100 (default 25).
234
+ - Pages: page from 1, size 1..100 (default 25).
235
235
 
236
236
  PLAN LIMITS
237
237
  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.
238
238
 
239
239
  CREATING MONITORS
240
- - check_target probes a target once before create_monitor. list_regions names the region codes.
240
+ - check_target probes a target once before create_monitor.
241
+ - regions: unless the user names some, use every limits.allowed_regions code, up to max_regions; SSL, DNS and port-list TCP take one.
242
+ - After create, tell the user the interval and regions chosen; offer to change the interval (update_monitor).
241
243
  - bulk_create_monitors creates up to 100, all or nothing.
242
244
  - type and target never change after create.
243
- - 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.
244
- - 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.
245
+ - 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.
246
+ - 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.
245
247
  - Exposed ports on a server: follow get_exposed_ports_preset.
246
248
 
247
249
  MANY MONITORS AT ONCE
@@ -265,7 +267,7 @@ ERRORS (start of a failed call's text)
265
267
  - "Invalid argument(s)": names each failing field. "Invalid request:": the rule broken. Fix, retry.
266
268
  - "Forbidden:": a plan limit, an unknown region, or the key's user lacks the permission; the reason says which.
267
269
  - "Not found:": no such id in this organization.
268
- - "Rate limited": wait the seconds given, then retry. All API key calls share the organization's per-minute budget.
270
+ - "Rate limited": wait the seconds given, then retry. All API keys share the organization's per-minute budget.
269
271
  - "Tool '<name>' failed: the API returned 5xx": server fault, retry once later.
270
272
  - "Tool '<name>' does not accept argument(s)": drop the ones named.
271
273
  - "Request failed with status N": read the reason, do not retry unchanged.
@@ -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 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\".\n- tag filters lists; tag_match \"all\" (default) needs every tag, \"any\" one of them.\n- Lists are paginated: 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. list_regions names the region codes.\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 goes to the account email of whoever created the monitor or heartbeat.\n- 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.\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 key calls 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 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",
4
4
  "tools": [
5
5
  {
6
6
  "name": "list_monitors",
@@ -436,7 +436,7 @@
436
436
  {
437
437
  "name": "create_monitor",
438
438
  "title": "Create a monitor",
439
- "description": "Create one monitor that checks a URL, host or port on a schedule from one or more regions, and return it in the get_monitor shape. Use check_target first to catch a typo or an unreachable host; use bulk_create_monitors for several monitors, and create_heartbeat for a job that should report in rather than be probed. Requires a key with the write scope. Plan limits apply (monitor count, minimum interval, monitors faster than 60 seconds, regions per monitor): breaking one is a 403 naming it, so call get_plan_usage first. A paused monitor still counts toward them. An invalid argument is a 422 naming it. Example: {\"name\": \"API\", \"type\": \"HTTP\", \"target\": \"https://api.example.com/health\", \"interval_seconds\": 300, \"timeout_seconds\": 10, \"regions\": [\"eu-central\"], \"config\": {\"expected_status_codes\": [200]}, \"tags\": [\"env:prod\"]}",
439
+ "description": "Create one monitor that checks a URL, host or port on a schedule from one or more regions, and return it in the get_monitor shape. Use check_target first to catch a typo or an unreachable host; use bulk_create_monitors for several monitors, and create_heartbeat for a job that should report in rather than be probed. Requires a key with the write scope. Plan limits apply (monitor count, minimum interval, monitors faster than 60 seconds, regions per monitor): breaking one is a 403 naming it, so call get_plan_usage first. A paused monitor still counts toward them. An invalid argument is a 422 naming it. The example shows the shape for a plan with one region per monitor; take interval_seconds and regions from the user and get_plan_usage, not from it. Example: {\"name\": \"API\", \"type\": \"HTTP\", \"target\": \"https://api.example.com/health\", \"interval_seconds\": 600, \"timeout_seconds\": 10, \"regions\": [\"us-east\"], \"config\": {\"expected_status_codes\": [200]}, \"tags\": [\"env:prod\"]}",
440
440
  "scope": "write",
441
441
  "input_schema": {
442
442
  "type": "object",
@@ -468,7 +468,7 @@
468
468
  "maximum": 86400,
469
469
  "minimum": 30,
470
470
  "type": "integer",
471
- "description": "Seconds between checks, 30 to 86400. The plan sets a minimum (limits.min_interval_seconds) and caps how many monitors may check more often than every 60 seconds (max_fast_monitors); breaking either is a 403 naming the limit."
471
+ "description": "Seconds between checks, 30 to 86400. The plan sets a minimum (limits.min_interval_seconds) and caps how many monitors may check more often than every 60 seconds (max_fast_monitors); breaking either is a 403 naming the limit. Tell the user the interval you chose."
472
472
  },
473
473
  "timeout_seconds": {
474
474
  "maximum": 120,
@@ -482,7 +482,7 @@
482
482
  },
483
483
  "minItems": 1,
484
484
  "type": "array",
485
- "description": "One or more distinct region codes, for example eu-central: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than the plan's max_regions, is a 403. SSL and DNS monitors take exactly one region (422 otherwise)."
485
+ "description": "One or more distinct region codes: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than max_regions, is a 403. SSL, DNS and TCP monitors with a ports list take exactly one region (422 otherwise). Unless the user names regions, pass every code in limits.allowed_regions, up to the plan's max_regions."
486
486
  },
487
487
  "config": {
488
488
  "additionalProperties": true,
@@ -764,13 +764,13 @@
764
764
  {
765
765
  "name": "bulk_create_monitors",
766
766
  "title": "Create several monitors",
767
- "description": "Create 1 to 100 monitors in one call, all or nothing; for a single monitor use create_monitor. Requires a key with the write scope. An invalid item, or a batch that would exceed the plan, rejects the whole call and creates nothing: call get_plan_usage first to check the batch fits. Errors name the failing item. A field that fails validation is named by its path, such as monitors.3.target (index 3 is the fourth item; all such errors are reported at once). Any other item error keeps the status create_monitor would give (403 when its interval or regions break the plan or name an unknown region, 404 for an unknown channel id, 422 for its config or its type's region rules) and its reason starts with monitors[3] (\"<item name>\"): — only the first such item is reported. Read the index only from that leading monitors[N] (the pattern ^monitors\\[(\\d+)\\] after any lead-in such as \"Forbidden: \" or \"Invalid request: \"), never from the name, which may itself contain quotes or brackets. A plan-limit 403 without that prefix is about the batch as a whole: together the items would exceed the plan's monitor count or its quota of monitors below 60 seconds. Fix the item or shrink the batch and send the whole call again. Returns monitors: one list_monitors row per created monitor, in request order. Example: {\"monitors\": [{\"name\": \"db.example.com exposed ports\", \"type\": \"TCP\", \"target\": \"db.example.com\", \"interval_seconds\": 3600, \"timeout_seconds\": 10, \"regions\": [\"eu-central\"], \"config\": {\"ports\": [5432, 6379, 27017], \"expected_state\": \"closed\"}}]}",
767
+ "description": "Create 1 to 100 monitors in one call, all or nothing; for a single monitor use create_monitor. Requires a key with the write scope. An invalid item, or a batch that would exceed the plan, rejects the whole call and creates nothing: call get_plan_usage first to check the batch fits. Errors name the failing item. A field that fails validation is named by its path, such as monitors.3.target (index 3 is the fourth item; all such errors are reported at once). Any other item error keeps the status create_monitor would give (403 when its interval or regions break the plan or name an unknown region, 404 for an unknown channel id, 422 for its config or its type's region rules) and its reason starts with monitors[3] (\"<item name>\"): — only the first such item is reported. Read the index only from that leading monitors[N] (the pattern ^monitors\\[(\\d+)\\] after any lead-in such as \"Forbidden: \" or \"Invalid request: \"), never from the name, which may itself contain quotes or brackets. A plan-limit 403 without that prefix is about the batch as a whole: together the items would exceed the plan's monitor count or its quota of monitors below 60 seconds. Fix the item or shrink the batch and send the whole call again. Returns monitors: one list_monitors row per created monitor, in request order. The example is a port-list TCP monitor, which takes exactly one region and an interval of at least 300 seconds. Example: {\"monitors\": [{\"name\": \"db.example.com exposed ports\", \"type\": \"TCP\", \"target\": \"db.example.com\", \"interval_seconds\": 3600, \"timeout_seconds\": 10, \"regions\": [\"eu-central\"], \"config\": {\"ports\": [5432, 6379, 27017], \"expected_state\": \"closed\"}}]}",
768
768
  "scope": "write",
769
769
  "input_schema": {
770
770
  "type": "object",
771
771
  "properties": {
772
772
  "monitors": {
773
- "description": "1 to 100 monitors, each taking the same fields and rules as create_monitor's arguments. Items with is_active false are created paused and still count toward the plan.",
773
+ "description": "1 to 100 monitors, each taking the same fields and rules as create_monitor's arguments. Items with is_active false are created paused and still count toward the plan. Unless the user names regions, give each item every code in limits.allowed_regions, up to the plan's max_regions; tell the user the intervals you chose.",
774
774
  "items": {
775
775
  "additionalProperties": false,
776
776
  "properties": {
@@ -1434,7 +1434,7 @@
1434
1434
  },
1435
1435
  "minItems": 1,
1436
1436
  "type": "array",
1437
- "description": "One or more distinct region codes, for example eu-central: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than the plan's max_regions, is a 403. SSL and DNS monitors take exactly one region (422 otherwise)."
1437
+ "description": "One or more distinct region codes: the plan's choices are limits.allowed_regions in get_plan_usage. An unknown code, or more regions than max_regions, is a 403. SSL, DNS and TCP monitors with a ports list take exactly one region (422 otherwise)."
1438
1438
  },
1439
1439
  "config": {
1440
1440
  "additionalProperties": true,
@@ -2577,7 +2577,7 @@
2577
2577
  {
2578
2578
  "name": "get_uptime_summary",
2579
2579
  "title": "Get uptime for a monitor",
2580
- "description": "Report one monitor's uptime percentage, average response time and incident count over the last 24 hours, 7 days and 30 days at once, to answer how reliable it has been. For a day-by-day series use get_uptime_daily; for response time per region use get_response_time_by_region; for the individual failures use list_check_results. Returns monitor_id and windows keyed 24h, 7d and 30d, each with uptime_percentage (DEGRADED checks count as up; null when there were no checks), total_checks, up_checks, down_checks, degraded_checks, incident_count and avg_response_time_ms.",
2580
+ "description": "Report one monitor's uptime percentage, average response time and incident count over the last 24 hours, 7 days and 30 days at once, to answer how reliable it has been. For a day-by-day series use get_uptime_daily; for response time per region use get_response_time_by_region; for the individual failures use list_check_results. Returns monitor_id and windows keyed 24h, 7d and 30d, each with uptime_percentage, downtime_seconds, observed_seconds, window_start (later than the window's start when the monitor is younger), total_checks, up_checks, down_checks, degraded_checks, incident_count and avg_response_time_ms. uptime_percentage is the share of observed time outside confirmed outages (an outage counts from the first failing probe to the first probe that is not DOWN; a failure only one region saw does not count; maintenance counts as up; hours with no checks are left out; null when nothing was observed). The check counts are informational: a failed check outside a confirmed outage does not lower uptime_percentage.",
2581
2581
  "scope": "read",
2582
2582
  "input_schema": {
2583
2583
  "type": "object",
@@ -2652,6 +2652,18 @@
2652
2652
  "type": "null"
2653
2653
  }
2654
2654
  ]
2655
+ },
2656
+ "downtime_seconds": {
2657
+ "description": "Seconds of confirmed downtime inside the window.",
2658
+ "type": "integer"
2659
+ },
2660
+ "observed_seconds": {
2661
+ "description": "Seconds inside the window the monitor was observed; uptime is measured over this time. Never less than downtime_seconds.",
2662
+ "type": "integer"
2663
+ },
2664
+ "window_start": {
2665
+ "description": "Start of the window: the window length before now, or when the monitor was created if that is later.",
2666
+ "type": "string"
2655
2667
  }
2656
2668
  },
2657
2669
  "required": [
@@ -2660,7 +2672,10 @@
2660
2672
  "up_checks",
2661
2673
  "down_checks",
2662
2674
  "incident_count",
2663
- "avg_response_time_ms"
2675
+ "avg_response_time_ms",
2676
+ "downtime_seconds",
2677
+ "observed_seconds",
2678
+ "window_start"
2664
2679
  ],
2665
2680
  "type": "object"
2666
2681
  },
@@ -5637,7 +5652,7 @@
5637
5652
  {
5638
5653
  "name": "get_uptime_daily",
5639
5654
  "title": "Get a monitor's daily uptime",
5640
- "description": "Report one monitor's uptime for each UTC day, oldest first and ending today, to find the day an outage or degradation began. Each day has date, uptime_percentage, total_checks, up_checks, down_checks, degraded_checks and maintenance_checks; a degraded check counts as up, and a day with no checks outside maintenance has a null uptime_percentage, not 100. For 24h, 7d and 30d totals use get_uptime_summary. Returns monitor_id and days.",
5655
+ "description": "Report one monitor's uptime for each UTC day, oldest first and ending today, to find the day an outage or degradation began. Each day has date, uptime_percentage, downtime_seconds, observed_seconds, degraded_seconds, total_checks, up_checks, down_checks, degraded_checks and maintenance_checks. degraded_seconds is the day's time in confirmed DEGRADED status (an ongoing degradation counts up to now; 0 for days before this monitor's status history began, when the status ledger shipped); it does not lower uptime_percentage. A day with degraded_seconds above 0 and no confirmed outage is a degraded (yellow) day in the dashboard; degraded_checks alone does not make one. uptime_percentage is the share of the day's observed time outside confirmed outages (an outage counts from the first failing probe to the first probe that is not DOWN; a failure only one region saw does not count; maintenance counts as up; hours with no checks are left out); a day with no checks and no outage has a null uptime_percentage, not 100. The check counts are informational: a failed check outside a confirmed outage does not lower uptime_percentage. For 24h, 7d and 30d totals use get_uptime_summary. Returns monitor_id and days.",
5641
5656
  "scope": "read",
5642
5657
  "input_schema": {
5643
5658
  "type": "object",
@@ -5713,6 +5728,18 @@
5713
5728
  },
5714
5729
  "maintenance_checks": {
5715
5730
  "type": "integer"
5731
+ },
5732
+ "downtime_seconds": {
5733
+ "description": "Seconds of confirmed downtime inside the day.",
5734
+ "type": "integer"
5735
+ },
5736
+ "observed_seconds": {
5737
+ "description": "Seconds of the day the monitor was observed; uptime is measured over this time. Never less than downtime_seconds; 0 means no data.",
5738
+ "type": "integer"
5739
+ },
5740
+ "degraded_seconds": {
5741
+ "description": "Seconds of this UTC day the monitor spent in confirmed DEGRADED status (from the monitor's status history; an ongoing degradation counts up to now). Maintenance is not subtracted. Zero for days before this monitor's status history began (when the status ledger shipped).",
5742
+ "type": "integer"
5716
5743
  }
5717
5744
  },
5718
5745
  "required": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fettle-mcp",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
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 pages from Claude, Cursor or Codex.",
6
6
  "keywords": [