Skip to main content
Glama

create_monitor

DestructiveIdempotent

Create or update monitoring for cron jobs, CI/CD pipelines, and HTTP endpoints: define schedules, probe checks, and alert thresholds to catch missed runs and outages.

Instructions

Create a new LastPing monitor (or update an existing one if slug matches — returns 'updated' note on upsert). For heartbeat/ci monitors supply schedule_kind ('simple' requires period_s, 'cron' requires cron_expr, 'on_demand' requires neither). For http monitors supply probe_url and probe_interval_s instead — and set probe_expected_status/probe_expected_body too, because those are what define 'healthy'; a probe with neither only proves something answered. For a monitor fed by CI rather than by its own pings, set ci_provider here: it is the ONLY place it can be set, and the secret it returns is shown exactly once.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tzNoIANA timezone for cron evaluation. Defaults to UTC.
nameYesHuman-readable monitor name, e.g. 'Daily backup job'.
slugNoOptional stable ID. If a monitor with this slug exists, it will be updated (upsert). Trimmed and lowercased automatically. Must match ^[a-z0-9][a-z0-9-]{1,48}[a-z0-9]$ (3-50 chars, lowercase alphanumeric and hyphens, starting and ending alphanumeric) after normalisation. UUID-shaped slugs are rejected — they would be ambiguous with a monitor id when importing into Terraform. Omit entirely for no slug.
tagsNoComma-separated labels for namespace scoping, e.g. 'agent:claude,env:prod'. Max 20 tags, each max 50 chars.
grace_sNoGrace period in seconds after a ping is due before alerting.
agent_idNoAttach this monitor to an agent from the registry, by the agent's id OR its slug (both are returned by register_agent). Omit for a monitor with no owning agent. Naming an agent that does not exist is an error — 400 UNKNOWN_AGENT — it is NEVER created implicitly; call register_agent first to get a valid agent_id. On an upsert (existing slug), omitting this leaves the monitor's current attachment (or lack of one) unchanged; supplying it re-applies the attachment, so an agent re-running its own registration converges to 'attached' every time rather than silently no-opping after the first call.
period_sNoPing interval in seconds. Required when schedule_kind='simple'.
ci_branchNoCI filter: only count runs on this branch, e.g. 'main'. Requires ci_provider. WITHOUT IT a run on ANY branch — a feature branch, a fork's pull request — reports to this monitor, so somebody else's broken branch marks your monitor down. Set it to the branch whose health you actually care about, which is almost always the default branch.
cron_exprNo5-field cron expression, e.g. '0 3 * * *'. Required when schedule_kind='cron'.
probe_urlNohttp monitors only: the absolute http/https URL to probe. Required when monitor_type='http'. The host is resolved at write time and rejected if it resolves only to private/link-local addresses.
ci_providerNoBind this monitor to a CI system, so the CI system itself reports every run by webhook and the job needs NO ping code at all. One of: 'github', 'gitlab', 'jenkins'. SET-ONCE: ci_provider can only be chosen when the monitor is created — update_monitor cannot change or remove it, so a monitor bound to the wrong provider must be deleted and recreated. Setting it generates a webhook secret that is returned exactly ONCE, in THIS call's response, together with the webhook URL. It is never retrievable afterwards — no MCP tool and no API read returns it again — so copy both out of the response and configure the CI webhook before doing anything else. Omit for a monitor that pings for itself. Also set ci_workflow and ci_branch unless the repository really has exactly one workflow on one branch.
ci_workflowNoCI filter: only count runs of the workflow / pipeline / job with this exact name. Requires ci_provider. WITHOUT IT, EVERY workflow in the repository reports to this monitor — so one unrelated failing workflow opens an incident against a job that is perfectly healthy, and a green run of a different workflow clears an incident the real job never recovered from. Set it whenever the repository has more than one workflow.
monitor_fromNoDORMANT UNTIL: an RFC 3339 timestamp before which no deadline is computed and no incident can open — the monitor is fully configured but not yet armed. Use it when you provision ahead of the work: a monitor for a job that does not start running until next Monday is otherwise 'late' from the moment you create it, which is a false alert on day one. The first-run deadline is seeded as monitor_from + grace_s. Default: unset, meaning deadlines start immediately. Example: '2026-01-01T00:00:00Z'. On an upsert (existing slug), omitting this clears the monitor's monitor_from and arms it immediately — pass the current value to keep it.
monitor_typeNo'heartbeat' (default), 'ci', or 'http'.
probe_methodNohttp monitors only: the HTTP method the probe sends. One of 'GET', 'HEAD', 'POST'. Default 'GET'. Use 'HEAD' for a cheap liveness check when the body does not matter — but note it returns no body, so probe_expected_body cannot match anything.
max_runtime_sNoMaximum seconds a single run may take before it is reported overdue (the 'overrun' rule), measured from the run's start ping. Omit to fall back to grace_s. This is how a long job avoids being flagged overdue while still being detected quickly if it goes silent: e.g. grace_s=600 with max_runtime_s=14400 alerts 10 minutes after a missed ping but tolerates a 4-hour run. It replaces grace_s for the overrun deadline ONLY — the silence rule and the first-run deadline still use grace_s. Range 60-31536000. Not supported on http monitors: a probe has no start/success pair, so the overrun rule can never fire and the API returns 400 MAX_RUNTIME_NOT_SUPPORTED (use probe_timeout_s to bound a single probe). On an upsert (existing slug), omitting this clears the monitor's max_runtime_s — pass the current value to keep it.
schedule_kindNo'simple' (requires period_s), 'cron' (requires cron_expr), or 'on_demand' (requires neither). Required for heartbeat/ci monitors. 'on_demand' means no cadence at all: no period_s, no cron_expr — the API returns 400 if either is supplied — and, by default, NO ABSENCE DEADLINES ARE ARMED BETWEEN RUNS. What this trades away: nothing tells you if the agent is never invoked again; silence between runs is invisible unless you opt in to expect_every_s. What it buys: a healthy agent that nobody happens to invoke for a week never generates a false 'late' or 'down' for simply not having been asked to run. Only run-scoped detection still applies once a run starts — max_runtime_s (overrun), step_timeout_s (stall), blocked_timeout_s (stuck on a human) — because those are anchored to a run's own start ping, not to a cadence. IMPORTANT: if you would be alarmed to find this agent silent for hours, set expect_every_s as well — it is the silence floor, and it is the only thing that makes an on_demand monitor detect absence at all. Choose 'simple'/'cron' when the agent is supposed to run on a cadence; choose 'on_demand' when invocation is inherently irregular and a quiet stretch between runs is expected, not a symptom.
expect_every_sNoSILENCE FLOOR in seconds: open a 'silence' incident if NO ping of any kind — success, start, fail, step — has arrived within this window, regardless of the schedule. It is anchored on the monitor's last activity, not on a cadence, which is what makes it the ONLY absence rule an 'on_demand' monitor can have: that schedule_kind arms nothing between runs, so without this field an on_demand monitor reads 'up' forever no matter how long the agent stays dark. Set it on any on_demand agent monitor you would be alarmed to find silent — that is what it is for. It does NOT fire mid-run: while a run is in flight (a start ping is outstanding) the floor stands down entirely and the run clock owns detection (max_runtime_s, step_timeout_s), so a legitimate 4-hour run that reports nothing is still not an incident. A 'blocked' ping also pauses it, bounded by blocked_timeout_s. On 'simple'/'cron' monitors it is a backstop rather than the main rule: it joins the existing deadline as whichever is SOONER, so it can tighten detection under a long cadence (a daily cron has a ~25-hour blind window) but can never loosen it. Default: unset, which means no floor and is exactly how every monitor behaved before this field existed. Range 60-31536000. Accepted on every monitor_type and every schedule_kind. On an upsert (existing slug), omitting this clears the monitor's expect_every_s and turns the silence floor back off — pass the current value to keep it.
step_timeout_sNoProgress budget in seconds: how long an armed run may go without reporting a step before a 'stalled' incident opens (the stall rule). The clock is anchored on the LATER of the run's start ping and its most recent step, so a run that wedges before its first step is caught too. Reach for this when 'still running' and 'still making progress' are different things — a long agent loop, a multi-stage pipeline, a migration. max_runtime_s alone tells you nothing until the whole budget expires; step_timeout_s=300 on a 4-hour budget tells you within five minutes, and names the last step that reported. To use it the run must report steps: call get_ping_instructions and use curl_step (POST <ping_url>/step?rid=<run-id>&step=<name>). A monitor with step_timeout_s set whose job never reports a step will open a stalled incident on EVERY run — set the field and instrument the job in the same change. Default: unset, which disables stall detection entirely; a monitor that sets nothing behaves exactly as it did before this field existed. Range 10-86400. Two constraints. (1) It must be strictly LESS than the effective run budget, COALESCE(max_runtime_s, grace_s), or the API returns 400 STEP_TIMEOUT_EXCEEDS_BUDGET — at or above the budget the run overruns first, so the stall rule could never fire. (2) Not supported on http monitors: a probe never arms a run and has no /step endpoint to call, so the API returns 400 STEP_TIMEOUT_NOT_SUPPORTED. A step resets the stall clock ONLY — it never extends max_runtime_s, so an agent that reports progress forever still overruns. On an upsert (existing slug), omitting this clears the monitor's step_timeout_s and turns stall detection back off — pass the current value to keep it.
probe_timeout_sNohttp monitors only: how many seconds a single probe may take before it counts as a failure. Range 1-30, default 10. This is the http equivalent of max_runtime_s, which http monitors reject: it is the only way to say 'answering, but far too slowly to be healthy'.
runaway_ceilingNoPING-RATE CEILING: the maximum number of pings this monitor may receive in a rolling one-hour window. Exceeding it opens a 'runaway' incident. This is the rule that catches a job or agent stuck in a LOOP — the failure every other rule misses, because a looping agent is pinging enthusiastically and therefore reads 'up' the whole time it is burning tokens or money. Set it a little above the monitor's real cadence: a job that runs every 15 minutes sends about 4 pings/hour, so 20 absorbs retries and still catches a loop. It is RATE-based, so failure_threshold does not gate it and neither does any run budget. Default: unset, which disables the runaway rule entirely. On an upsert (existing slug), omitting this clears the monitor's ceiling and turns the runaway rule back off — pass the current value to keep it.
notify_min_run_sNoNOTIFICATION DURATION FLOOR in seconds: a run SHORTER than this does not produce an INFO-CLASS notification (success, started, every-run, note). This exists for exactly one problem: on an agent monitor, one run is one task you asked for, so asking the agent 'what's 2+2' produces a start and a success notification exactly like a 56-minute deploy does. If you have routed success/started/every-run/note to a destination, you WILL be paged for trivial runs unless you set this. IT NEVER SUPPRESSES A FAILURE. down, fail, recovery and blocked are alert-class and are never affected by this field, however short the run — a run that failed in two seconds is exactly what you need to hear about, and this field cannot silence that, structurally, no matter how it is set. It also never suppresses 'started': a run's duration does not exist yet the moment it begins, so started is always reported regardless of this floor. And it never suppresses an event whose duration could not be measured at all (e.g. a bare success with no preceding start ping) — an unknown duration always means 'notify', never 'suppress'. Default: unset, which means no floor and is exactly how every monitor behaved before this field existed. Range 60-31536000. Not supported on http monitors: an http probe has no start/success pair, so its run duration is never measured and the floor could never apply (the API returns 400 NOTIFY_MIN_RUN_NOT_SUPPORTED). On an upsert (existing slug), omitting this clears the monitor's notify_min_run_s and turns the notification duration floor back off — pass the current value to keep it.
probe_interval_sNohttp monitors only: how often to probe, in seconds. Required when monitor_type='http'. Range 30-86400.
blocked_timeout_sNoMaximum seconds a run may sit in the 'blocked' state (an agent reported it is waiting on a human) before a 'blocked' incident opens. UNSET DOES NOT MEAN WAIT FOREVER: omitting this does not disable the timeout, it falls back to the default, which is 24 HOURS — an agent still blocked 24 hours after reporting so, with this field never set, gets a 'blocked' incident regardless. Lower it to be paged sooner when a stuck approval is urgent; raise it for work that legitimately waits on a human for longer than a day. This is distinct from the immediate, non-incident 'blocked' notification a route on the 'blocked' event type delivers the moment the agent reports it (see set_route) — that fires right away; this field governs the separate incident that opens only if the wait outlives the timeout. Accepted on every monitor_type: unlike max_runtime_s/step_timeout_s it has no run-scoped precondition an http monitor could fail, so there is nothing to reject. On an upsert (existing slug), omitting this clears the monitor's blocked_timeout_s and falls back to the 24h default — pass the current value to keep it.
failure_thresholdNoNumber of consecutive failures required before an incident opens. Default 1 (open on the very first failure). This is how you stop a single transient blip from paging someone: set 2-5 on a job that fails occasionally for reasons that resolve themselves, and no incident opens until that many runs in a row have failed. Any success resets the count to zero. It gates the 'fail' cause ONLY — silence (a missed ping), overrun, never_started and runaway are time- or rate-based, so a consecutive count means nothing for them and they are never delayed by it. Range 1-100. On an upsert (existing slug), omitting this resets the monitor's threshold to 1 — pass the current value to keep it.
probe_expected_bodyNohttp monitors only: a substring that MUST appear in the response body for the probe to count as healthy. THIS IS THE DIFFERENCE BETWEEN 'the server answered' AND 'the app works': a broken app that renders an error page still returns 200, passes a status-only check, and leaves the monitor green. Match on something only a healthy response contains, e.g. '"status":"ok"'. Substring match, not a regex, and case-sensitive. Default: empty, meaning the body is not inspected at all.
probe_expected_statusNohttp monitors only: the EXACT HTTP status code that counts as healthy. Default 200; any other code fails the probe. Set it when the healthy answer is not 200 — 204 for a no-content health endpoint, or 301 when what you are checking is that a redirect still exists (pair that with probe_follow_redirects=false, or the probe will follow it and see the destination's status instead).
probe_follow_redirectsNohttp monitors only: whether the probe follows 3xx redirects. Default false. Leaving it false is usually what you want: the redirect itself is then compared against probe_expected_status like any other response, so a site that starts redirecting to a login wall, a parking page or an outage notice is CAUGHT rather than silently followed to a healthy-looking 200. Set true only when the URL you are checking is legitimately a redirect to the thing you actually care about.

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. First observed

TDQS

A4.5/5.0
Behavior5/5

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

Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=true, idempotentHint=true), and the description adds substantial context beyond them: the upsert overwrite semantics, the set-once ci_provider constraint, and the critical disclosure that the CI webhook secret 'is shown exactly once' and is never retrievable afterwards. The described upsert behavior is consistent with both idempotentHint (same slug converges) and destructiveHint (existing config can be overwritten), so there is no contradiction.

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?

