UptimeLens On-Call
Operate UptimeLens on-call and escalation workflows on the customer's own resources, through the UptimeLens MCP server. This skill turns an alerting question ("who's on call?", "ack that page", "cover my shift") into the correct sequence of MCP tool calls.
When to use this skill
Use it for the operational side of incident alerting:
- Finding who is currently on call (or why nobody is).
- Acknowledging or snoozing an active escalation that is paging someone.
- Covering a shift by overriding an on-call rotation for a time window.
- Inspecting escalation runs (active pages + history) and escalation policies.
For root-cause analysis of an incident (as opposed to managing the page), prefer the read-only triage_incident MCP prompt, or the read tools get_incident, get_root_cause, list_status_changes, and query_metrics. This skill stays on the on-call/escalation layer and links to incident context only when it helps decide who should act.
Prerequisites
- The UptimeLens MCP server is connected to this client. Read tools work on every plan.
- Write actions (
acknowledge_escalation,bulk_acknowledge_escalation,resolve_escalation,snooze_escalation,escalate_escalation,create_on_call_override,update_on_call_override,delete_on_call_override,create_cover_request,accept_cover_request,decline_cover_request) require a read-write API token and a Pro plan or higher. With a read-only token the write tools are not even listed; on the Free plan they returnFeatureNotAvailable. - Some of these carry a second, per-feature gate on top of the plan gate, and they are not all the same one:
create_on_call_override,update_on_call_overrideandaccept_cover_requestneed the on-call override feature. Accepting counts because it produces an active override — the very thing the feature sells. (A pending request created on a paid plan and accepted after a downgrade would otherwise create an override the plan no longer includes; that gap was closed deliberately.)create_cover_requestneeds a different feature — on-call cover requests — so a plan can include one and not the other.delete_on_call_overrideanddecline_cover_requestare deliberately ungated: undoing something must stay possible after a downgrade, otherwise a shift swap you can no longer edit is also one you can no longer cancel. Any of these can returnFeatureNotAvailableeven with a read-write token.
If a write tool is missing or returns FeatureNotAvailable, tell the user which prerequisite is unmet instead of retrying.
Tools
These tools come from the UptimeLens MCP server. Reference them fully qualified as UptimeLens:<tool> — replace UptimeLens with whatever name the connector was given in this client, otherwise the tool may not be found.
Read (discovery and context):
UptimeLens:list_on_call_schedules— schedules; source of thescheduleIdthatwho_is_on_callandcreate_on_call_overrideneed.UptimeLens:who_is_on_call— who is on call for one schedule right now; returnsgapReasonwhen nobody is.UptimeLens:get_on_call_schedule— the upcoming roster for one schedule over the next N days (default 7, max 90): each shift (who, when, rotation vs override), coverage gaps with their reason, and a coverage summary. Use this for future coverage;who_is_on_callis just now.UptimeLens:list_on_call_overrides— the active and upcoming overrides for one schedule; the source of theidthatupdate_on_call_overrideanddelete_on_call_overrideneed. Each entry carries the user (who takes the shift), the requester (requestedBy, set only for a pending cover request — who asked for the cover), window, reason, and state. Only anactiveoverride is editable; apendingentry is a cover request still awaiting the target user's accept, andupdate_on_call_overridewill reject it. Past overrides are not listed.UptimeLens:list_escalation_runs— escalation runs (active pages + history); source of therunIdthatacknowledge_escalation,snooze_escalationandescalate_escalationneed. Progress is 1-based:currentStep(the step the escalation has reached),nextStep(fires next),totalSteps.UptimeLens:get_escalation_run— one run's full state: which step the escalation has reached and which fires next (currentStep/nextStepoftotalSteps), repeat progress, urgency, ack/resolve method (WHY it ended), snooze & ack-timeout deadlines,nextActionAt, triggering monitor/incident.UptimeLens:get_escalation_run_timeline— one run's chronological event log: notifications, delivery outcomes, ack timeouts, skipped targets, repeats, resolution — the richest "what happened / why it escalated" source.UptimeLens:list_escalation_policies— the on-call alerting rules.UptimeLens:get_escalation_policy— one policy's detail: ordered steps numbered 1..N (the numberscurrentStep/nextStepinlist_escalation_runsrefer to), each step's delay, target strategy and targets. Resolve schedule targets viawho_is_on_call, user targets vialist_team_members.UptimeLens:list_team_members— people on the team; source of theuserIdthatcreate_on_call_overrideneeds.
Write (change state — see "Confirm before writing"):
UptimeLens:acknowledge_escalation— stop further paging for one active run. Input:runId.UptimeLens:resolve_escalation— close the page permanently. Input:runId. Unlike acknowledge, a resolved run never re-pages, so use it when the underlying issue is confirmed fixed — not as a way to make a noisy alert stop.UptimeLens:bulk_acknowledge_escalation— acknowledge many active runs at once. Input:runIds(1–50). Partial-success: already-resolved/unknown runs are counted as skipped, not errors. Use afterlist_escalation_runs(state=active)to clear a batch.UptimeLens:snooze_escalation— pause paging for one run for a number of minutes. Input:runId,durationMinutes(1–240).UptimeLens:escalate_escalation— page the next not-yet-paged step now instead of waiting out its timer ("escalate now"). Input:runId. Nothing is skipped: the step shown asnextStepfires; after the last step the next repeat starts immediately, and with no repeat left the run is closed as exhausted (nextStepis 0 — tell the user there is nobody left to page). The run goes back to active and its urgency becomeshigh. Rejected for test runs and finished runs.UptimeLens:create_on_call_override— put a user on call for a schedule during a window. Input:scheduleId,userId,endAt; optionalstartAt(defaults to now),reason. Requires the on-call override feature (see prerequisites).UptimeLens:update_on_call_override— edit an existing override in place: change itsendAtorreason, and (only before it starts) itsuserIdorstartAt. Input:id(fromcreate_on_call_override's result, or discovered vialist_on_call_overrideswhen you didn't just create it) plus the fields to change; omit a field to leave it unchanged. This is how you shorten, extend, or reassign a cover; usedelete_on_call_overridewhen the swap should not happen at all. Requires the on-call override feature.UptimeLens:delete_on_call_override— delete an override outright: the swap is cancelled and the regular rotation applies again. Input:id. Use this rather than editing when the cover should not happen at all.UptimeLens:create_cover_request— ask a teammate to take a window instead of assigning it: creates apendingrequest and emails the target, who must accept before it becomes an active override. Input:scheduleId,userId(who is being asked),startAt,endAt; optionalreason. Usecreate_on_call_overridewhen you mean to assign the shift immediately without asking.UptimeLens:accept_cover_request— accept apendingcover request → it becomes an active override (the target user takes the shift). Input:id(apendingentry fromlist_on_call_overrides). Only the target user or an admin can accept.UptimeLens:decline_cover_request— decline apendingcover request (no override is created). Input:id(apendingentry fromlist_on_call_overrides). Only the target user or an admin can decline.
Core workflow: handle an on-call alert
Most write tools need an ID that only a read tool can give you, so always discover first. Copy this checklist and work through it:
On-call response:
- [ ] 1. Find the active escalation runs (list_escalation_runs, state=active, isTest=false)
- [ ] 2. Pick the run in question (rank by startedAt; check urgency and currentStep/totalSteps)
- [ ] 3. Add context if useful (incidentId → get_incident; triggeringMonitorId → list_status_changes → get_root_cause)
- [ ] 4. Decide: acknowledge (own it, paging stops) or snooze (pause N minutes, paging resumes)
- [ ] 5. Confirm the action with the user, then call the write tool with the run's id
Step 1 — find active runs. Call list_escalation_runs with state="active". Use isTest=false for real, incident-triggered pages; isTest=true are "page-yourself" test runs and should not be treated as live incidents.
Step 2 — pick the run. Each run has an id (this is the runId for write tools), urgency (high/low), currentStep of totalSteps (how far the escalation has climbed — 1-based; higher means more people have been paged; nextStep is who gets paged next), and startedAt. When several are active, rank by startedAt (oldest first) and surface high urgency first.
Step 3 — context (optional). If the run has an incidentId, call get_incident for impact and timeline. If it has a triggeringMonitorId, call list_status_changes with that monitor id to see its recent up/down changes, then get_root_cause with a statusChangeId from that list for per-probe network diagnostics. Use this only to help the user decide; do not start a full investigation here.
Step 4 / 5 — act. Choose acknowledge vs snooze vs escalate (below), confirm, then write.
Acknowledge, resolve, snooze, or escalate
-
Acknowledge (
acknowledge_escalation) means "I own this now" — paging stops while you work. This is the right answer for "take", "I've got it", or "silence" a page. Acknowledging a run that is no longer active returns anEscalationRunAlreadyResolvederror — harmless (it was already acknowledged or resolved); report it as already-handled and do not retry. -
Resolve (
resolve_escalation) means "this is over" — the run is closed permanently and never re-pages. Use it when the user says the underlying issue is fixed, not merely that they are on it. A run also resolves on its own when its incident resolves, so resolving by hand is for the case where the page outlived the problem. Because it cannot be undone, prefer acknowledge when in doubt. -
Snooze (
snooze_escalation) means "quiet it fordurationMinutes, then page again" — a deferral, not ownership. It is not idempotent: each call re-sets the snooze window to now + N minutes, so calling it again extends the silence. Use the smallest duration that fits (1–240), and never snooze instead of acknowledging when the alert actually needs an owner. -
Escalate now (
escalate_escalation) means "this needs more people, now" — the run'snextStepis paged immediately instead of after its wait, urgency becomeshigh(quiet hours no longer apply), and an acknowledged run becomes active again. Use it when the user says the current responder cannot handle it or nobody is responding; it is the opposite of snooze, so never call both on the same run in one turn. Tell the user which step will be paged (nextStepfromget_escalation_run).
Acknowledging the wrong run silences a real page and no one is alerted, so confirm the runId matches the alert the user means.
Coverage gaps
who_is_on_call returns a gapReason when nobody is on call:
schedule_disabled— the schedule is turned off; the policy is relying on other targets.no_active_rotations/no_rotation_members— the schedule has no one assigned to page right now.outside_active_window— it is outside this schedule's active hours.
When there is a gap and someone needs to take the page, create_on_call_override puts a specific user on call for a window. Discover scheduleId via list_on_call_schedules and userId via list_team_members (team members expose no email or phone — match by name/role).
who_is_on_call only reports the gap happening now. To find gaps before they page anyone, call get_on_call_schedule for the schedule — its gaps array lists every uncovered window over the next N days with the same reasons, and coveragePercent summarizes how well the period is covered. This is the proactive companion to who_is_on_call.
Confirm before writing
Read and triage freely. For the write tools, state what you are about to do and get the user's go-ahead first — these change who gets paged:
- Acknowledge / snooze: name the run (urgency, what triggered it) and, for snooze, the minutes.
- Resolve: say plainly that the page is being closed for good and will not re-page. Ask whether the underlying issue is actually fixed — "make it stop" is a request for acknowledge or snooze, not resolve.
- Override: name the schedule, the user, and the exact window (
startAt–endAt, UTC RFC3339). If the window crosses midnight,endAt's date is the following day;endAtmust be afterstartAt. - Delete override / decline cover request: name whose shift goes back to the regular rotation. Cancelling a cover changes who gets paged just as much as creating one does.
Most of these are reversible — an override can be edited or shortened, an ack or snooze re-escalates — so the goal is a clear human decision, not a permission wall. Two are not: resolve_escalation closes a page permanently, and delete_on_call_override removes the swap rather than editing it. Prefer the least-surprising action and never batch-acknowledge multiple runs without explicit per-run confirmation.
Common scenarios
"Who's on call for <team/schedule>?"
list_on_call_schedules → match the schedule by name → who_is_on_call(scheduleId). If gapReason is set, explain it and offer an override.
"Who's on call this week / show the upcoming roster (and any coverage gaps)?"
list_on_call_schedules → pick the schedule by name → get_on_call_schedule(scheduleId) (defaults to the next 7 days; pass days up to 90 for a longer view). Summarize the shifts (who and when), then call out any gaps with their reason and the coveragePercent, and offer an override for an uncovered window. Use this instead of who_is_on_call whenever the question is about the upcoming period rather than the current moment.
"Acknowledge the database alert."
list_escalation_runs(state=active, isTest=false) → identify the run (use triggeringMonitorId/incidentId to match "database") → confirm → acknowledge_escalation(runId).
"Snooze that page for 30 minutes."
Find the active run as above → confirm → snooze_escalation(runId, durationMinutes=30). Remind the user it will page again after the window.
"Nobody is answering — escalate this now."
Find the active run as above → get_escalation_run(runId) to name the step that will be paged (nextStep) → confirm → escalate_escalation(runId). Report that the step is being paged and that the run is now high urgency.
"Cover Sam's shift tonight, 18:00–06:00."
list_on_call_schedules → pick the schedule (note its timezone) → list_team_members → find the covering user's userId → convert the user's local window to UTC → confirm the UTC window → create_on_call_override(scheduleId, userId, startAt="2026-06-14T18:00:00Z", endAt="2026-06-15T06:00:00Z", reason="cover for Sam"). The window crosses midnight, so endAt is the next calendar day — endAt must be after startAt or the call is rejected.
"Ask Dana if she can take my shift on Friday night."
The user wants to ask, not assign, so use the request flow: list_on_call_schedules → pick the schedule (note its timezone) → list_team_members → find Dana's userId → convert the window to UTC → confirm → create_cover_request(scheduleId, userId, startAt, endAt, reason). This creates a pending request and emails Dana; nothing changes on the rotation until she accepts. Tell the user that — a request that is never accepted leaves the original person on call. Use create_on_call_override only when they mean "put Dana on call", not "ask Dana".
"Cancel that cover — I'll keep the shift after all."
list_on_call_overrides(scheduleId) → find the entry → confirm → delete_on_call_override(id) for an active override (the regular rotation applies again), or decline_cover_request(id) for one still pending. Deleting is the right call when the swap should not happen at all; shortening it with update_on_call_override is for when it should happen, differently.
"The database issue is fixed — close that page."
Find the run (list_escalation_runs, state=active or acknowledged) → check with the user that the issue is fixed, not just noisy → resolve_escalation(runId). Say that it will not page again. If they only want quiet while they work, acknowledge or snooze instead.
"Actually, extend that cover until 08:00."
You already created the override, so edit it in place instead of making a new one: update_on_call_override(id, endAt="2026-06-15T08:00:00Z") — pass only the field you are changing. Confirm the new UTC window back to the user.
"Extend the override on the database schedule to 08:00." (you didn't create it this session)
You don't have the override's id in context, so discover it first: list_on_call_schedules → match the schedule → list_on_call_overrides(scheduleId) → pick the active override by its user/window (a pending entry is an unaccepted cover request and can't be edited) → update_on_call_override(id, endAt="…Z"). list_on_call_overrides is the only way to get an override id you didn't just create; never guess an id. The parameter is named id.
"Accept the pending cover request on the database schedule."
list_on_call_schedules → match the schedule → list_on_call_overrides(scheduleId) → find the pending entry (a cover request awaiting accept; its userId is who would take the shift and requestedBy is who asked — use them to pick the right one when several are pending) → confirm with the user → accept_cover_request(id). Only the target user or an admin can accept; otherwise the tool returns a permission error. To reject it instead, use decline_cover_request(id). (Accepting turns the pending request into an active override — it changes who gets paged, so confirm first.)
"Anything paging right now?"
list_escalation_runs(state=active, isTest=false) → summarize by urgency and age (startedAt), highest urgency and oldest first; offer to acknowledge or snooze each.
Notes
- All timestamps are UTC RFC3339 (e.g.
2026-06-14T18:00:00Z). Schedules carry their own IANAtimezone; users usually mean schedule-local time, so convert to UTC before an override and confirm the UTC window back to them. - Paginated list tools (
list_on_call_schedules,list_escalation_runs,list_team_members) return at most 100 items withtotalandhasMore; page withoffsetwhenhasMoreis true rather than assuming the first page is everything. A few naturally-bounded lists (e.g.list_on_call_overrides— one schedule's active+upcoming overrides) return the full set without paging. - Every tool is scoped to the token owner's account; you cannot see or change another customer's on-call setup.