Skip to main content
Glama

Update a monitor

update_monitor
Idempotent

Change the settings of one existing monitor while leaving its other fields as they are. Pass only the fields to modify; at least one field besides the monitor ID is required.

Instructions

Change one monitor's settings and return it in the get_monitor shape. Only the fields you pass change, and at least one besides monitor_id is required (422 otherwise); type and target never change (create a new monitor instead). Not for pausing or resuming (pause_monitor, resume_monitor), for many monitors at once (bulk_update_monitors) or for tags alone across monitors (bulk_update_monitor_tags). Requires a key with the write scope. Plan limits are checked against the result, as on create_monitor (only moving a monitor below 60 seconds takes a fast slot): breaking one is a 403 naming it. Port-list rules are checked against the result too, so changing only the interval or regions of a port-list TCP monitor can be a 422. Omit a field to keep it; never send null. Example: {"monitor_id": "", "interval_seconds": 600}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNoDisplay name, 1 to 255 characters.
tagsNoReplaces the whole tag list when passed, at most 10; [] clears it; omit it to keep the tags. 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.
configNoReplaces the monitor's whole config, not just the keys you send: a field of the type's schema you leave out resets to its default (read the current one with get_monitor first). Sending only port on a TCP monitor whose expected_state is closed resets it to open. A port-list TCP monitor cannot switch to a single port (422). An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state "open" (default) or "closed", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state "closed", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form.
regionsNoOne 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).
monitor_idYesThe monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404.
channel_idsNoNotification channel uuids from list_channels. When passed it replaces the whole binding; [] clears it, after which every verified, active channel is alerted; omit it to keep the binding. An id that is not an active channel of this organization is a 404.
badge_enabledNoTurns the monitor's public status badge on or off. A monitor on a published status page has a badge even when it is false.
timeout_secondsNoSeconds one check may take before it fails, 1 to 120.
interval_secondsNoSeconds 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.
confirmation_thresholdNoHow many checks in a row must fail in every region before the monitor goes DOWN and an incident opens, 1 to 10; 3 when not set on create.
notification_cooldown_secondsNo60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYes
nameYes
tagsNo
typeYesKnown values: HTTP, PING, SSL, TCP, DNS.
configYes
statusYesKnown values: PENDING, UP, DEGRADED, DOWN, PAUSED.
targetYes
regionsYes
user_idYes
is_activeYes
created_atYes
updated_atYes
channel_idsNo
next_run_atYes
badge_enabledNo
ssl_cert_infoNo
ssl_expires_atYes
last_checked_atYes
region_statusesYesPer-region latest status, sorted by region name. Built from ``region_snapshots``; ``job_id`` is dropped (internal dedup key) and malformed/partial snapshot rows are skipped rather than failing the read.
timeout_secondsYes
interval_secondsYes
confirmation_thresholdYes
notification_cooldown_secondsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed12 schema fields changedv0.6.1
    • addedInput schema / properties / badge_enabled / description
      Added value: +"Turns the monitor's public status badge on or off. A monitor on a published status page has a badge even when it is false."
    • addedInput schema / properties / channel_ids / description
      Added value: +"Notification channel uuids from list_channels. When passed it replaces the whole binding; [] clears it, after which every verified, active channel is alerted; omit it to keep the binding. An id that is not an active channel of this organization is a 404."
    • addedInput schema / properties / config / description
      Added value: +"Replaces the monitor's whole config, not just the keys you send: a field of the type's schema you leave out resets to its default (read the current one with get_monitor first). Sending only port on a TCP monitor whose expected_state is closed resets it to open. A port-list TCP monitor cannot switch to a single port (422). An object whose fields depend on type, all optional unless stated. HTTP: method (GET, HEAD, POST, PUT, PATCH or DELETE, any case; default GET); expected_status_codes (non-empty list of codes 100 to 599, default [200]); keyword (case-sensitive substring the body must contain, at most 1024 characters, not with HEAD); follow_redirects (default true); verify_ssl (default true; false skips TLS verification, so the monitor can never report TLS_INVALID); request_headers (object of name to value: at most 20, a name at most 128 characters of letters, digits and ! # $ % & ' * + - . ^ _ ` | ~, a value at most 1024 bytes of printable ASCII, space or tab, the whole object at most 8192 bytes as JSON; names differing only in case, and Host, Content-Length, Transfer-Encoding, Connection, Upgrade, TE, Trailer, Keep-Alive, CF-Connecting-IP or any Proxy-* name, are a 422); request_body (string, at most 8192 bytes as UTF-8, needs POST, PUT, PATCH or DELETE). Reads return every request_headers value as the literal __FETTLE_UNCHANGED__; writing that literal back in an update keeps the stored value (on create it is a 422). PING: packet_count (1 to 20, default 4). SSL: warn_before_days (1 to 365, default 14) and port (1 to 65535, default 443). TCP: either port (1 to 65535) with expected_state \"open\" (default) or \"closed\", or ports (1 to 20 distinct ports that must all be closed, which needs expected_state \"closed\", exactly one region and interval_seconds of at least 300; a check fails when any of them accepts a connection, and the monitor goes DOWN once confirmation_threshold failures confirm it). Both port and ports, or neither, is a 422; expected_state values are lowercase. DNS: record_type (A, AAAA, CNAME, MX, TXT or NS; required) and expected_value (at most 2048 characters). With expected_value one answer must equal it (case-insensitive, ignoring surrounding spaces and a trailing dot; exact for TXT); without it any answer passes. MX answers are the mail host names without priority (mail.example.com, not 10 mail.example.com). A and AAAA look up every address of the host, IPv4 and IPv6 alike, and any one may match; write an IPv6 address in its shortest form."
    • addedInput schema / properties / confirmation_threshold / description
      Added value: +"How many checks in a row must fail in every region before the monitor goes DOWN and an incident opens, 1 to 10; 3 when not set on create."
    • addedInput schema / properties / interval_seconds / description
      Added value: +"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."
    • addedInput schema / properties / monitor_id / description
      Added value: +"The monitor's uuid from list_monitors. An id that is not a monitor of this organization, or a deleted one, is a 404."
    • addedInput schema / properties / name / description
      Added value: +"Display name, 1 to 255 characters."
    • addedInput schema / properties / notification_cooldown_seconds / description
      Added value: +"60 to 86400 seconds; 1800 when not set on create. Only holds back a duplicate first alert for the same incident within that window. Repeat reminders while an incident stays open and unacknowledged follow the plan's renotify_interval_seconds and renotify_max_count (get_plan_usage; 0 means no reminders) instead, and the recovery alert is never held back."
    • addedInput schema / properties / regions / description
      Added value: +"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)."
    • addedInput schema / properties / tags / description
      Added value: +"Replaces the whole tag list when passed, at most 10; [] clears it; omit it to keep the tags. 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."
    • addedInput schema / properties / timeout_seconds / description
      Added value: +"Seconds one check may take before it fails, 1 to 120."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "badge_enabled": {
      +      "type": "boolean"
      +    },
      +    "channel_ids": {
      +      "items": {
      +        "format": "uuid",
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "config": {
      +      "additionalProperties": true,
      +      "type": "object"
      +    },
      +    "confirmation_threshold": {
      +      "type": "integer"
      +    },
      +    "created_at": {
      +      "type": "string"
      +    },
      +    "id": {
      +      "format": "uuid",
      +      "type": "string"
      +    },
      +    "interval_seconds": {
      +      "type": "integer"
      +    },
      +    "is_active": {
      +      "type": "boolean"
      +    },
      +    "last_checked_at": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "name": {
      +      "type": "string"
      +    },
      +    "next_run_at": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "notification_cooldown_seconds": {
      +      "type": "integer"
      +    },
      +    "region_statuses": {
      +      "description": "Per-region latest status, sorted by region name.\n\nBuilt from ``region_snapshots``; ``job_id`` is dropped (internal\ndedup key) and malformed/partial snapshot rows are skipped rather\nthan failing the read.",
      +      "items": {
      +        "properties": {
      +          "checked_at": {
      +            "type": "string"
      +          },
      +          "display_name": {
      +            "type": "string"
      +          },
      +          "region": {
      +            "type": "string"
      +          },
      +          "status": {
      +            "description": "Known values: UP, DEGRADED, DOWN, ERROR.",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "region",
      +          "status",
      +          "checked_at",
      +          "display_name"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "regions": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "ssl_cert_info": {
      +      "anyOf": [
      +        {
      +          "properties": {
      +            "issuer": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "not_after": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "not_before": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "subject": {
      +              "anyOf": [
      +                {
      +                  "type": "string"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            },
      +            "valid": {
      +              "anyOf": [
      +                {
      +                  "type": "boolean"
      +                },
      +                {
      +                  "type": "null"
      +                }
      +              ]
      +            }
      +          },
      +          "type": "object"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "ssl_expires_at": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "status": {
      +      "description": "Known values: PENDING, UP, DEGRADED, DOWN, PAUSED.",
      +      "type": "string"
      +    },
      +    "tags": {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    "target": {
      +      "type": "string"
      +    },
      +    "timeout_seconds": {
      +      "type": "integer"
      +    },
      +    "type": {
      +      "description": "Known values: HTTP, PING, SSL, TCP, DNS.",
      +      "type": "string"
      +    },
      +    "updated_at": {
      +      "type": "string"
      +    },
      +    "user_id": {
      +      "format": "uuid",
      +      "type": "string"
      +    }
      +  },
      +  "required": [
      +    "id",
      +    "user_id",
      +    "name",
      +    "type",
      +    "target",
      +    "interval_seconds",
      +    "timeout_seconds",
      +    "regions",
      +    "config",
      +    "status",
      +    "last_checked_at",
      +    "next_run_at",
      +    "confirmation_threshold",
      +    "notification_cooldown_seconds",
      +    "ssl_expires_at",
      +    "is_active",
      +    "created_at",
      +    "updated_at",
      +    "region_statuses"
      +  ],
      +  "type": "object"
      +}
  2. First observedv0.5.4

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare idempotency and non-destructiveness; the description goes further with PATCH-like semantics (omitted fields retained, null forbidden), 422/403/404 failure conditions, plan-limit checks against the result, and the config-wholesale-replacement warning. This is substantial behavioral disclosure beyond the structured hints, though it does not restate the safety profile itself.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core mutation semantics, immutability constraint, and routing alternatives before the operational caveats. It is long and dense, but the length is earned by the complexity of an 11-parameter tool with nested config; a few clauses (e.g. the port-list/plan-limit details) could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, the description needn't explain return values, and it focuses correctly on update semantics, error paths, and plan-limit interactions. For a complex nested-config mutation tool, the coverage of edge cases (null handling, config replacement, region/interval constraints) is thorough.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds cross-field meaning the schema cannot: 'omit a field to keep it; never send null', the requires-one-field-beyond-monitor_id rule, and a concrete usage example. These clarify how parameters interact rather than merely restating individual field docs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Change one monitor's settings') plus the scope (single monitor) and return shape ('get_monitor shape'). It explicitly distinguishes itself from bulk_update_monitors, pause_monitor/resume_monitor, and bulk_update_monitor_tags, so an agent can route correctly without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the excluded use cases and their alternatives explicitly (pause/resume, bulk updates, tag-only bulk edits) and tells the agent to use create_monitor for immutable type/target changes. It also states the write-scope prerequisite and the minimum-field requirement, covering when and when-not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.