Four sentences pack the core verb, the upsert caveat, the three archetype routings, and the one-time-secret warning with zero filler — every sentence earns its place, and the most decision-relevant facts (upsert, type routing, set-once) are front-loaded. It loses a point only because it is a single dense wall of text with no scannable structure; light bolding or bullets would improve it given the breadth it covers.

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

Completeness4/5

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

For a 28-parameter create tool with no output schema and low annotation richness, the description covers the major decision branches an agent needs: which parameters to supply per monitor type, the upsert pathway, and the one-time return of the CI secret. The only notable gap is that it never states the general success return shape (e.g., the new monitor's id), mentioning only the 'updated' note and the secret; since no output schema exists, a sentence on the primary return value would round it out.

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 description coverage is 100%, and every one of the 28 parameters already carries a rich schema-level description, so the baseline is 3. The tool description adds value on top by grouping parameters into the three usage scenarios (schedule_kind clusters, probe_url/probe_interval_s/probe_expected_* clusters, ci_provider/ci_workflow/ci_branch clusters) and by explaining why probe_expected_status/probe_expected_body matter ('a probe with neither only proves something answered'), which the schema states per-parameter but the description synthesizes.

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?

The description opens with a specific verb and resource — 'Create a new LastPing monitor' — and immediately qualifies the scope with the upsert behavior ('or update an existing one if slug matches — returns 'updated' note on upsert'), which distinguishes it from the sibling update_monitor. It then names the three monitor archetypes (heartbeat/ci, http, CI-fed), leaving no ambiguity about what the tool produces.

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

Usage Guidelines4/5

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

The description gives strong when-to-use routing: which parameter groups apply to heartbeat/ci vs http monitors, and the explicit statement that ci_provider 'is the ONLY place it can be set' — a direct exclusion that routes the agent to create_monitor rather than update_monitor for CI binding. It does not, however, explicitly name update_monitor as the alternative for editing a slugless existing monitor's fields, and it says nothing about when to prefer delete_monitor/pause_monitor/resume_monitor, so the when-not guidance is partial.

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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tp322d/lastping-app'

If you have feedback or need assistance with the MCP directory API, please join our Discord server