Skip to main content
Glama

Probe a target before creating a monitor

check_target
Read-onlyIdempotent

Run a one-off HTTP, ping, SSL, TCP, or DNS probe from a Fettle-chosen region before creating a monitor to catch typos or unreachable hosts.

Instructions

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"}

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
typeYesHTTP (a URL answers with an expected status), PING (a host answers ICMP), SSL (a certificate is valid and not about to expire), TCP (a port is open, or a list of ports is closed) or DNS (a record resolves, optionally to an expected value).
configNoAs in create_monitor; TCP and DNS need it. The region, interval and update rules there do not apply to a one-off probe. 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.
targetYesWhat to check, up to 2048 characters. HTTP: an http:// or https:// URL (https:// is added when the scheme is missing; port, path and query are kept). PING, SSL, TCP and DNS: a bare public hostname or IP address with no :port and no path (the port goes in config): host:port is a 422, and a full URL is cut down to its host, losing its port. Hostnames are ASCII (punycode for internationalized domains). localhost, *.localhost and addresses that are not public (private, loopback, link-local, CGNAT 100.64.0.0/10, reserved, unspecified) are a 422.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
errorNo
regionYes
statusYesKnown values: up, down, error, unknown.
status_codeNo
failure_kindNo
response_time_msNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.6.1
    • addedInput schema / properties / config / description
      Added value: +"As in create_monitor; TCP and DNS need it. The region, interval and update rules there do not apply to a one-off probe. 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 / target / description
      Added value: +"What to check, up to 2048 characters. HTTP: an http:// or https:// URL (https:// is added when the scheme is missing; port, path and query are kept). PING, SSL, TCP and DNS: a bare public hostname or IP address with no :port and no path (the port goes in config): host:port is a 422, and a full URL is cut down to its host, losing its port. Hostnames are ASCII (punycode for internationalized domains). localhost, *.localhost and addresses that are not public (private, loopback, link-local, CGNAT 100.64.0.0/10, reserved, unspecified) are a 422."
    • addedInput schema / properties / type / description
      Added value: +"HTTP (a URL answers with an expected status), PING (a host answers ICMP), SSL (a certificate is valid and not about to expire), TCP (a port is open, or a list of ports is closed) or DNS (a record resolves, optionally to an expected value)."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "error": {
      +      "anyOf": [
      +        {
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "failure_kind": {
      +      "anyOf": [
      +        {
      +          "description": "Known values: TIMEOUT, DNS_FAILURE, CONNECTION_REFUSED, TLS_INVALID, HTTP_4XX, HTTP_5XX, HTTP_UNEXPECTED_STATUS, KEYWORD_MISSING, TOO_MANY_REDIRECTS, TARGET_BLOCKED, PORT_STATE_MISMATCH, INVALID_TARGET, UNKNOWN.",
      +          "type": "string"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "region": {
      +      "type": "string"
      +    },
      +    "response_time_ms": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    },
      +    "status": {
      +      "description": "Known values: up, down, error, unknown.",
      +      "type": "string"
      +    },
      +    "status_code": {
      +      "anyOf": [
      +        {
      +          "type": "integer"
      +        },
      +        {
      +          "type": "null"
      +        }
      +      ]
      +    }
      +  },
      +  "required": [
      +    "status",
      +    "region"
      +  ],
      +  "type": "object"
      +}
  2. First observedv0.5.4

TDQS

A4.6/5.0
Behavior5/5

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

Annotations cover safety (readOnly, idempotent, non-destructive), and the description still adds real operational context: the write-scope auth requirement, per-address rate limiting with a 429/retry_after contract, and the semantic that 'unknown' means no definite answer rather than a failure. That last point is behavior an agent cannot infer from schema or annotations.

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?

Well front-loaded: purpose, then outputs, then the confusing 'unknown' semantics, then usage, then auth/rate limits, then the example. Slightly dinged because enumerating the returned fields (region, response_time_ms, status_code, error, failure_kind) duplicates what the output schema already provides.

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?

For a probe tool with an output schema in place, the description covers everything an agent needs: auth scope, rate-limit failure mode, the meaning of each status value, and how this call relates to create_monitor and check_now. No gaps remain for correct invocation.

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

Parameters3/5

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

Schema coverage is 100% and the enum values and config sub-fields are thoroughly documented in the schema itself, so the baseline is 3. The description only adds a single worked example ({"type": "HTTP", "target": "https://api.example.com/health"}) and a note that TCP/DNS need config; it does not meaningfully extend parameter semantics beyond the schema.

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?

Specific verb+resource ('Run one real check of a target') with an explicit scope qualifier ('without creating anything'), and it enumerates the result fields. It also distinguishes itself from both siblings it could be confused with: create_monitor and check_now.

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?

Explicit when-to-use ('Use it before create_monitor to catch a typo or an unreachable host'), an explicit non-blocking caveat ('a down result does not stop you creating the monitor'), and the alternative for the other case ('For a monitor that already exists use check_now'). Nothing is left to inference.

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