← Back to all apps
i

incident.io

Codeby incident.io
Launched Oct 5, 2026 on ChatGPTLaunched Apr 4, 2026 on Claude

Manage your full incident.io workspace from one place. Declare and triage incidents, ack pages, check who's on call, and track follow-ups - without switching tools. Analyze incident trends, escalation response rates, and alert noise across your organization. Browse your catalog, query telemetry from connected observability tools, and run structured operational reviews. Everything your team needs to stay on top of things, without the tab juggling.

108ChatGPT Tools
35Claude Tools
incident.ioDeveloper
CodeCategory

Use Cases

code

Available Tools

Action Create

action_create
Full Description

Create an action on an incident.

Actions are remediation tasks captured during an incident to help resolve it now — restarting a service, rolling back a deploy, investigating a spike. Only capture work that is part of resolving the incident.

Actions are deliberately distinct from follow-ups. Work to be tracked for after the incident is resolved — fixing a runbook, adding monitoring, a postmortem task — is a follow-up, not an action: use follow_up_create for that. Someone saying the word "action" does not on its own make it one.

The action is created with status "outstanding". An action with the same description already open on the incident is rejected rather than duplicated.

Streams are a special case: a closed stream can still have its existing actions managed, but no new ones created, because a stream has no follow-up flow to move the work into.

Returns the created action.

Parameters (2 required, 1 optional)
Required
descriptionstring

single sentence describing the remediation work, e.g. 'roll back the payments deploy'

incident_idstring

incident to create the action on (ID, external ID, or reference like INC-123)

Optional
assignee_idstring

user ID to assign the action to (use user_list to find IDs) — must be a participant in the incident

Action Delete

action_delete
Full Description

Delete an incident action.

Use this when an action was captured by mistake, or is no longer wanted. Use action_update to mark work that was considered and rejected as "not_doing" instead — that keeps the decision visible on the incident, where deleting hides it.

Deleting is separate from updating because it is a different operation: it archives the action, so it stops appearing in action_list and can no longer be edited. It cannot be undone through these tools.

This does not convert the action into a follow-up. To carry work forward past the incident, create a follow-up with follow_up_create and then delete the action.

Returns the deleted action.

Parameters (1 required)
Required
idstring

action ID to delete

Action List

action_list
Full Description

List incident actions with optional filters and pagination.

Actions are remediation tasks captured during an incident to help resolve it now — restarting a service, rolling back a deploy, investigating a spike. They are distinct from follow-ups, which track the work that happens after an incident is resolved: use follow_up_list for those.

Each result includes: description, status, assignee, creator, the parent incident, and timestamps.

Filters (all optional):

  • incident_id: filter to a specific incident (accepts ID, external ID, or reference like INC-123)
  • assignee_id: filter by assignee user ID (use your own ID from config://organisation to find "my actions")
  • status: one or more of outstanding, completed, not_doing
  • created_after / created_before: date range for when the action was created (yyyy-mm-dd or RFC 3339)

Deleted actions, and actions that have been converted into follow-ups, are never returned.

Pagination: results are ordered oldest first. Use page_size (default 10, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results. "total_count" is how many actions match the filters altogether, so use it for counts rather than counting one page.

Use action_create to capture new remediation work, and action_update to reassign one or mark it done.

Parameters (0 required, 7 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

assignee_idstring

filter by assignee user ID

created_afterstring

only actions created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only actions created before this date (yyyy-mm-dd or RFC 3339)

incident_idstring

filter to a specific incident (ID, external ID, or reference like INC-123)

page_sizeinteger

results per page (default 10, max 50)

statusarray

filter by status: outstanding, completed, not_doing

Action Update

action_update
Full Description

Update an existing incident action. Only the fields you provide will be changed — omitted fields are left as-is.

Use action_list to find action IDs. Use action_create to capture new remediation work.

Updatable fields:

  • description: reword the action
  • assignee_id: assign to a user (empty string unassigns). The assignee must be a participant in the incident.
  • status: change to outstanding, completed, or not_doing

Actions cannot be deleted through this tool: "deleted" is not an accepted status, because deleting archives the action and needs a different permission. Use action_delete for that. Prefer status "not_doing" when the work was considered and rejected, which keeps the decision visible where deleting hides it. An action cannot be converted into a follow-up here either — create the follow-up with follow_up_create instead.

An action that has already been deleted, or converted into a follow-up, can no longer be edited.

Returns the updated action.

Parameters (1 required, 3 optional)
Required
idstring

action ID to update

Optional
assignee_idstring

user ID to assign (pass empty string to unassign)

descriptionstring

new description

statusstring

new status: outstanding, completed, or not_doing

Alert Attach

alert_attach
Full Description

Attach an existing alert to an incident, marking it as related.

Use this when alerts should be recorded against an incident that already exists — for example after finding firings with alert_list. The alert is not moved or deleted; it is linked to the incident as related.

Use alert_list or alert_show to find an alert's ID, then pass the alert_id and incident_id here. The incident_id accepts a ULID, numeric external ID, or reference like INC-123. If the alert is already related to the incident, this is a no-op and still returns success.

If someone previously marked this alert unrelated to this incident, the call is refused with an "explicitly_unrelated" error rather than quietly undoing their decision. Tell the user it was explicitly unrelated and ask whether to override; if they confirm, retry with re_relate set to true, which relates it again and returns status "re_related". Don't set re_relate on a first attempt.

To declare a new incident for alerts rather than attach to an existing one, use alert_create_incident.

Parameters (2 required, 1 optional)
Required
alert_idstring

alert ID (ULID)

incident_idstring

incident to attach to (ID, external ID, or reference like INC-123)

Optional
re_relateboolean

set true to re-relate an alert someone previously marked unrelated to this incident. Only set it once the user has asked you to override that.

Alert Create Incident

alert_create_incident
Full Description

Declare a new incident for one or more alerts, attaching them to it as related.

Use this when firing alerts warrant an incident and none exists yet. It creates the incident and relates every alert in one atomic step, so you never end up with an incident that is missing the alerts that justified it.

Prefer this over incident_create followed by alert_attach: this links the incident to its originating alert and rolls the whole thing back if attaching fails.

Before declaring, check for an existing open incident for the same problem (incident_list with status_category triage/active/paused). If one exists, use alert_attach instead of declaring a duplicate.

Required: alert_ids (at least one) and name.

Alerts that belong to an alert group are rejected, with an "alert_ids" validation error naming them and nothing created. Alert groups are attached as a unit, which this tool can't do — tell the user to attach the group from the dashboard, or to ungroup those alerts first, then retry with the rest.

Everything else behaves exactly as incident_create: the incident starts in triage unless you give both severity_id and an active incident_status_id, never invent a severity the user hasn't stated, and organisations that require custom fields at declare time return a "missing_required_fields" validation error naming what is missing. Read config://organisation for severity, status, type, custom field and role IDs.

Private alerts can only go on a private incident — pass visibility "private" for those, or the call is rejected.

A retry of the same request attaches the alerts to the incident it already created, with already_existed set — say it was already declared rather than claiming you declared it.

Returns the incident and the alerts attached to it. Use incident_show for full details.

Parameters (2 required, 9 optional)
Required
alert_idsarray

alert IDs (ULIDs) to declare the incident for, up to 50

namestring

short, descriptive incident name (e.g. 'Database connection pool exhausted')

Optional
custom_field_entriesarray

custom field values to set on the new incident

incident_status_idstring

status ID to start in (see config://organisation). Defaults to triage. If you set an active status, severity_id is required.

incident_type_idstring

incident type ID (see config://organisation). Defaults to the organisation's default type.

role_assignmentsarray

role assignments for the new incident (see config://organisation for role IDs)

severity_idstring

severity ID (see config://organisation), or the catalog entry ID for a severity. If omitted, the incident starts in triage with no severity.

slack_team_idstring

Slack workspace (team) ID to create the incident channel in, e.g. T012AB3CD4. Only relevant for Slack Enterprise Grid organisations with multiple workspaces. Omit otherwise.

summarystring

initial summary describing what is happening (markdown)

users_to_invitearray

user IDs to invite to the incident channel (see user_list). Ignored for private incidents.

visibilitystring

public (default, visible to all) or private (restricted access). Private alerts require a private incident.

Alert Detach

alert_detach
Full Description

Detach an alert from an incident, marking it as unrelated.

Use this when an alert was routed to the wrong incident and needs to be removed. The alert is not deleted — it is marked as unrelated to this incident.

Use alert_show to find an alert's ID and its linked incidents, then pass the alert_id and incident_id here. The incident_id accepts a ULID, numeric external ID, or reference like INC-123.

Parameters (2 required)
Required
alert_idstring

alert ID (ULID)

incident_idstring

incident to detach from (ID, external ID, or reference like INC-123)

Alert List

alert_list
Full Description

List alerts with optional filters and pagination. Use alert_show for full details on a specific alert.

Each result includes: title, status, alert source (with type), priority, deduplication key, and links.

Use 'include' to request additional fields on each result:

  • tags: names of tags applied to the alert

Filters (all optional):

  • query: search alert titles and descriptions
  • status: one or more of firing, resolved
  • alert_source: one or more alert source config IDs (use alert_source_list to discover these)
  • priority: one or more priority IDs (see config://organisation resource for IDs)
  • deduplication_key: exact match on a deduplication key
  • attributes: filter by alert attribute values (object mapping attribute ID to array of values, see config://organisation for attribute IDs)
  • tag: one or more alert tag names, matched case-insensitively (use alert_tag_list to discover them); returns alerts carrying any of them. Archived tags are ignored.
  • created_after / created_before: dates to bound the time range (yyyy-mm-dd or RFC 3339)
  • has_related_incident: true for alerts attached to an incident, false for unattached

By default, results are limited to alerts created in the last 30 days. Set created_after to look further back, but prefer a narrow time range alongside other filters — wide ranges on large orgs are slower and more likely to time out.

By default, alerts caught by maintenance windows are excluded from results.

Pagination: results are ordered newest first. Use page_size (default 15, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Tip: if you need counts, trends, or noise analysis, use alert_stats first — it's much more efficient than paginating through alert_list. Use alert_list when you need to browse specific alerts or inspect their details.

Understanding alert attributes: alerts carry structured attributes (e.g. team, service, environment, feature) that describe what they relate to. Read config://organisation to see what attributes are configured, then use the attributes filter to slice alerts by these dimensions. For example, filtering by service helps answer "which alerts fire for the payments service?" or by team for "what's the alert load for the platform team?"

Parameters (0 required, 13 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

alert_sourcearray

filter by alert source config IDs

attributesobject

filter by alert attribute values: keys are attribute IDs, values are arrays of accepted values

created_afterstring

only alerts created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only alerts created before this date (yyyy-mm-dd or RFC 3339)

deduplication_keystring

exact match on deduplication key

has_related_incidentboolean

if true, only alerts attached to an incident; if false, only unattached alerts

includearray

optional fields to enrich each result with: tags

page_sizeinteger

results per page (default 15, max 50)

priorityarray

filter by priority IDs

querystring

search alert titles and descriptions

statusarray

filter by status: firing, resolved

tagarray

filter to alerts carrying any of these alert tag names (case-insensitive). Archived tags are ignored.

Alert Note List

alert_note_list
Full Description

List notes attached to an alert.

Notes capture context, decisions, and investigation findings against an alert without needing to declare an incident. Each result includes the markdown content, author, and timestamps. Notes the caller cannot see (e.g. due to private-alert access control) are not returned.

Content is returned as Markdown. Supported formatting includes headings, bold/italic/strikethrough, inline and fenced code, lists, blockquotes, links, GitHub-flavoured tables, and horizontal rules. Raw HTML, image syntax, task lists, and footnotes are not rendered.

Pagination: results are ordered oldest first. Use page_size (default 10, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Pass "id" to fetch a single note instead of the page.

Use alert_note_manage to write, edit or remove a note.

Parameters (1 required, 3 optional)
Required
alert_idstring

alert ID (ULID) to list notes for

Optional
afterstring

cursor from a previous page to fetch the next one

idstring

a single note's ID (ULID): returns just that note, and nothing if it is not on this alert

page_sizeinteger

results per page (default 10, max 50)

Alert Note Manage

alert_note_manage
Full Description

Write, edit or remove a note on an alert.

Notes capture context, decisions and investigation findings against an alert without declaring an incident.

Actions:

  • create: add a note to an alert. Takes alert_id and content.
  • update: replace a note's content. Takes id and content.
  • delete: remove a note. Takes id.

Content is Markdown. Headings, bold/italic/strikethrough, inline and fenced code, lists, blockquotes, links, GitHub-flavoured tables and horizontal rules all render. Raw HTML, images, task lists and footnotes are stripped or rendered as plain text.

Only a note's author can edit or delete it. Read notes with alert_note_list.

Parameters (1 required, 3 optional)
Required
actionstring

one of: create (takes alert_id and content), update (takes id and content), delete (takes id)

Optional
alert_idstring

for create: the alert to attach the note to (ULID)

contentstring

for create and update: the note's Markdown body. On update it replaces the current content

idstring

for update and delete: the note's ID (ULID), from alert_note_list

Alert Resolve

alert_resolve
Full Description

Resolve one or more firing alerts, marking them resolved now and recording who did it.

Use this to close the loop after triage — for example once you've confirmed a firing alert is noise, or the underlying problem is fixed. Use alert_list or alert_show to find alert IDs first.

Pass several alert_ids in one call rather than calling once per alert: a batch takes one row lock pass and notifies responders once, where repeated single calls are slower and noisier. Up to 50 per call.

Resolving is idempotent — an alert that is already resolved comes back as already_resolved, not an error.

Not every alert can be resolved here. Some sources own resolution themselves. For a few (PagerDuty, Opsgenie, BigPanda, Jira, and Wiz when configured for write-back or local resolution) resolving here works as normal. For the rest (ServiceNow, Zendesk, GitHub issues, and Wiz when configured as the source of truth) the alert clears only when that system closes the underlying ticket: those come back as externally_resolved, naming the source. Tell the user to close it there rather than retrying.

The response reports every alert you asked about with its own outcome:

  • resolved: was firing, now resolved
  • already_resolved: was resolved before this call, nothing changed
  • externally_resolved: the alert's source resolves its own alerts, so it is still firing
  • no_permission: you lack the alerts.resolve permission for that alert's team
  • not_found: no alert with that ID, or you cannot see it
  • not_resolved: still firing for some other reason (the message says more)

Read "resolved" for how many actually changed, and report the exceptions rather than claiming everything was resolved.

To resolve the page an alert raised rather than the alert itself, use escalation_respond. Alerts and escalations are separate: resolving an alert does not acknowledge its page.

Parameters (1 required)
Required
alert_idsarray

alert IDs (ULIDs) to resolve, up to 50 per call

Alert Show

alert_show
Full Description

Look up an alert by ID and return its details.

Returns: title, description, status, deduplication key, alert source (with type), priority, tags, links (source, dashboard, silence), and any linked incidents.

Use 'include' to request additional sections:

  • payload: the raw JSON payload from the alert source (only available for firing alerts)

The response includes linked incident IDs. Pass these to incident_show with include: ["investigation"] to see the full investigation for each linked incident.

Parameters (1 required, 1 optional)
Required
idstring

alert ID (ULID)

Optional
includearray

optional sections to include: payload

Alert Source List

alert_source_list
Full Description

List configured alert sources for this organisation.

Returns the ID, name, and source type (e.g. datadog, sentry, grafana, http) for each alert source. Use alert source IDs to filter alert_list results by source.

This is not paginated — alert source lists are typically small.

Parameters (0 required, 1 optional)
Optional
querystring

search alert source names

Alert Stats

alert_stats
Full Description

Count alerts grouped by one or more dimensions, returning aggregate statistics.

Use this tool instead of paginating through alert_list when you need counts, breakdowns, or trend data across many alerts — for example "how many alerts by source this week?" or "what proportion of alerts result in incidents?"

Dimensions (combine freely in the group_by array):

  • status: group by status (firing, resolved)
  • priority: group by alert priority (e.g. Critical, Urgent, In-hours)
  • source: group by alert source name (e.g. Sentry, Grafana, Datadog)
  • has_incident: group by whether the alert is attached to an incident (true/false)
  • team: group by the org's configured team. Resolves the team alert attribute, so its counts agree with filtering alerts by team. Multi-value: alerts tagged with several teams are counted under each; untagged alerts show as "None".
  • tag: group by alert tags. Multi-value: alerts carrying several tags are counted under each; untagged alerts show as "None". Archived tags are ignored, so an alert whose only tags are archived is counted under "None".

Scoping to a team: use the team filter for exact teams, or team_part_of to include a parent team and all its sub-teams in the hierarchy (e.g. a "Go To Market" parent covering Sales, Marketing, etc.). Combine team_part_of with group_by ["team"] to break a parent down into its sub-teams. Scoping to tags: use the tag filter with alert tag names to include alerts carrying any of those tags.

  • attribute:<attribute_id>: group by any alert attribute's value (e.g. team, service, environment). Read config://organisation to find attribute IDs. Array attributes are flattened so each value is counted individually; catalog-typed attributes are resolved to names.
  • week: group by ISO week (e.g. 2026-W03)
  • month: group by calendar month (e.g. 2026-01)
  • quarter: group by calendar quarter (e.g. 2026-Q1)

Each group includes a count, a workload breakdown (responder time from linked incidents, split by working hours, late evening, and overnight), and sample alert IDs that you can pass to alert_show for detail. This lets you answer "which alert sources generate the most on-call work?" directly.

Note on workload scope: workload is summed from all incidents linked to the alerts in each group, regardless of when those incidents were created. This means an alert created in December linked to an incident from November will include November's workload. This is intentional — it measures the total impact generated by the alert — but means alert workload totals may differ from incident_stats workload for the same date range.

By default, alerts caught by maintenance windows are excluded.

The tool processes at most 25,000 alerts. If more match, the response sets "truncated": true — narrow the date range for accurate results.

Conversion rate: to calculate what proportion of alerts become incidents, group by ["source", "has_incident"]. For each source, conversion rate = count(has_incident=true) / total count. Sources with low conversion rates are noise candidates.

Cross-reference: use incident_stats(group_by: ["alert_source"]) to see how alert sources map to incident volume and workload over time. This traces the full path from alert noise through to responder cost. Note that alert counts will be higher than incident counts for the same source, since multiple alerts can link to the same incident.

Deeper analysis: many organisations have a small number of alert sources (e.g. one Datadog integration) but rich alert attributes (team, service, environment, feature). Group by attribute:<attribute_id> to break volume, conversion and workload down by these — for example group_by ["attribute:<service_id>", "has_incident"] to find the noisiest services, or group_by ["team"] for per-team alert load. Read config://organisation to discover attribute IDs. Use alert_list when you need to browse the individual alerts behind a number.

Structured analysis: for a comprehensive report with playbooks, themes, and recommendations, call analysis_start first — it provides step-by-step methodology and a branded report template. Use this tool directly only for quick, focused queries.

Parameters (0 required, 12 optional)
Optional
alert_sourcearray

filter by alert source config IDs

created_afterstring

only alerts created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only alerts created before this date (yyyy-mm-dd or RFC 3339)

group_byarray

dimensions to group by. Categorical: status (firing/resolved), priority, source. Multi-value: team (the org's configured team alert attribute), tag. Attribute: attribute:<attribute_id> for any alert attribute (e.g. team, service, environment). Time buckets: week, month, quarter. Boolean: has_incident (whether alert is attached to an incident). If empty, returns a single total count.

max_alert_ids_per_groupinteger

how many alert IDs to return per group (default 10, max 250). Set to 0 to omit IDs entirely.

max_groupsinteger

limit the number of groups returned (default 250). Check total_groups in the response to see how many existed before truncation.

priorityarray

filter by priority IDs

sort_groups_bystring

order groups by: alphabetical (the default — by dimension key, so week/month/quarter come back chronological), count (highest first), or workload (highest total responder-minutes first). max_groups keeps the first N groups in the current order, so to get a true top-N (e.g. noisiest sources) pass count or workload — otherwise you get an alphabetical slice that can omit the largest groups.

statusarray

filter by status: firing, resolved

tagarray

filter to alerts carrying any of these alert tag names (case-insensitive). Archived tags are ignored.

teamarray

filter to alerts tagged with these team IDs (exact match), resolved against the org's team alert attribute. Mutually exclusive with team_part_of. Use team_list to discover team IDs.

team_part_ofarray

filter to alerts tagged with these team IDs including all sub-teams in the hierarchy. Use this to scope to a parent team and everything beneath it. Mutually exclusive with team.

Alert Tag Apply

alert_tag_apply
Full Description

Add, remove, or replace tags on up to 50 alerts.

Use alert_list or alert_show to find alert IDs. Tags must already exist; this tool never creates them.

Choose operation add to keep existing tags and add these, remove to keep all tags except these, or set to replace the complete tag set. An empty set clears every tag.

References are validated before any alert changes. If any alert or tag is unknown, the whole call fails with alerts_not_found or tags_not_found and nothing is changed. Otherwise each alert reports updated, too_many_tags, or no_permission.

Parameters (3 required)
Required
alert_idsarray

alert IDs (ULIDs) to update, up to 50 per call

operationstring

how to change the tags: add, remove, or set

tagsarray

existing unarchived tag names; set accepts an empty list to clear all tags

Alert Tag List

alert_tag_list
Full Description

List the organisation's active alert-tag vocabulary.

Alert tags are names responders apply to alerts after they arrive (for example "noisy" or "known issue"). This tool returns the live vocabulary — archived tags are excluded. Each result is an id and name only; it does not include how often a tag is used.

Use this to discover tag IDs and names. Pass a query to filter by name substring.

Pagination: results are ordered by name, case-insensitively. Use page_size (default 25, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Parameters (0 required, 3 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

page_sizeinteger

results per page (default 25, max 50)

querystring

search tag names (case-insensitive substring match)

Analysis Start

analysis_start
Full Description

Start an operational analysis session. Returns a download URL for a tar.gz archive containing everything needed to run analysis: playbooks with step-by-step methodology, your organisation's configuration (severity IDs, custom fields, roles), reference materials, and a branded HTML report template.

Download and extract the archive, then follow the playbook steps using the MCP data tools (incident_stats, alert_stats, escalation_stats, etc.).

Parameters (0 required, 1 optional)
Optional
playbookstring

optional,which analysis playbook to follow: operational-review, alert-noise, on-call-burden, team-health, response-effectiveness. If omitted, includes the index and all playbooks so you can pick the right one.

Ask

ask
Full Description

Ask the incident.io AI agent a question about your organisation's incidents, on-call schedules, alert routes, and operational setup.

Use this tool for conversational questions that need reasoning, entity resolution, or multi-step investigation — for example "what happened on my last on-call shift?", "summarise recent incidents for the payments team", or "who is on call for the backend service?". The agent can query schedules (including past shifts and overrides), search incidents, look up catalog data, and manage schedule overrides.

Pass incident_id to focus the agent on that incident, with its full investigation data and management tools: it can update the incident, create follow-ups, escalate, and draft status updates — for example "what caused this incident?" or "draft a status update for stakeholders". It may act on the incident to satisfy the request, so for a purely-read question prefer incident_show with include: ["investigation", "postmortem"].

For structured data needs (counts, filtering, pagination), prefer the direct tools: incident_stats for analytics, incident_list for browsing, incident_show for details. The ask tool adds latency and cost from the inner LLM call, so only use it when you need the agent's reasoning.

Pass session_id from a previous response to continue a multi-turn conversation.

Parameters (1 required, 4 optional)
Required
questionstring

the question to ask the agent

Optional
allow_code_sessionboolean

let the agent read source code by cloning the repository server-side; only set this if you have no local checkout to answer code questions from yourself

datasource_idsarray

restrict telemetry queries to specific datasource IDs; when omitted all enabled datasources are queried

incident_idstring

scope the conversation to a specific incident (ID, external ID, or reference e.g. INC-123)

session_idstring

resume a previous conversation by passing the session_id from a prior response

Ask Telemetry

ask_telemetry
Full Description

Ask the telemetry-focused AI agent a question, or run a native query verbatim. This agent queries logs, metrics, traces, and dashboards across your connected observability platforms (Datadog, Grafana, Splunk, Honeycomb, etc.). Read the telemetry://datasources resource to see which platforms are connected.

There are two modes:

1. Natural language (default): set "question" and let the agent plan and translate the query. Use this to correlate incident data with observability signals — for example "what do the error rates look like for the payments service?", "show me the logs around the time of INC-123", or "query the CPU dashboard for the last hour".

2. Passthrough (verbatim): set "passthrough" with a complete native expression, its query_type (log_query | metric_query | span_query | sql_query), and the datasource_id to run it against. The expression is the datasource's native query language for log/metric/span (LogQL, PromQL, TraceQL) or a SQL statement for sql_query, and runs exactly as written — the planner is bypassed, nothing reshapes it. Use this when you already hold the precise query (e.g. you authored it from the code, a runbook, or the user). "question" is optional in this mode; when supplied it becomes the recorded query's purpose and steers any follow-up analysis. If you're unsure whether the labels, fields or metric names a verbatim expression references exist on the datasource, call telemetry_inspect on the same datasource_id to confirm them first — a typo fails the whole query. You only need it when you lack prior proof the vocabulary is sound: earlier results this session that already surfaced those labels and metrics, or an expression the user handed you verbatim, are proof enough.

Pass session_id from a previous response to continue a multi-turn conversation.

Parameters (0 required, 5 optional)
Optional
datasource_idsarray

restrict telemetry queries to specific datasource IDs; when omitted all enabled datasources are queried

incident_idstring

scope the conversation to a specific incident (ID, external ID, or reference e.g. INC-123)

passthroughobject

run a native query expression verbatim against one datasource instead of planning from question

questionstring

the natural-language question to ask the telemetry agent; optional when passthrough is set, where it doubles as the recorded query's purpose and steers any follow-up analysis

session_idstring

resume a previous conversation by passing the session_id from a prior response

Catalog Entry List

catalog_entry_list
Full Description

List entries in a catalog type with optional search and pagination.

Catalog entries are instances of a type — for example, entries in a "Service" type might include "Payments API" or "User Auth". Each entry has attribute values defined by the type's schema, and may have aliases (alternative identifiers like EP011 for escalation paths or owner/repo for GitHub repos).

Required: catalog_type_id (the ID or type_name of the catalog type — use catalog_type_list to discover available types).

The response includes the type's attribute schema alongside entries. Attribute values use attribute names as keys. Reference attributes (those pointing to other catalog types) are formatted as "Name (ID)" so you can read the name directly and use the ID to look up the referenced entry via catalog_entry_show if needed.

Pagination: entries are ordered by name (or rank for ranked types). Use page_size (default 25, max 250) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Parameters (1 required, 3 optional)
Required
catalog_type_idstring

catalog type ID or type_name (use catalog_type_list to discover types)

Optional
afterstring

cursor from a previous page to fetch the next one

page_sizeinteger

results per page (default 25, max 250)

searchstring

search entry names and identifiers

Catalog Entry Show

catalog_entry_show
Full Description

Look up a catalog entry by ID and return its full details.

Returns the entry with all attribute values and aliases — unlike catalog_entry_list, array attributes are not truncated. The response includes the type's attribute schema for context. Aliases are alternative identifiers for the entry (e.g. EP011 for escalation paths, owner/repo for GitHub repos).

Use this when you need the complete set of values for a specific entry, e.g. all members of a team or all dependencies of a service.

Parameters (1 required)
Required
idstring

catalog entry ID (ULID)

Catalog Type List

catalog_type_list
Full Description

List catalog types configured in this organisation.

The catalog is a connected map of your organisation's data — it contains types like Service, Team, Feature, Customer, and anything else relevant to your organisation. Each type has a schema of attributes that define what data its entries hold.

Use this tool to discover what types exist, then use catalog_entry_list to browse entries of a specific type.

Returns: name, type_name, description, and the attribute schema for each type (excluding derived attributes like backlinks and paths).

This is not paginated — organisations typically have a manageable number of catalog types.

Parameters (0 required, 1 optional)
Optional
querystring

search type names

Code Change List

code_change_list
Full Description

List merged code changes (pull or merge requests) newest merge first, with filters on repository, merge time, deploy status, title and author.

Each row has the change's ID, permalink, title, author, merge time, tags, how many deploy events are linked to it, the environments they named and the latest deploy time. Pass an ID to code_change_show for the description, files, commits and the full deploy history.

Filters:

  • repository_id or repo: scope to one repository. Every row carries repository.id for the former; the latter takes an owner/name slug
  • merged_after / merged_before: the merge window. Only merged changes are listed. When merged_after is omitted the window is the 14 days before merged_before (or before now), and the response echoes the window it used, so widen merged_after if you need more
  • deployed_to: only changes with a linked deploy to that environment, or 'any' for at least one
  • query: substring match on the title, within the window
  • author: exact provider username, within the window

A repo that matches no tracked repository still lists any rows carrying that slug, and the response note names the closest tracked repositories so a misspelling is a one-step retry. Open and unmerged changes are not listed here; look one up by permalink with code_change_show.

Pass next_cursor as 'after' to fetch the next page. There is no total count: while has_more is true the rows you have are a partial set, so narrow the window or the filters rather than paging through a long history.

Parameters (0 required, 11 optional)
Optional
afterstring

cursor from a previous page's next_cursor

authorstring

provider username of whoever opened the change (exact, ignoring case)

deployed_tostring

only changes with a linked deploy to this environment, e.g. production, or 'any' for at least one linked deploy

includearray

optional sections: summaries (the AI summary on each row)

merged_afterstring

only changes merged at or after this time (RFC 3339, or a date like 2026-08-04). Defaults to 14 days before merged_before, or before now

merged_beforestring

only changes merged at or before this time (RFC 3339, or a date; a bare date means the whole of that day)

page_sizeinteger

results per page (default 10, max 50)

providerstring

github or gitlab

querystring

case-insensitive substring match on the title, applied within the window

repostring

repository slug as owner/name, e.g. acme/api (case-insensitive)

repository_idstring

tracked repository ID, as returned in a code change's repository.id. Prefer this over repo when you have it

Code Change Show

code_change_show
Full Description

Look up one code change (a pull or merge request we have ingested from the organisation's code host) and everything we know about when it was deployed.

Find it by its provider URL (permalink), by the ID a code_change_list row gave you, or by a merge commit SHA when you have a commit from a deploy or a log line and want the change behind it.

Returns: title, repository, author, state (open, merged or closed), opened/merged times, the merge commit SHA, the change's description and AI summary, tags, the files touched and the commits, then 'deploys': one entry per deploy event linked to this change, with the environment, component, deploy type (full, partial, rollback) and how the link was made. 'deploy_tracking' says how to read that list: whether this repository has deploy tracking at all, which environments it deploys to, and the typical merge-to-deploy time. Read its note before concluding a change has or has not shipped: deploys are linked from deploy events, so an empty list is strong evidence only when the repository is tracked, and never proof.

Use 'include' for more:

  • diff: the code diff (capped; the permalink has the full change)
  • comments: review comments and their replies

To browse what merged into a repository, or to find a change by title, use code_change_list.

Parameters (0 required, 4 optional)
Optional
idstring

code change ID, as returned by code_change_list

includearray

optional sections: diff (the code diff, capped), comments (review comments and replies)

permalinkstring

provider URL of the pull or merge request, e.g. https://github.com/acme/api/pull/4821. Supply exactly one of permalink, id or sha

shastring

merge commit SHA, or a prefix of at least 7 hex characters, to find the change that produced a commit on the default branch

Cover Request Create

cover_request_create
Full Description

Create a cover request asking for volunteers to cover a shift.

By default the system identifies candidates from the schedule's rotation members and notifies them directly; pass candidate_user_ids to ask specific people instead — e.g. just the one person the requester named. The requester receives a summary tracking candidate responses.

The request is created on behalf of the authenticated user, who must be on call during the requested window — you can only ask for cover of your own shift. Requires user authentication (e.g. OAuth) rather than an API key.

Times must be UTC RFC 3339 ending in Z; never convert a wall-clock time by writing an offset yourself. Prefer this over schedule_override_create when someone asks for cover rather than instructs a change: a cover request asks first, an override changes who gets paged immediately.

Parameters (3 required, 2 optional)
Required
end_atstring

cover window end as UTC RFC 3339 ending in Z. Same rules as start_at

schedule_idstring

schedule ID (ULID) needing coverage

start_atstring

cover window start as UTC RFC 3339 ending in Z. Never attach a local UTC offset

Optional
candidate_user_idsarray

user IDs to ask, when the requester named who should cover ("can Alex take my shift?"). Empty means ask everyone on the schedule

messagestring

message explaining why cover is needed, written in the first person as the requester

Cover Request List

cover_request_list
Full Description

List cover requests: asks for someone else to take a stretch of an on-call shift.

Use this to find the cover request ID that cover_request_respond and cover_request_manage need — e.g. "remind people about my cover request" or "accept Milly's request" starts here.

Only current and future requests are returned (a request whose window has fully passed is no longer actionable). By default only pending ("created") requests show; pass state to see accepted, declined, or cancelled ones. Pass user (a user ID, or "me" for the caller) to narrow to requests that user raised or is a candidate for, and schedule_id to narrow to one schedule.

Each result carries the request's window, state, message, candidates with their response state, and — for partially covered requests — which ranges are covered and which still need someone.

Parameters (0 required, 3 optional)
Optional
schedule_idstring

only cover requests on this schedule

statestring

filter by state: created (pending, the default), accepted, declined, or cancelled

userstring

a user ID, or "me" for the caller: only cover requests this user raised or is a candidate for

Cover Request Manage

cover_request_manage
Full Description

Manage a cover request as its requester or creator.

Actions:

  • cancel: cancel the request. Only works while it is still pending (nobody has accepted yet).
  • accept_offer: accept a candidate's partial coverage offer, creating an override for the offered ranges. Requires candidate_user_id.
  • send_reminder: nudge candidates who haven't responded yet.

Only the requester or creator can manage a request, so this requires user authentication (e.g. OAuth) rather than an API key.

Parameters (2 required, 1 optional)
Required
actionstring

one of: cancel (only while still pending), accept_offer (accept a candidate's partial offer — requires candidate_user_id; creates the override for the offered ranges), send_reminder (nudge candidates who haven't responded)

cover_request_idstring

the cover request to manage

Optional
candidate_user_idstring

for accept_offer: the user ID of the candidate whose offer to accept

Cover Request Respond

cover_request_respond
Full Description

Respond to a cover request you are a candidate on.

  • accept: accept the full request. An override is created automatically so you are placed on call for the requested window.
  • decline: decline the request; you are removed from consideration.
  • offer: offer partial coverage for specific time ranges. The requester then accepts or declines your offer.

The response is attributed to the authenticated user, who must be a candidate on the request. Requires user authentication (e.g. OAuth) rather than an API key. Offer time ranges must be UTC RFC 3339 ending in Z.

Parameters (2 required, 2 optional)
Required
cover_request_idstring

the cover request to respond to

responsestring

one of: accept (take the whole request — an override is created placing you on call), decline (remove yourself from consideration), offer (offer partial coverage for specific ranges)

Optional
messagestring

optional message to the requester

offer_time_rangesarray

required when response is offer: the ranges you can cover

Custom Dashboard Create

custom_dashboard_create
Full Description

Create a native Insights dashboard from a set of organised charts and tiles.

Call insights_chart_options first. Use preset_key whenever a preset fits the request: it carries valid organisation-specific defaults. Use chart only for a combination that is not already a preset, starting from a preset's chart in insights_chart_options. Add a trend or KPI tile by its key from the tiles list.

Each chart and trend tile becomes a full-width row, and KPI tiles next to each other share a row, grouped under the supplied section heading. The result is a normal native dashboard that the user can open and refine with the visual editor.

When the request names a team, custom field value, or anything else to filter by, find it in insights_chart_options. If nothing matches, tell the user what you looked for and the closest options that exist, and ask before you create the dashboard. Never drop a filter the user asked for without telling them.

This creates the dashboard immediately. Call it only after the user has asked for a dashboard and the requested contents are clear; ask a focused question first when an important grouping, time range, or metric is ambiguous. Returns a direct link to the created dashboard.

Parameters (2 required, 5 optional)
Required
namestring

The dashboard name shown in Insights

sectionsarray

The ordered dashboard sections. Each section must contain at least one panel.

Optional
aggregationstring

The chart time bucket: days, weeks, months or quarters. Defaults to period_unit.

compare_previous_periodboolean

Compare panels with the preceding period

include_current_periodboolean

Include the current incomplete period

period_countinteger

How many relative periods the dashboard shows. Defaults to 12.

period_unitstring

The relative period unit: days, weeks, months or quarters. Defaults to weeks.

Custom Field Values

custom_field_values
Full Description

Look up which values a custom field accepts, so you can set it to a real one.

Call this before setting a custom field on incident_create or incident_update. Pass custom_field_id — either the field's ID or its exact name — and optionally a search term to narrow a long list. You do not need to know the field's type first: this handles every type.

There is no cursor here. When pagination.has_more is true, pass a search term to narrow the list rather than asking for the next page.

Each value comes back with an id and a human-readable value. The id is what you set: the response's set_using tells you which key of a custom_field_entries value to put it in (value_option_id for option fields, value_catalog_entry_id for catalog-backed ones).

Read the field's own flags before writing to it:

  • can_be_set is false when an expression fully derives the field. Setting it will fail, so don't try.
  • allows_new_values is true when the field is tag-like, so people can add values to it. You can still only set a value that appears in this list.
  • accepts_multiple tells you whether you may set several values at once.

Text, link and numeric fields configure no values at all. They return an empty list with a note, which is not the same as an option field that has no options configured.

This is the best way to find the values a custom field accepts.

Parameters (1 required, 2 optional)
Required
custom_field_idstring

custom field ID or exact field name (see config://organisation)

Optional
page_sizeinteger

values to return (default 25, max 100)

searchstring

narrow to values matching this term, e.g. the value the user asked for

Document Search

document_search
Full Description

Search the organisation's synced knowledge base documents — runbooks, guides, post-mortems, architecture notes and similar — indexed from sources like GitHub, Notion, and Confluence.

Two matching modes are supported, and you can pass both for higher recall:

  • queries: natural-language questions or phrasings, matched semantically against document content
  • keywords: specific names, terms, or identifiers, matched against document summaries

Returns compact summaries (id, title, generated summary and tags, source system and URL), not full content. Matches are sorted alphabetically by URL — judge relevance from the summaries and tags, not the order. Each match may list refers_to: other indexed documents it links to, worth considering as follow-up reads. Pass a result's id to document_show to read its full content.

Use this to find operational knowledge, e.g. the runbook for a failing system or what a past incident concluded. This covers the organisation's own documents only, and not incident.io's own product documentation — it will not tell you how an incident.io feature behaves or how to configure one. For a synthesised answer to a broad question, prefer the ask tool.

Parameters (0 required, 2 optional)
Optional
keywordsarray

specific names, terms, or identifiers matched against document summaries; each keyword is scored independently, so prefer several short terms over one long phrase

queriesarray

natural-language phrasings of what you're looking for, matched semantically against document content; use when the ask is conceptual (e.g. 'how do we recover from a failed deploy')

Document Show

document_show
Full Description

Read a document from the organisation's synced knowledge base, returning the full text content (typically markdown) alongside its title, generated summary and tags, source system, and URL.

Name the document by its ID from document_search, or by its file path when it is a file in a synced plugin: either under the plugin's mount (/plugins/<plugin>/runbooks/lock-wait.md) or relative to the plugin root (runbooks/lock-wait.md). Source URLs are not accepted. Very large documents are cut at a size cap, signalled by content_truncated; the source URL links to the complete document.

Use this once search has surfaced a promising document and you need its actual content, e.g. to follow runbook steps or quote a post-mortem.

Use 'include' to request additional sections:

  • notes: problems recorded against the document by incidents and by assessed skill loads, newest first. Each note says what the document gets wrong, quotes the passage it is about, proposes an edit, and carries a status: open, or likely_resolved when the quoted passage is no longer in the text. Use them to decide what to fix in a runbook. A note's skill_usage_ids are the loads that produced it; pass the document to extension_skill_usage_list to see every load that worked from it.
Parameters (1 required, 1 optional)
Required
idstring

document ID (ULID) as returned by document_search, or the path of a file in a synced plugin: under its mount (/plugins/<plugin>/runbooks/lock-wait.md) or relative to the plugin root (runbooks/lock-wait.md)

Optional
includearray

optional sections to include: notes (recorded problems with the document, each with its status)

Duration Metrics Stats

duration_metrics_stats
Full Description

Aggregate incident duration metrics (e.g. time to acknowledge, time to resolve) grouped by one or more dimensions, returning per-group statistics.

Use this for MTTX-style questions — "what's our median time to resolve for P1s this quarter?", "how has time to acknowledge trended by month?", "which team resolves incidents fastest?". Each group reports count, mean, p25, p50 (median), p75, p90, min, and max, all as durations in hours.

Dimensions (combine up to 2, at most one time bucket):

  • metric: which duration metric the numbers belong to (e.g. Time to resolve vs Time to acknowledge). Group by this whenever more than one metric is in play, otherwise different metrics are pooled into one meaningless number.
  • severity: group by severity level (e.g. Critical, Major, Minor)
  • week / month / quarter: group by time bucket (bucketed by incident report time)
  • custom_field:<field_id>: group by a custom field's values (read config://organisation to find field IDs)

By default all configured duration metrics are included — pass duration_metric_ids to restrict to specific ones. Zero-length durations are excluded, and each metric honours its own paused-time configuration, matching the MTTX dashboard.

Date range: durations are measured over incidents reported within the window. Supply created_after / created_before derived from the question; if omitted the window defaults to the last 90 days. A very wide window over a large organisation can time out — narrow the range if that happens.

By default test and tutorial incidents are excluded and declined/canceled/merged incidents are excluded. Provide explicit status_category or mode filters to override these defaults.

Cross-reference: use incident_stats for counts and workload (this tool is about how long incidents take, not how many there are), and incident_list with include: ["durations"] to see per-incident durations behind a group.

Parameters (0 required, 13 optional)
Optional
created_afterstring

only incidents reported on or after this date (yyyy-mm-dd or RFC 3339). Derive from the question; defaults to 90 days before created_before (or today) if omitted.

created_beforestring

only incidents reported on or before this date (yyyy-mm-dd or RFC 3339). Defaults to today if omitted.

custom_fieldsobject

filter by custom field values: keys are custom field IDs, values are arrays of accepted value IDs

duration_metric_idsarray

restrict to specific incident duration metric IDs (e.g. time to acknowledge, time to resolve). Omit to include every configured duration metric — usually paired with group_by ["metric"] to keep them separate.

group_byarray

dimensions to group by, e.g. ["metric", "month"]. Options: metric (which duration metric — group by this to compare metrics), severity, a time bucket (week, month, or quarter), and custom_field:<field_id>. At most 2, at most one time bucket. If empty, returns a single aggregate across all matching durations.

incident_typearray

filter by incident type ID (read config://organisation to discover type IDs)

max_groupsinteger

limit the number of groups returned (e.g. top 10). Check total_groups in the response to see how many existed before truncation. All groups are returned if omitted.

modearray

filter by mode: standard, retrospective, test, tutorial

severityarray

filter by severity ID

sort_groups_bystring

order groups by: count (most incidents first) or slowest (highest median duration first). Defaults to the natural order (chronological when grouping by a time bucket, then by severity rank). max_groups keeps the first N in the current order, so pass count or slowest to get a true top-N.

status_categoryarray

filter by status category: triage, active, post-incident, closed, paused, declined, merged, canceled

teamarray

filter by team IDs (exact match). Mutually exclusive with team_part_of. Use team_list to discover team IDs.

team_part_ofarray

filter by team IDs including all sub-teams in the hierarchy. Mutually exclusive with team. Use team_list to discover team IDs.

Escalation Create

escalation_create
Full Description

Raise an escalation to page a specific user or an escalation path. The words "escalate" and "page" are synonymous.

Escalations wake people up and cannot be undone. Paging the wrong person, or paging when nobody asked you to, is the worst mistake this tool can make, so it drafts by default.

Choosing an action

  • action=suggest (the default) — draft an escalation for a person to accept, edit or decline. Use it whenever the request was implicit, the target is uncertain, or the target is an escalation path.
  • action=execute — page immediately. Only when the user explicitly asked for someone to be paged AND you have exactly one unambiguous user ID. To page a draft a human has already reviewed, pass action=execute with only suggestion_id — it is applied verbatim. Anything ambiguous — an escalation path, several users, or paging whoever asked — is drafted for confirmation instead of paged.
  • action=edit_suggestion — revise a draft. Pass suggestion_id plus only the fields you want changed; anything omitted keeps the draft's value. A user and an escalation path are alternative targets, so setting either one clears the other.

When not to use it

  • Information requests: "who's on call for payments?", "which teams can I page?". Answer those with escalation_path_list, schedule_show or catalog_entry_list. Naming who you could page is fine; paging them is not.
  • Changing who is on call. This tool cannot edit a schedule or an escalation path.
  • Something you can't do but a human could. The answer is never to page someone; say what you can't do.

Parameters

  • Give exactly one of user_ids or escalation_path_id. Never both, never neither. Prefer a user ID when you have a specific person in mind.
  • incident_id is optional — an escalation can stand alone. With an incident, title defaults to the incident's name; without one, title is REQUIRED, because the person paged needs to know what for.
  • description is required, and should say what expertise or action is needed. Keep names, incident numbers and priorities out of it. Good: "Database performance issue requires your PostgreSQL optimisation expertise".
  • Pass real ULIDs only. If you cannot find the ID you need, ask rather than guessing, and never fall back to a fuzzy match.

What a draft does

From a chat thread the draft is posted as a card in the conversation. From any other caller it is created without a card, so show it to the user yourself and find it again with suggestion_list; a person can accept it from the dashboard. card_posted on the result tells you which happened. A draft whose card lives in a conversation must be edited there (e.g. via ask with incident_id).

Parameters (0 required, 9 optional)
Optional
actionstring

'suggest' (default) drafts an escalation for a human to accept, edit or decline; 'execute' pages immediately; 'edit_suggestion' revises an existing draft

descriptionstring

why this page is needed, focusing on the expertise or action wanted. Required unless revising a draft that already has one

escalation_path_idstring

ID of the escalation path to page (see escalation_path_list). Give exactly one of user_ids or escalation_path_id

incident_idstring

incident this page relates to (ID, external ID, or reference like INC-123). Optional — an escalation can stand alone

priority_idstring

escalation priority ID (see config://organisation for IDs)

suggestion_idstring

the draft to act on — required with 'edit_suggestion', and with 'execute' to page a draft that was already reviewed. Accepts an id from a suggest result or suggestion_list. On an edit, omitted fields keep the draft's current values

titlestring

what the person is being paged for. Defaults to the incident's name when incident_id is given, and is required when it is not

urgencystring

how loudly to notify the users: 'high' (default) or 'low'. Only pass 'low' when a quiet page was explicitly asked for — never infer it from severity. With action 'edit_suggestion', pass 'high' to turn a quiet draft back into a normal page, since omitting urgency keeps the draft's current setting. Ignored when paging an escalation path, which carries its own per-level urgency

user_idsarray

IDs of the users to page. Give exactly one of user_ids or escalation_path_id

Escalation List

escalation_list
Full Description

List escalations (also known as "pages") with optional filters, newest first.

Use this for anything about pages that have already happened: "why was I paged?", "how many times was I paged last night?", "has that page been acked?", "find the page a teammate sent me". Pass user: ["me"] when someone asks about their own pages.

Each result includes the escalation's ID, title, status, priority, escalation path, who raised it, who was paged, when it was acked and the acker's user ID, and the linked alert and incident. Use escalation_show for full details on a specific escalation.

Filters (all optional):

  • query: search escalation titles
  • status: one or more of pending, triggered, acked, resolved, expired, cancelled, snoozed, pending_repeat. What each means:
    • pending: created but nobody has been paged yet
    • triggered: someone is currently being paged and hasn't responded
    • acked: someone acknowledged the page and is handling it (stops it climbing the path)
    • resolved: the page is done (acked and closed out, or the linked incident/alert resolved)
    • expired: nobody acknowledged before the escalation path ran out of levels to try
    • cancelled: called off before it completed
    • snoozed: temporarily silenced, to re-trigger later
    • pending_repeat: acknowledged but set to page again after a delay (a repeating reminder)
    • escalation_path: one or more escalation path IDs
    • priority: one or more priority IDs (see config://organisation for IDs)
    • user: one or more user IDs, or "me" for the caller
    • incident: one or more incident IDs
    • alert: one or more alert IDs
    • created_after / created_before: bound the time range

Use page_size to set the page length (default 15, max 50). Pass "next_cursor" back as "after" to fetch the next page.

Parameters (0 required, 11 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

alertarray

filter by linked alert IDs

created_afterstring

only escalations created at or after this time (yyyy-mm-dd or RFC 3339)

created_beforestring

only escalations created at or before this time (yyyy-mm-dd or RFC 3339). A bare date covers the whole of that day

escalation_patharray

filter by escalation path IDs

incidentarray

filter by linked incident IDs

page_sizeinteger

results per page (default 15, max 50)

priorityarray

filter by priority IDs

querystring

search escalation titles. Titles only, so a person's name will not match. To find a page someone else raised, bound the time range and read created_by on the results

statusarray

filter by state: pending, triggered, acked, resolved, expired, cancelled, snoozed, pending_repeat

userarray

filter by target user IDs. Pass "me" to mean whoever is asking — use it for "why was I paged" and "my pages", and don't look the ID up first

Escalation Path List

escalation_path_list
Full Description

List escalation paths configured in this organisation.

Escalation paths define who gets paged and in what order when an alert fires or someone manually escalates. Each path has levels — level 1 is paged first, then level 2 if nobody acknowledges, and so on. Each path has a short_id (e.g. EP011) that serves as a human-readable alias.

Use escalation_path_show to see the full ladder with who is currently on call at each level. You can search by name or short_id.

Pagination: results are ordered by name. Use page_size (default 15, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Parameters (0 required, 3 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

page_sizeinteger

results per page (default 15, max 50)

querystring

search escalation path names or short IDs (e.g. EP011)

Escalation Path Show

escalation_path_show
Full Description

Look up an escalation path and show who would be paged at each level.

Shows the full escalation ladder, resolving schedules to their current on-call users. Each level also names the schedules it pages (and the rotation, when it pages just one), which answers "which paths use this schedule". When the path has conditional branches (e.g. different paths for different priorities or working hours), all branches are shown with the currently active branch marked.

Level 1 is paged first — if nobody acknowledges within the time-to-ack window, level 2 is paged, and so on.

Use this to answer questions like "who would get paged if this alert fires?", "what does the backend escalation look like?", or "who's first-line on-call for this path?"

Use schedule_show to see the full rotation details for any schedule referenced in the path. Use escalation_stats(group_by: ["path"]) to see paging volume and ack rates for this path over time.

Parameters (1 required)
Required
idstring

escalation path ID (ULID)

Escalation Respond

escalation_respond
Full Description

Respond to an active escalation (page) on behalf of the authenticated user.

Use escalation_list to find active escalations, then respond with:

  • ack: acknowledge the page — stops it from climbing the escalation path. Use when you or an agent are handling the issue.
  • nack: decline the page — the escalation continues to the next level. Use when you cannot handle it.

Returns the updated escalation with its new status.

Requires user authentication (e.g. OAuth) rather than an API key, because the response is attributed to a specific user.

Parameters (2 required)
Required
idstring

escalation ID (ULID)

responsestring

how to respond: ack (acknowledge — stop paging, you are handling it) or nack (decline — you cannot handle this, continue escalating)

Escalation Show

escalation_show
Full Description

Look up an escalation (page) by ID and return its details.

An escalation is what happens when someone gets paged — it tracks who is being notified, whether they've acknowledged, and the full history of the page.

Returns: title, description, status, priority, escalation path, creator, linked incident and alert IDs, who is being paged (targets with urgency), and the full state transition history — including who acknowledged it, by name, and when.

Parameters (1 required)
Required
idstring

escalation ID (ULID)

Escalation Stats

escalation_stats
Full Description

Count escalations (pages) grouped by one or more dimensions, returning aggregate statistics with workload from linked incidents.

Use this tool instead of paginating through escalation_list when you need counts or trend data — for example "how many pages per escalation path this week?" or "what's our ack rate?"

Dimensions (combine freely in the group_by array):

  • status: group by outcome (pending, triggered, acked, resolved, expired, cancelled, snoozed). "Cancelled" means the page was automatically cancelled because the underlying alert resolved or was attached to an incident — it is system-initiated, not user-initiated. Exclude cancelled from ack rate calculations.
  • priority: group by priority (e.g. Critical, Urgent, In-hours)
  • path: group by escalation path name (e.g. "Engineering", "SRE On-call")
  • team: group by the team that owns the escalation path. Resolves through escalation path ownership, so its counts agree with filtering escalations by team. A path owned by several teams is counted under each; escalations on a path with no team owner show as "None".
  • user: group by the user(s) who were paged. Shows user names. An escalation can target multiple users across different levels, so the same escalation may appear under multiple users. Useful for assessing individual on-call burden.
  • time_of_day: group by when the escalation was created in UTC — working_hours (09:00-18:00 Mon-Fri), late_evening (18:00-23:00 any day + weekend daytime 09:00-18:00), or overnight (23:00-09:00)
  • week: group by ISO week (e.g. 2026-W03)
  • month: group by calendar month (e.g. 2026-01)
  • quarter: group by calendar quarter (e.g. 2026-Q1)

Scoping to a team: use the team filter for exact teams, or team_part_of to include a parent team and all its sub-teams in the hierarchy. Both resolve through escalation path ownership. Combine team_part_of with group_by ["team"] to break a parent down into its sub-teams.

Key metrics to derive from the results:

  • Ack rate: to calculate, group by ["path", "status"] then compute resolved / (resolved + expired) per path. Low rates indicate paging fatigue or coverage gaps.
  • Out-of-hours load: group by time_of_day to see working_hours vs late_evening vs overnight split. Overnight pages with low ack rates are the highest priority to fix.
  • Path comparison: group by path to see which teams are paged most
  • Workload per group: each group includes responder-hours from linked incidents, split by working hours, late evening, and overnight

Each group includes a count, workload breakdown, and sample escalation IDs that you can pass to escalation_show for detail.

The tool processes at most 25,000 escalations. If more match, the response sets "truncated": true — narrow the date range for accurate results.

Cross-reference: use alert_stats(group_by: ["source"]) to see which alert sources drive the most pages, and incident_stats(group_by: ["severity", "month"]) to see how paging load correlates with incident volume. Together the three stats tools give a full picture: alerts → pages → incidents → workload.

Structured analysis: for a comprehensive report with playbooks, themes, and recommendations, call analysis_start first — it provides step-by-step methodology and a branded report template. Use this tool directly only for quick, focused queries.

Parameters (0 required, 11 optional)
Optional
created_afterstring

only escalations created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only escalations created before this date (yyyy-mm-dd or RFC 3339)

escalation_patharray

filter by escalation path IDs

group_byarray

dimensions to group by. Categorical: status (pending/triggered/acked/resolved/expired/cancelled/snoozed/delayed/pending_repeat), priority, path (escalation path name), user (paged user), team (the team that owns the escalation path), time_of_day (working_hours/late_evening/overnight in UTC). Time buckets: week, month, quarter. If empty, returns a single total count.

max_escalation_ids_per_groupinteger

how many escalation IDs to return per group (default 10, max 250). Set to 0 to omit IDs entirely.

max_groupsinteger

limit the number of groups returned (e.g. top 10). Check total_groups in the response to see how many existed before truncation. All groups are returned if omitted.

priorityarray

filter by priority IDs

sort_groups_bystring

order groups by: alphabetical (the default — by dimension key, so week/month/quarter come back chronological), count (highest first), or workload (highest total responder-minutes first). max_groups keeps the first N groups in the current order, so to get a true top-N (e.g. most-paged paths) pass count or workload — otherwise you get an alphabetical slice that can omit the largest groups.

statusarray

filter by state: pending, triggered, acked, resolved, expired, cancelled, snoozed, pending_repeat

teamarray

filter to escalations on paths owned by these team IDs (exact match). Mutually exclusive with team_part_of. Use team_list to discover team IDs.

team_part_ofarray

filter to escalations on paths owned by these team IDs including all sub-teams in the hierarchy. Use this to scope to a parent team and everything beneath it. Mutually exclusive with team.

Extension Connector List

extension_connector_list
Full Description

List the organisation's extension connectors — the MCP servers and HTTP APIs connected through Extensions — with their capabilities and connection health.

Each entry says what the connector can be asked for (its capabilities, after runtime restrictions) and whether the connection currently works: connection_status is the latest diagnostic verdict, and reconnection_reason is set when it needs re-authentication. The tools field names the operations enabled in the connector's access policy.

Use this when reviewing an organisation's Extensions estate: what's connected, what's broken, and what a new integration would add.

Extension Plugin Create

extension_plugin_create
Full Description

Load a plugin from a source-control repository as an extension, and start its first sync.

A plugin is a skill tree — a directory holding skills/<name>/SKILL.md files, optionally with a README and reference files — that incident.io's AI agents mount and draw on during investigations and chat. Point this tool at the repository (and subpath, when the plugin isn't the repository root) and the plugin is registered with every skill enabled, then synced.

The repository must be reachable through the organisation's connected GitHub or GitLab integration; that isn't checked here. The first sync runs asynchronously and verifies it within moments — check the plugin's sync_status via extension_plugin_list, where an inaccessible repository or malformed plugin shows up as a sync_error. Renaming, disabling, skill selection, and removal are managed from the dashboard's Extensions page.

Parameters (3 required, 2 optional)
Required
providerstring

source-control provider the repository lives in: github or gitlab

repo_namestring

repository name

repo_ownerstring

owner segment of the repository slug; for GitLab this may carry group/subgroup segments

Optional
namestring

mount name override; defaults to the plugin directory or repository name

subpathstring

directory within the repository containing the plugin; omit for the repository root

Extension Plugin List

extension_plugin_list
Full Description

List the organisation's extension plugins with their skills and sync state.

Extension plugins are skill trees (SKILL.md files) synced from the organisation's own source-control repositories and mounted into incident.io's AI agents, so the agents follow the organisation's runbooks and conventions during investigations and chat.

Use this tool to see which plugins are installed and which skills each provides. To see how a plugin's skills are performing — and what our assessments say their authors should fix — pass a plugin's ID or name to extension_skill_feedback_list.

Extension Plugin Sync

extension_plugin_sync
Full Description

Request a re-sync of an extension plugin from its source repository.

Plugins otherwise sync on an hourly schedule, so use this after pushing changes to the plugin's repository to have agents pick them up now. The sync runs asynchronously: the response shows the plugin back in a pending state, and extension_plugin_list shows the outcome — last_synced_at moves on success, sync_error carries the reason on failure.

This completes the skill-improvement loop: read extension_skill_feedback_list, fix the skills in the repository, sync here, then re-read the feedback — issues whose quoted content you changed will read likely_resolved against the new version.

Parameters (1 required)
Required
pluginstring

extension plugin ID or mount name (see extension_plugin_list)

Extension Plugin Update

extension_plugin_update
Full Description

Update an extension plugin: enable or disable it, rename its mount, or change which of its skills agents may load.

Absent fields are left unchanged. Skill selection is set whole-state: pass skill_selection_mode "selected" together with the complete enabled_skill_dirs list (any dir not listed is disabled), or "automatic" with no dirs to let agents load every skill in the current version. Use the dir_name values from extension_plugin_list, and read extension_skill_feedback_list first when deciding — the funnel and issues say which skills earn their place.

Relocating a plugin to a different repository, and removing it, are managed from the dashboard's Extensions page.

Parameters (1 required, 4 optional)
Required
pluginstring

extension plugin ID or mount name (see extension_plugin_list)

Optional
enabledboolean

whether the plugin is mounted into agent runs

enabled_skill_dirsarray

under selected mode, the complete list of skill dir_names agents may load — whole-state, replacing any previous selection; must not be set under automatic mode

namestring

new mount name; agents see the plugin's tree at /plugins/<name>

skill_selection_modestring

how the plugin picks which skills agents may load: automatic (every skill in the current version, including newly-synced ones) or selected (only the dirs in enabled_skill_dirs)

Extension Skill Feedback List

extension_skill_feedback_list
Full Description

Get the current feedback on an extension plugin's skills, so their author can improve them.

After an agent loads a plugin skill during an investigation or chat, a retrospective assessment judges how the load went once the run is scored: whether the skill was followed (the funnel), whether following it helped (the contribution), and what specifically held it back. Those observations are deduplicated into distinct issues, each anchored to the file and verbatim quote it's about, with a suggestion for the fix.

Use this when improving a plugin's skills. Work the issues most-actionable-first (they're ordered that way): an issue's target_file and target_quote locate the content to edit in the plugin's source repository, and its theme names where the fix lands — description_mismatch in the frontmatter description, instruction_gap in the skill body, broken_reference in a link, capability_gap needs conditional guidance, output_format in format sections, behaviour/scope in structure. Keep what the strengths describe. An issue whose status is likely_resolved has probably been fixed already: its quoted content is gone from the current version.

Only skills that agents have actually loaded appear, and coverage grows over time: assessment runs after a run is scored, so assessed_count lags usage_count. Feedback survives renames and removals: an entry with in_current_version false is a skill that no longer exists under that directory, kept for its history rather than for editing.

Issues the organisation has dismissed as accepted tradeoffs (via extension_skill_feedback_update) are excluded by default; set include_dismissed to see them alongside, marked dismissed with the recorded reason.

Use 'include' to request additional sections:

  • examples: the most recent assessed loads per skill, each with the assessor's headline and rationale and a link to the run. Useful when a verdict needs evidence behind it; omitted by default because it's the bulk of the response. They are capped per skill and per surface, so a busy skill's examples may only span its last few hours — narrow them with example_usage and example_contribution to reach a particular verdict's loads, and use extension_skill_usage_list when you want every load over a period rather than a sample.
Parameters (1 required, 5 optional)
Required
pluginstring

extension plugin ID or mount name (see extension_plugin_list)

Optional
example_contributionstring

draw the examples only from loads with this contribution verdict: helped, neutral, hurt, or unclear. Every rate still counts every load

example_usagestring

draw the examples only from loads with this funnel verdict: not_used, not_applicable, partial, or followed. Every rate still counts every load

includearray

optional sections to include: examples (the most recent assessed loads with the assessor's notes)

include_dismissedboolean

when true, issues the organisation dismissed via extension_skill_feedback_update appear too, marked dismissed with the reason and who dismissed them

skillstring

narrow to one skill, by its dir_name (preferred) or frontmatter name

Extension Skill Feedback Update

extension_skill_feedback_update
Full Description

Dismiss a skill feedback issue the organisation won't fix, or reopen one dismissed earlier.

Use dismiss when an issue reflects an accepted tradeoff — the skill is deliberately written that way, the cost of fixing outweighs the friction, or the feedback misjudges intent — and continuing to report it would only be noise ("won't fix, stop reporting"). A dismissal is durable: later assessments observing the same issue do not revive it, so only dismiss issues that are genuinely settled rather than merely unfixed. Reopen undoes a dismissal, putting the issue back in the default feedback view.

Address the issue with the dir_name and issue_key from extension_skill_feedback_list (set include_dismissed there to find dismissed issues to reopen). Strengths cannot be dismissed — they're kept so authors don't undo what works.

Parameters (4 required, 1 optional)
Required
actionstring

dismiss (stop reporting the issue) or reopen (undo a dismissal)

dir_namestring

the skill's directory under skills/, as reported by extension_skill_feedback_list

issue_keystring

the issue to update, from extension_skill_feedback_list's issue_key field

pluginstring

extension plugin ID or mount name (see extension_plugin_list)

Optional
reasonstring

why the issue is being dismissed — required for dismiss, recorded and shown alongside the dismissed issue

Extension Skill Usage List

extension_skill_usage_list
Full Description

List individual assessed skill loads — one row per time an agent loaded a skill and the retrospective assessment judged how it went.

Each row carries the assessor's headline and one-sentence rationale, both verdicts (whether the agent followed the skill, and whether following it helped), the incident it ran against, a link to the run, and the documents the run worked from while the skill was loaded, such as the runbook it followed. That makes this the tool for evidence about particular loads: a digest of how skills did over a period, the runs behind a verdict, the worked examples to show someone, or every time a runbook was followed.

For a skill's overall track record — its rates, its open issues, and what to fix — use extension_skill_feedback_list instead. This tool never aggregates: it lists loads, newest first.

Filters (all optional):

  • plugin / skill: narrow to one plugin (ID or mount name) or one skill (dir_name)
  • surface: investigation or chat
  • usage: not_used, not_applicable, partial, followed
  • contribution: helped, neutral, hurt, unclear
  • document: only loads that worked from one document, by ID or plugin file path. Pair it with document_show and include: ["notes"] to see what those loads recorded against the document
  • since / until: bound the window (yyyy-mm-dd or RFC 3339). A bare date as "until" covers the whole of that day; a timestamp is the exact instant it names
  • window: which timestamp since and until bound

Only assessed loads appear. Assessment runs after a run is scored, so it lags the load — which is why window defaults to "assessed": a recurring digest that windows on when loads were assessed picks up every load exactly once, where windowing on "activated" permanently misses whatever was assessed after the last digest read it.

Pagination: use page_size (default 10, max 50) and pass "next_cursor" as "after" for the next page. Stopping before "has_more" is false means you have incomplete results.

Parameters (0 required, 11 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

contributionstring

keep only loads with this contribution verdict: helped, neutral, hurt, or unclear

documentstring

keep only loads that worked from this document, such as a runbook the run followed. A document ID (ULID) as returned by document_search, or the path of a file in a synced plugin: under its mount (/plugins/<plugin>/runbooks/lock-wait.md) or relative to the plugin root (runbooks/lock-wait.md)

page_sizeinteger

results per page (default 10, max 50)

pluginstring

narrow to one plugin, by ID or mount name (see extension_plugin_list)

sincestring

only loads at or after this time (yyyy-mm-dd or RFC 3339)

skillstring

narrow to one skill, by its dir_name

surfacestring

narrow to one surface: investigation or chat

untilstring

only loads at or before this time. A bare date covers the whole of that day, so until=2026-03-20 includes the 20th; a timestamp is the exact instant, so until=2026-03-20T00:00:00Z stops at the start of the 20th

usagestring

keep only loads with this funnel verdict: not_used, not_applicable, partial, or followed

windowstring

which timestamp since and until bound, and which the results are ordered by: assessed (default) or activated

Extension Upload Url

extension_upload_url
Full Description

Get a URL to upload extension content you want to check, when it isn't in a repository we can read.

Use this when there is nothing connected yet: no plugin registered and no repository we hold access to. If your content is on a branch, skip this and give extension_verify the repository and branch instead — we read that ourselves, and you upload nothing.

Two steps, because the archive never passes through this API: call this for a URL, PUT your gzipped tar to it, then call extension_verify with the same mount_name. Uploading a name again replaces what was there, so iterating costs nothing but the upload.

Tar from inside the plugin root, so members start at skills/ rather than at the directory holding it: cd <plugin-root> && tar czf tree.tar.gz $(ls -A). Tarring the parent instead prefixes every path, and the run fails saying the tree carries no skills. Build the archive before you call this: the URL is signed for ten minutes.

Nothing is registered by this. The tree is read for the run and discarded, so it never enters the catalog and no real investigation can load it.

Parameters (1 required)
Required
mount_namestring

what the tree will mount as during the run — use the name you intend to register the plugin under, so paths inside your skills resolve the same way they will in production. Lowercase letters, numbers and hyphens. Uploading this name again replaces what is there.

Extension Verify

extension_verify
Full Description

Test proposed extension content before landing it.

Three ways to say where the tree comes from. Name a plugin to check a change against its current synced version — what is live today. Name a repository, branch and mount name to check the tree on that branch, which is how you try work you have pushed but not merged; that does not need a plugin to exist, but it is just as useful when one does, because a protected main blocks merging rather than pushing. Or, when there is nothing connected at all, upload the tree with extension_upload_url and give the mount_name you uploaded to.

Either way the change is proposed, not committed: the files you pass are overlaid for the run only, and nothing is written back to the plugin or the repository.

The changed files are overlaid on the base tree — the plugin's current synced version, or the repository at the branch you name — and a verification agent tests the result: it writes concrete expectations for what should happen, hands realistic scenarios to a fresh agent that has the patched content and no knowledge of the change, and grades the expectations against what that agent actually did. Neither the plugin nor the repository is modified.

Only a plugin needs changes, because it is the version already live and the change is what makes the run a proposal. A branch and an uploaded tree are each the subject already, so pass either on its own and the run tells you whether that content works — which is what you want after pushing a branch, with no need to upload a tree we can already read.

External calls are simulated by default, and the report lists every simulated call as a place the run is weaker than production. Set live_connectors or live_telemetry to make reads real instead — graded against what those systems actually answer, and listed separately in real_calls. Writes are never made, whatever you set: the content under test has not shipped, so a scenario that would change a connected system is refused and the agent is told to assume it succeeded.

Anchor the run one of two ways: a reference to a recorded situation (a chatbot thread or investigation where things went wrong, or a skill feedback issue from extension_skill_feedback_list — the change is verified against the recorded problem), or a prose description of what to test (a new skill, a hypothetical you're protecting against). The run takes a few minutes; the response carries the verification ID to poll with extension_verify_show.

Parameters (1 required, 14 optional)
Required
changesarray

the proposed file changes, applied over the base tree for the run — over the plugin's current synced version, or over the repository tree at the ref. Neither is ever modified.

Optional
connector_overridesarray

tool-level changes to the connector inventory executors resolve against: add tools to an existing connector, replace or remove its real ones, or declare a whole hypothetical connector by naming one that doesn't exist. Tools the override doesn't name stay real. Use to test content against a capability surface before it is connected.

descriptionstring

what the change should achieve or the situation to test, in prose. Required when no reference is given.

live_connectorsboolean

make real read-only calls to the organisation's connectors instead of simulating them. Grades the change against what those systems actually answer rather than what the executor imagined they would. Reads only — a verification never writes to a connected system. Slower, and results describe the world now, not a scenario's premise. Default false.

live_telemetryboolean

run real read-only telemetry queries against the organisation's datasources instead of simulating them. Slower and costlier, but grades query quality against real data — results describe the world now, not a scenario's premise. Does not affect connector calls, which live_connectors controls. Default false.

mount_namestring

what the tree mounts as during the run — use the name you intend to register the plugin under, so paths inside your skills resolve the same way they will in production. Lowercase letters, numbers and hyphens. Required whenever plugin is omitted, and on its own — with no repository — it names a tree you uploaded with extension_upload_url.

pluginstring

extension plugin ID or mount name (see extension_plugin_list), to check a change against its current synced version. Omit and name a repository and branch instead to check work you have pushed but not merged — including for a plugin that is already registered — or omit both and give only mount_name to check a tree you uploaded.

providerstring

github or gitlab, when reading the tree from a repository. Required with repo_owner, repo_name and ref if you are naming one; leave all of them out when verifying an uploaded tree.

refstring

the branch to read the tree from. Resolved to a commit when you call this, so a push landing while the run is queued can't change what gets checked. Required when naming a repository.

reference_idstring

the recorded situation's ID, required with reference_type

reference_typestring

a recorded situation to test against: chatbot_thread, investigation or skill_feedback_issue. Give this when the change responds to something that already happened.

repo_namestring

the repository's name. Required when naming a repository.

repo_ownerstring

the repository's owner or group. Required when naming a repository.

runbookstring

plugin-relative path of a runbook to verify, e.g. runbooks/postgres-lock-errors.md. Any file in the tree, in any format. Puts the run in runbook mode: it checks whether the runbooks skill's find job selects this runbook for the referenced incident, and whether following it reaches the right conclusion. A change that writes exactly one markdown file under a runbooks directory fills this in for you; anything else needs it named. Give reference_type investigation, or the selection check has no incident to select for. Live telemetry and connector reads default on in this mode when you hold telemetry.view, because the runbook's queries are its content.

subpathstring

path to the plugin root inside the repository, for a monorepo holding several. Omit when the plugin is the whole repository.

Extension Verify Show

extension_verify_show
Full Description

Show a plugin verification's status and result.

Poll this after extension_verify: a run typically takes a few minutes, and while it runs the response reports how long it has been going and how far it has got. Once status is complete, the result carries the overall verdict, each tested expectation with its evidence, the external calls the run simulated rather than made (each a place the verification is weaker than a real run), and suggested edits for anything that failed — apply those locally and verify again.

Parameters (1 required)
Required
idstring

the verification ID returned by extension_verify

External Service List

external_service_list
Full Description

List the third-party services whose status pages we monitor.

Use it to turn a vendor into a name external_service_status accepts, and to tell "we don't monitor that vendor" apart from "that vendor is fine".

Every organisation sees the same services: we monitor them centrally, and an organisation cannot add to the set or remove from it. Names are the vendor's own ("Amazon Web Services", "Google Cloud Platform"): neither "AWS" nor "Bedrock" appears in one. A query matching nothing is refused with the closest names rather than an empty list.

Returns at most 25 services, sorted by name, with the number that matched. There is no pagination: a query narrows the list instead.

Parameters (0 required, 1 optional)
Optional
querystring

fuzzy search over service names. Whitespace-separated tokens must each match, in any order, ignoring . - _ and case differences. A token also matches as an in-order abbreviation (grfna matches Grafana). Omit to list every monitored service

External Service Status

external_service_status
Full Description

Read the state of third-party services we monitor, and the state changes inside a window.

A state here is a claim, and the result says whose. state_confirmed_by carries the source of the current state, reported_by the source of each change:

  • "vendor" — the vendor published this on their status page. It is their announcement, in their words.
  • "our_monitoring" — we inferred this ourselves and the vendor has published nothing. It is our suspicion, unconfirmed by them, and their status page does not show it. The service is not "in" this state as far as anyone outside us is concerned.

Use it whenever a vendor comes up in an incident: an upstream outage is the cheapest explanation to rule in or out, and the state changes tell you whether the timing lines up with your incident.

Takes ids or exact names from external_service_list, so resolve the vendor before calling: a product name belongs to its vendor ("Bedrock" and "S3" are both "Amazon Web Services"), and an abbreviation is not the name we hold ("GCP" is "Google Cloud Platform"). A name we do not monitor comes back under unknown.

This reads other companies' status pages, which we monitor centrally. It is not status_page_update, which publishes to the organisation's own status page.

Parameters (1 required, 2 optional)
Required
servicesarray

which services to read, as ids or exact names from external_service_list. Matched exactly: a product or an abbreviation is not a name we hold, and 'Bedrock' and 'S3' both live under 'Amazon Web Services'

Optional
fromstring

start of the window to read state changes over, as an RFC3339 timestamp or a date. A bare date starts at midnight. Defaults to 24 hours before 'to'

tostring

end of the window, as an RFC3339 timestamp or a date. A bare date covers the whole of that day. Defaults to now, and is capped at now

Feedback

feedback
Full Description

Submit feedback about the incident.io MCP tools to help us improve them.

After completing a task using the MCP tools, reflect on whether the experience could have been better. Consider:

  • Was there data you needed but couldn't get, or had to piece together from multiple calls?
  • Did a tool return too much or too little information for your use case?
  • Was there a question you couldn't answer without paginating through many results?
  • Did you have to work around a limitation (e.g. manually counting, converting units, cross-referencing IDs)?
  • Would a different grouping dimension, filter, or sort option have saved significant effort?

Examples of valuable feedback:

  • "I wanted to find the top 5 noisiest alert sources but had to call alert_stats then manually rank by workload — a built-in ranking would help"
  • "incident_show doesn't include the Slack channel name, only the URL — I needed the name to cross-reference with another system"
  • "I couldn't filter escalation_stats by the user who was paged — I wanted to show a specific person's paging load"
  • "The workload data was in minutes but I always convert to hours — returning both would save a step"

IMPORTANT: Always ask the user for permission before submitting feedback. Draft your feedback, present it to the user, and only call this tool after they approve. The user may want to refine, add context, or decline to send.

The feedback goes directly to the team building these tools and is stored for analysis. Even small friction points are valuable.

Parameters (3 required)
Required
contextstring

what were you trying to do? Describe the goal or task that led to this feedback.

ideal_functionalitystring

what would make this great? Describe the feature, data, or improvement that would have solved the problem.

what_was_triedstring

what did you try, and what was missing or didn't work? Describe the tools you used and where you hit friction.

Follow Up Create

follow_up_create
Full Description

Create a follow-up on an incident, either from scratch or by importing an existing external ticket.

Follow-ups are post-incident tasks — work that needs to happen after an incident is resolved, like "add monitoring for X", "update runbook", or "fix the root cause". They are distinct from in-flight actions which are checklist items used during active response. Follow-ups persist, can be assigned, prioritised, labelled, and exported to external issue trackers.

There are two modes:

1. Create from scratch: provide incident_id and title (required), plus optional description, assignee_id, assignee_team, priority_id, labels. The follow-up is created with status "outstanding".

2. Import from external ticket: provide incident_id and url (a link to an existing Linear, Jira, GitHub, GitLab, Asana, ClickUp, or Shortcut issue). The title, description, status, and assignee are imported from the ticket automatically. The follow-up is linked to the external issue for ongoing sync.

Instead of creating directly, action "suggest" posts a draft for a human to accept, edit, or decline, and action "edit_suggestion" (with suggestion_id) revises a draft. To apply a draft that was already reviewed, use action "execute" with only suggestion_id — it is applied verbatim. Prefer "suggest" when the user asked for a draft or you are unsure. In a chat conversation the draft appears as a card; elsewhere it has no card — show it to the user, and find it later with suggestion_list. A url import cannot be drafted.

If the org requires a priority or assignee, those fields become required and the tool will return a validation error if they're missing. A draft is looser: a missing required assignee is filled for you (the incident lead, else the caller), and a required priority is enforced when a person accepts.

A user and a team can own a follow-up at the same time. Omit assignee_team and the incident's own team is used where the organisation requires one; pass an empty string for no team. Where the organisation demands a team and none can be inferred, the call is refused rather than creating one it considers invalid.

assignee_id, assignee_team and priority_id each take an ID or a name. A name matching more than one user, team or priority is rejected rather than guessed.

Parameters (1 required, 9 optional)
Required
incident_idstring

incident to create the follow-up on (ID, external ID, or reference like INC-123)

Optional
actionstring

'execute' (default) creates the follow-up directly, or applies a reviewed draft when only suggestion_id is passed; 'suggest' posts a draft for a human to accept, edit, or decline; 'edit_suggestion' revises an existing draft

assignee_idstring

user ID or name to assign the follow-up to (find ids with user_list). A name matching more than one user is rejected rather than guessed

assignee_teamstring

team catalog entry ID or name to own this follow-up (find teams with catalog_entry_list). A user and a team can own one at the same time. Omit to take the incident's own team where the organisation sets one; pass an empty string for no team

descriptionstring

additional context or details

labelsarray

labels to attach (max 50 chars each, created automatically if new)

priority_idstring

follow-up priority ID or name (see config://organisation for IDs)

suggestion_idstring

the draft to act on — required with 'edit_suggestion', and with 'execute' to apply a draft that was already reviewed. Accepts an id from a suggest result or suggestion_list. On an edit, omitted fields keep the draft's current values

titlestring

follow-up title describing the action needed (required unless url is provided)

urlstring

URL of an existing issue in an external tracker (Linear, Jira, GitHub, etc.) to import as a follow-up — when provided, title and description are fetched from the ticket automatically (action 'execute' only)

Follow Up List

follow_up_list
Full Description

List follow-ups with optional filters and pagination.

Follow-ups are post-incident tasks that track work needed after an incident is resolved — things like "add monitoring for X", "update runbook", or "fix the root cause". They are distinct from in-flight actions (checklist items used during active response). Follow-ups can have priorities, assignees, labels, and can be exported to external issue trackers like Jira or Linear.

Each result includes: title, status, priority, assignee (user), assignee team, creator, labels, linked external issue, and timestamps.

Filters (all optional):

  • incident_id: filter to a specific incident (accepts ID, external ID, or reference like INC-123)
  • assignee_id: filter by assignee user ID (use your own ID from config://organisation to find "my follow-ups")
  • assignee_team_id: filter to a team (a catalog entry ID from team_list). Matches follow-ups assigned to the team, plus follow-ups assigned to a direct member of that team when no team is set — mirroring what the team page shows. An explicit team assignment always wins.
  • status: one or more of outstanding, completed, not_doing
  • created_after / created_before: date range for when the follow-up was created (yyyy-mm-dd or RFC 3339). Useful for scoping to recent follow-ups rather than returning historical items.

Pagination: results are ordered oldest first. Use page_size (default 10, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

For aggregate counts and breakdowns (e.g. "how many outstanding follow-ups by priority?"), use follow_up_stats instead of paginating through this list.

For post-incident review workflows, combine with incident_show to understand the incident context behind each follow-up. Use follow_up_create to add new follow-ups discovered during analysis.

Parameters (0 required, 8 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

assignee_idstring

filter by assignee user ID

assignee_team_idstring

filter by owning team — a catalog entry ID from the org's Team catalog type (use team_list to discover valid IDs)

created_afterstring

only follow-ups created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only follow-ups created before this date (yyyy-mm-dd or RFC 3339)

incident_idstring

filter to a specific incident (ID, external ID, or reference like INC-123)

page_sizeinteger

results per page (default 10, max 50)

statusarray

filter by status: outstanding, completed, not_doing

Follow Up Stats

follow_up_stats
Full Description

Count follow-ups grouped by one or more dimensions, returning aggregate statistics.

Use this tool when you need counts or breakdowns across many follow-ups — for example "how many outstanding follow-ups by priority?" or "follow-up completion rate by incident severity". Use follow_up_list to browse individual follow-ups.

Dimensions (combine freely in the group_by array):

  • status: group by follow-up status (outstanding, completed, not_doing)
  • priority: group by follow-up priority (e.g. P0, P1, P2). Shows "No priority" for unset.
  • assignee: group by assigned user. Shows "Unassigned" for follow-ups without an assignee.
  • has_external_issue: group by whether the follow-up has been exported to an external tracker like Jira or Linear (true/false)
  • incident_severity: group by the severity of the parent incident (e.g. Critical, Major, Minor). Useful for answering "are we completing follow-ups from our most critical incidents?"
  • week: group by ISO week (e.g. 2026-W03)
  • month: group by calendar month (e.g. 2026-01)
  • quarter: group by calendar quarter (e.g. 2026-Q1)

Each group includes a count, sample incident references (e.g. INC-123) for drill-down, an age summary for outstanding items showing how long they've been open, and a completion-time summary (mean and max days from creation to completion) covering the group's completed follow-ups. Completion time is measured for follow-ups created within the queried window; narrowing by created_after/created_before therefore answers "how long did the follow-ups created in this period take to close".

By default, deleted and archived follow-ups are excluded.

The tool processes at most 25,000 follow-ups. If more match, the response sets "truncated": true — narrow the date range for accurate results.

Drill-down: each group includes incident references. Pass these to follow_up_list(incident_id: "INC-123") to see the individual follow-ups, or to incident_show for incident context.

Cross-reference: use incident_stats to understand the incidents that generated these follow-ups, and follow_up_list to browse and update individual items.

Structured analysis: for a comprehensive report with playbooks and recommendations, call analysis_start first.

Parameters (0 required, 10 optional)
Optional
assignee_idstring

filter by assignee user ID

created_afterstring

only follow-ups created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only follow-ups created before this date (yyyy-mm-dd or RFC 3339)

group_byarray

dimensions to group by. Categorical: status (outstanding/completed/not_doing), priority, assignee, has_external_issue (exported to Jira/Linear/etc). Parent incident: incident_severity. Time buckets: week, month, quarter. If empty, returns a single total count.

incident_idstring

filter to a specific incident (ID, external ID, or reference like INC-123)

max_groupsinteger

limit the number of groups returned (e.g. top 10). Check total_groups in the response to see how many existed before truncation.

max_sample_ids_per_groupinteger

how many incident references (e.g. INC-123) to return per group (default 10, max 250). Set to 0 to omit IDs entirely.

priorityarray

filter by follow-up priority option IDs

sort_groups_bystring

order groups by: alphabetical (the default — by dimension key, so week/month/quarter come back chronological) or count (highest first). max_groups keeps the first N groups in the current order, so to get a true top-N (e.g. assignees with the most outstanding follow-ups) pass count — otherwise you get an alphabetical slice that can omit the largest groups.

statusarray

filter by follow-up status: outstanding, completed, not_doing

Follow Up Update

follow_up_update
Full Description

Update an existing follow-up. Only the fields you provide will be changed — omitted fields are left as-is.

Use follow_up_list to find follow-up IDs. Use follow_up_create to add new follow-ups.

Updatable fields:

  • title: rename the follow-up
  • description: set or clear the description (empty string clears)
  • assignee_id: assign to a user by ID or name (empty string unassigns the user)
  • assignee_team: set the owning team by catalog entry ID or name (empty string unassigns the team)
  • priority_id: set priority by ID or name (empty string clears, see config://organisation for IDs)
  • status: change to outstanding, completed, or not_doing
  • labels: replace all labels (omit to leave unchanged)

A user and a team can own a follow-up at the same time: assignee_id and assignee_team are independent, and setting one never clears the other. A name matching more than one user, team or priority is rejected rather than guessed.

Deleting a follow-up is not possible here, so "deleted" is not an accepted status. Follow-ups can currently only be deleted on other surfaces like Slack and the dashboard.

If the follow-up has been exported to an external issue tracker (Jira, Linear, etc.), the fields that sync from the external system cannot be changed here and the tool says which they are. The owning team can always be changed; the priority can too, unless the organisation syncs priorities from the tracker.

Returns the updated follow-up.

Parameters (1 required, 7 optional)
Required
idstring

follow-up ID to update

Optional
assignee_idstring

user ID or name to assign (pass empty string to unassign the user; the owning team is left alone)

assignee_teamstring

team catalog entry ID or name to own this follow-up (pass empty string to unassign the team; the assigned user is left alone)

descriptionstring

new description (pass empty string to clear)

labelsarray

replace all labels (max 50 chars each, omit to leave unchanged)

priority_idstring

follow-up priority ID or name (pass empty string to clear, see config://organisation for IDs)

statusstring

new status: outstanding, completed, or not_doing

titlestring

new title

Glossary Create

glossary_create
Full Description

Create a glossary entry: a coined term (acronym, service name, or internal jargon) and what it means.

Use this when the organisation uses a term that is not already in the glossary and someone with organisation settings permission wants it defined so Scribe and other AI features transcribe and summarise it correctly. Look the term up with glossary_list first — a live entry with the same item (case-insensitive) is rejected.

Pass after with an entry ID from glossary_list to insert the new entry immediately after it. Omit after to append the new entry to the end. Anyone can read it with glossary_list; creating it requires organisation_settings.update.

Returns the created entry.

Parameters (2 required, 1 optional)
Required
descriptionstring

what the term means (max 2000 characters)

itemstring

the term to coin, e.g. an acronym or service name (max 128 characters). Must be unique among live entries, case-insensitively

Optional
afterstring

glossary entry ID after which to insert this entry. Omit to append it to the end

Glossary Delete

glossary_delete
Full Description

Delete a glossary entry so it no longer appears in glossary_list.

Use this when a coined term is wrong or no longer used. Deleting frees the item: the same term can be added again later with glossary_create. It cannot be undone through these tools. Find the ID with glossary_list.

Requires organisation_settings.update.

Returns the deleted entry.

Parameters (1 required)
Required
idstring

glossary entry ID from glossary_list

Glossary List

glossary_list
Full Description

List and search this organisation's glossary: coined terms (acronyms, service names, internal jargon) and what they mean.

Consult the glossary before treating an unfamiliar acronym, service name, or piece of jargon as unknown, and before inventing an expansion. Scribe and other AI features use these definitions so they transcribe and summarise the organisation's language correctly. If the user mentions a term that might be internal, look it up here first.

Anyone in the organisation can read the glossary. To add or change terms, use glossary_create, glossary_update, or glossary_delete (those need organisation settings permission).

Filters (all optional):

  • item: exact match on the coined term (case-insensitive). Prefer this when you already have the item.
  • query: relevance-ranked search over item and description, matching whole words and partial terms. Prefer this when searching for a meaning or a partial name.

Pagination: entries are ordered by rank, or by relevance when query is set. Use page_size (default 25, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. A query or item that matches nothing is refused with the closest coined items rather than an empty list.

Parameters (0 required, 4 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

itemstring

exact term to look up (case-insensitive). Use this when you already know the coined item (e.g. PSP); use query for a looser search

page_sizeinteger

results per page (default 25, max 50)

querystring

search over item and description, ranked by relevance. Matches whole words and partial terms (e.g. ledger finds ledger-service). Use this when you are looking up jargon, an acronym, or a service name you don't have an exact match for

Glossary Update

glossary_update
Full Description

Update a live glossary entry's item and description.

Use this to correct a definition or rename a coined term. Both item and description are required — pass the current item unchanged if you are only editing the description. Find the ID with glossary_list. An archived entry cannot be updated: create a new one with glossary_create instead.

Requires organisation_settings.update. A live entry that already holds the same item (case-insensitive) is rejected.

Returns the updated entry.

Parameters (3 required)
Required
descriptionstring

what the term means after the update (max 2000 characters)

idstring

glossary entry ID from glossary_list

itemstring

the term as it should be coined after the update (max 128 characters). Must be unique among other live entries, case-insensitively

Help Query

help_query
Full Description

Ask how incident.io works and get an answer written from incident.io's own product documentation.

Use it for questions about the product itself: "how do escalation paths work?", "what does incident.io integrate with for follow-ups?", "how do I set up an alert route?", "what's the difference between streams and incidents?". Reach for it before guessing at product behaviour, and before telling a user something isn't possible.

This is not document_search. document_search searches the organisation's own synced documents — their runbooks, guides and post-mortems from GitHub, Notion or Confluence. This tool searches incident.io's documentation of the product, which every organisation shares and none can add to. A question about how a feature behaves belongs here; a question about how this organisation responds to an outage belongs in document_search.

It answers from documentation only and can see nothing about the organisation — no incidents, schedules or configuration. For "who is on call right now?" or "which alert routes do we have?", use the tools that read live data.

Returns a written answer, not a list of matching documents: there are no per-document ids to read further, so ask a fuller question than you would give a search box. A model writes the answer, so a call takes a few seconds.

Pass session_id from a previous response to ask a follow-up with the earlier turns in context.

Parameters (1 required, 1 optional)
Required
questionstring

the question about incident.io, phrased as you would ask a support engineer (e.g. 'how do escalation paths pick who to page?')

Optional
session_idstring

resume a previous help conversation by passing the session_id from a prior response

Incident Create

incident_create
Full Description

Create a new incident.

Use this tool when you know what incident to create (e.g. from an alert, a customer report, or a detected issue).

Before creating from an alert or a report, check for an existing open (triage, active or paused) incident for the same problem so you attach to it or merge rather than declaring a duplicate.

Required: name (a short, descriptive title).

A retry of the same request returns the incident it already created, with already_existed set — say it was already declared rather than claiming you declared it.

Rate limited: an organisation can only create a limited number of incidents per hour. A call over the limit is rejected — don't retry in a loop.

The incident is created in triage by default — this means no severity is required and the team can assess before accepting. To create an already-accepted incident, provide both severity_id and an active incident_status_id.

Never invent a severity. Only pass severity_id if the user has explicitly stated one (e.g. "create a sev2", "this is critical"). If they haven't, leave severity_id empty so the incident starts in triage and a responder can set it later.

Some organisations have disabled manual triage incidents — those require severity_id at creation time. The organisation's declare form may also require custom fields on every incident, including triage.

A call missing any required field creates nothing.

If the tool can deliver the form to the person itself, the call succeeds and says what was missing — tell them the form is waiting for them and stop; don't repeat the field list or claim you declared anything.

Otherwise it returns a "missing_required_fields" validation error. Its first entry summarises what is missing. After it comes one "missing_required_field" entry per field, each pointing at the field it means: severity_id for severity, custom_field_entries/<custom_field_id> for a custom field. Read those pointers to tell the fields apart.

You may be given a URL to a form that the user can fill in the missing fields which you should share with them to complete if you cannot gather the fields yourself. If they tell you what all of the missing fields should be you can retry calling the tool with those new fields.

Defaults applied when fields are omitted:

  • visibility: public
  • incident_type_id: the organisation's default incident type
  • incident_status_id: triage (only if the organisation allows manual triage incidents)
  • severity_id: none (allowed in triage; required if status is active or if the org has disabled manual triage)
  • slack_team_id: only meaningful on Slack Enterprise Grid with multiple workspaces — defaults to the workspace the authenticated user is a member of (when unambiguous), otherwise the organisation's primary workspace

Read the config://organisation resource to discover severity IDs, status IDs, incident type IDs, custom field IDs, and role IDs.

Returns the created incident summary.

Parameters (1 required, 9 optional)
Required
namestring

short, descriptive incident name (e.g. 'Database connection pool exhausted')

Optional
custom_field_entriesarray

custom field values to set on the new incident

incident_status_idstring

status ID to start in (see config://organisation). Defaults to triage. If you set an active status, severity_id is required.

incident_type_idstring

incident type ID (see config://organisation). Defaults to the organisation's default type.

role_assignmentsarray

role assignments for the new incident (see config://organisation for role IDs)

severity_idstring

severity ID (see config://organisation), or the catalog entry ID for a severity. If omitted, the incident starts in triage with no severity — set severity when you accept it.

slack_team_idstring

Slack workspace (team) ID to create the incident channel in, e.g. T012AB3CD4. Only relevant for Slack Enterprise Grid organisations with multiple workspaces — see the Slack workspaces section of config://organisation. Omit otherwise.

summarystring

initial summary describing what is happening (markdown)

users_to_invitearray

user IDs to invite to the incident channel . These must be incident.io user IDs — any other kind of ID invites nobody, with no error. Ignored for private incidents.

visibilitystring

public (default, visible to all) or private (restricted access)

Incident List

incident_list
Full Description

Search and list incidents, returning a summary per result. Use incident_show to get full details for a specific incident.

Each result includes: reference (e.g. INC-123), name, status (with category), severity, mode, reported_at, updated_at, and a permalink. A merged incident (status category "merged") also includes "merged_into", identifying the incident it was merged into.

Use the include parameter to enrich results with additional fields, avoiding the need to call incident_show for each incident:

  • summary: short incident summary (~200 chars, AI-generated or human-written) — useful for understanding what each incident was about without fetching full details
  • roles: include role assignments (e.g. incident lead) with user names and IDs
  • custom_fields: include custom field values
  • timestamps: named timestamps (e.g. reported at, resolved at) — useful for timeline and trend analysis
  • durations: duration metrics (e.g. time to resolve, in seconds) — useful for comparing incident response times
  • escalation_urgency: include AI assessment of whether each incident needed immediate response (urgency level and tags). Only available for orgs with AI investigations enabled. Use incident_show for the full reasoning text.

This is especially useful for analytical queries like "who has been incident lead the most?" — include roles and paginate through the results rather than calling incident_show for each one. For trend analysis, include summary, timestamps, and durations to get context without extra API calls.

By default only standard and retrospective incidents are returned, and declined/canceled/merged incidents are excluded, except when searching by query, which returns every status category. Provide explicit filters to override these defaults.

Filters (all optional):

  • query: free-text search across incident names
  • status_category: one or more of triage, active, post-incident, closed, paused, declined, merged, canceled
  • severity: one or more severity IDs
  • incident_type: one or more incident type IDs (e.g. filter to "Default" only, or exclude "Internal" and "Maintenance")
  • mode: one or more of standard, retrospective, test, tutorial. standard is a real, live incident; retrospective records something that already happened for the postmortem/timeline without a live response; test and tutorial are practice incidents (a test run, or the onboarding walkthrough) and are excluded by default
  • team: one or more team IDs (exact match — incidents tagged with any of these teams)
  • team_part_of: one or more team IDs including all sub-teams in the hierarchy (e.g. "Platform" returns incidents for Platform and all its child teams). Mutually exclusive with team.
  • custom_fields: filter by custom field values (object mapping field ID to array of value IDs)
  • created_after / created_before: dates to bound the time range (yyyy-mm-dd or RFC 3339)
  • assigned_to: one or more user IDs (or the literal "me" for the calling user). Returns incidents where any listed user is a participant (responder/collaborator/observer) or has any incident role assignment (e.g. lead). Use this to triage your own workload without wading through everyone else's, e.g. {"assigned_to": ["me"], "status_category": ["triage", "active"]}. "me" only works for OAuth tokens, not API keys.

To discover severity IDs, incident type IDs, custom field IDs, and custom field value IDs, read the config://organisation resource first.

Sorting: results are ordered newest first by default. Set sort_by to "workload" to order by total responder-minutes (highest first), which is useful for finding the most costly incidents. Workload data is synced hourly from our insights pipeline.

Pagination: use page_size to control the page (default 10, max 50). When the response has "has_more": true, pass the "next_cursor" value as "after" to fetch the next page. Stopping before "has_more" is false means you have incomplete results.

Tip: if you need counts or trend data, use incident_stats first — it's much more efficient than paginating through incident_list and counting manually. Use incident_list when you need to browse individual records or need the detail that includes provide.

Parameters (0 required, 15 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

assigned_toarray

filter to incidents where any of these users is involved — either as a participant (responder, collaborator, observer) or assigned to any incident role (lead, etc.). The literal string "me" resolves to the calling user (only available for OAuth tokens, not API keys). Useful for triaging your own workload — e.g. {"assigned_to": ["me"], "status_category": ["triage", "active"]} returns your open incidents. Use the "You" section of config://organisation to find your own user ID, or team_list / team_show to find other users' IDs.

created_afterstring

only incidents created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only incidents created before this date (yyyy-mm-dd or RFC 3339)

custom_fieldsobject

filter by custom field values: keys are custom field IDs, values are arrays of accepted value IDs (read the config://organisation resource to discover field and value IDs)

incident_typearray

filter by incident type ID (read config://organisation to discover type IDs)

includearray

optional fields to enrich each result with: summary (short incident summary, ~200 chars), roles (role assignments), custom_fields (custom field values), timestamps (named timestamps like reported at, resolved at), durations (duration metrics like time to resolve), escalation_urgency (AI assessment of whether immediate response was needed — urgency and tags only, use incident_show for full reasoning). Use these to avoid calling incident_show for every result.

modearray

filter by mode: standard, retrospective, test, tutorial

page_sizeinteger

results per page (default 10, max 50)

querystring

search incident names

severityarray

filter by severity ID

sort_bystring

sort order: created_at (default, newest first) or workload (highest total responder-minutes first, uses insights data synced hourly)

status_categoryarray

filter by status category: triage, active, post-incident, closed, paused, declined, merged, canceled

teamarray

filter by team IDs (exact match). Mutually exclusive with team_part_of. Use team_list to discover team IDs.

team_part_ofarray

filter by team IDs including all sub-teams in the hierarchy. Use this when you want incidents for a team and all its descendant teams. Mutually exclusive with team. Use team_list to discover team IDs.

Incident Merge

incident_merge
Full Description

Merge incidents that turn out to be the same problem into one.

The incidents in incident_ids are the sources: each moves to the merged status and stops being responded to separately. merged_into_incident_id is the target, which survives and carries the response on. Merging several sources into one target is a single call — don't loop.

A source may be in any lifecycle status except merged or canceled. The target may also have any status except merged or canceled. If it has been merged into something else, merge into the incident at the end of that chain instead. Streams cannot be merged, on either side.

Sources that cannot be merged are skipped and the rest still apply. The outcome names the sources that merged and the ones that did not. A refusal of the target, or a call where nothing could be merged, is an error. Each merge is its own transaction, so a later failure does not undo the sources that already merged. Call again with the same list to see where it got to: an incident that already merged is skipped by name.

Merging is visible to responders: each source's channel is archived after a delay, its alerts and attachments move onto the target, and its subscribers are notified.

Read the result with incident_show. To reverse a merge, use incident_unmerge on the source that was merged away.

Parameters (2 required)
Required
incident_idsarray

the incidents to merge away — the sources (ID, external ID, or reference like INC-123). Each may be in any lifecycle status except merged or canceled.

merged_into_incident_idstring

the incident they are merged into — the target, which survives (ID, external ID, or reference like INC-123)

Incident Message

incident_message
Full Description

Share a finding, insight, or piece of analysis into an incident's chat channel, so the responders can see it.

Posts a quoted message attributed to you, with an optional threaded reply for longer detail. Use it to forward something you have worked out — "post that to the channel", "let the responders know".

This is not the tool for updating the incident. Three nearby things go elsewhere:

  • Communicating a change to status, severity, summary or custom fields, or a progress note on the incident timeline, is incident_update (its message field).
  • Correcting an in-progress investigation's hypothesis is investigation_steer.
  • Answering the user in this conversation needs no tool at all.

Distil the key finding into a concise message rather than dumping the whole conversation. The main message is quoted in the channel, so keep it to the takeaway and put supporting detail in thread_message.

The attribution line names you from your credentials — it cannot be set by the caller. An incident with no chat channel has nowhere to post, and is refused.

Parameters (2 required, 1 optional)
Required
incident_idstring

incident whose channel to post into (ID, external ID, or reference like INC-123)

messagestring

the finding to post, in markdown. Keep it concise — distil the key takeaway rather than pasting the whole conversation.

Optional
thread_messagestring

optional longer detail posted as a threaded reply, so the main message stays concise

Incident Show

incident_show
Full Description

Look up an incident by ID or reference (e.g. INC-123, 123, or a full ID) and return its details.

Returns: name, status, severity, roles, participants, custom fields, timestamps, durations, workload (responder time split by working/late/overnight hours), summaries, channel URLs, and the 5 most recent status updates. For a merged incident, "merged_into" identifies the incident it was merged into.

Use 'include' to request additional sections:

  • investigation: AI investigation findings and extended summary. Always request this when investigating root causes or triaging — it contains the analysis our AI has already performed.
  • postmortem: the post-mortem document content. Request this when reviewing what happened or preparing reports — it contains the team's written analysis.
  • updates: all status updates (default returns most recent 5 only). Request this when you need the full timeline of how the incident progressed.
  • escalation_urgency: AI assessment of whether the incident truly needed immediate response (immediate, deferrable, or unsure) with classification tags and reasoning. Useful for on-call burden analysis and alert noise reviews. Only available for orgs with AI investigations enabled.
  • call_notes: AI-generated notes from calls, returned as two separate lists. "call_notes" covers calls held during the incident — what responders said while working it. "meeting_notes" covers follow-up meetings held afterwards, such as debriefs and post-mortem reviews. Request this when you want what people actually discussed rather than what was written down. Notes are only returned for the 5 most recent calls; raw transcripts are not available through this API.

For investigation or root cause analysis, request include: ["investigation", "postmortem"] — the default response without these only gives you the basic metadata, not the deeper analysis.

For the full investigation content (all findings, checks, conversation history, and incident context as a file tree), use the investigation_sync tool instead — it returns a downloadable tar.gz archive of the complete investigation filesystem.

Parameters (1 required, 1 optional)
Required
idstring

incident ID, external ID, or reference (e.g. INC-123, 123, or a ULID)

Optional
includearray

optional sections to include: postmortem, investigation, updates, escalation_urgency, call_notes

Incident Stats

incident_stats
Full Description

Count incidents grouped by one or more dimensions, returning aggregate statistics.

Use this tool when you need counts, breakdowns, or trend data across many incidents — for example "how many P1s this quarter?" or "incident volume by team by month". Use incident_list when you need to browse or search individual incidents, and incident_show to get full details for a specific incident.

Dimensions (combine freely in the group_by array):

  • severity: group by severity level (e.g. Critical, Major, Minor)
  • status: group by status category (e.g. triage, active, closed)
  • type: group by incident type
  • mode: group by mode. standard is a live incident, retrospective records a past one for its postmortem/timeline, and test/tutorial are practice incidents (excluded by default)
  • alert_source: group by the alert source that triggered the incident (e.g. Datadog, Sentry). Shows "No alert" for manually created incidents. Multi-value: incidents with alerts from multiple sources are counted under each source individually.
  • escalation_urgency: group by AI-assessed urgency (immediate, deferrable, unsure, or "Not assessed" for incidents without analysis). Useful for quantifying alert noise and on-call burden — combine with month for trend analysis.
  • team: group by the org's configured team (e.g. Engineering, Platform). Prefer this over grouping by a team-shaped custom field (custom_field:<id>) — "team" resolves the org's configured team field, so its counts agree with filtering by team. Multi-value: incidents tagged with several teams are counted under each; incidents with no team show as "None". Combine with month/severity for per-team trends and workload.
  • custom_field:<field_id>: group by a custom field's values (read config://organisation to find field IDs). Multi-value: multi-select fields are flattened so each value is counted individually.
  • role:<role_id>: group by who is assigned a specific role (e.g. Incident Lead). Shows user names, or "Unassigned" for incidents without that role.
  • week: group by ISO week (e.g. 2026-W03)
  • month: group by calendar month (e.g. 2026-01)
  • quarter: group by calendar quarter (e.g. 2026-Q1)

Each group includes a count, a workload breakdown (total responder-minutes split by working hours, late evening, and overnight), and the most recent incident references (e.g. INC-123) which you can pass directly to incident_show to drill into. Workload data is synced hourly from our insights pipeline and may be absent for very recent incidents.

By default, test and tutorial incidents are excluded and declined/canceled/merged incidents are excluded. Provide explicit status_category or mode filters to override these defaults.

The tool processes at most 25,000 incidents. If more match, the response sets "truncated": true — narrow the date range for accurate results.

Drill-down: each group includes incident references (e.g. INC-123). Pass these to incident_show with include: ["investigation", "postmortem"] to understand root causes behind the numbers.

Cross-reference: compare with alert_stats(group_by: ["source"]) to see how alert volume and noise translate to the incident workload shown here.

Structured analysis: for a comprehensive report with playbooks, themes, and recommendations, call analysis_start first — it provides step-by-step methodology and a branded report template. Use this tool directly only for quick, focused queries.

Parameters (0 required, 13 optional)
Optional
created_afterstring

only incidents created after this date (yyyy-mm-dd or RFC 3339)

created_beforestring

only incidents created before this date (yyyy-mm-dd or RFC 3339)

custom_fieldsobject

filter by custom field values: keys are custom field IDs, values are arrays of accepted value IDs

group_byarray

dimensions to group by, e.g. ["severity", "month"]. Categorical: severity, status, type, mode, escalation_urgency, team. Custom field: custom_field:<field_id>. Time buckets: week, month, quarter. If empty, returns a single total count.

incident_typearray

filter by incident type ID (read config://organisation to discover type IDs)

max_groupsinteger

limit the number of groups returned (e.g. top 10). Check total_groups in the response to see how many existed before truncation. All groups are returned if omitted.

max_incident_ids_per_groupinteger

how many incident references (e.g. INC-123) to return per group (default 10, max 250). Set to 0 to omit IDs entirely.

modearray

filter by mode: standard, retrospective, test, tutorial

severityarray

filter by severity ID

sort_groups_bystring

order groups by: alphabetical (the default — by dimension key, so week/month/quarter come back chronological), count (highest first), or workload (highest total responder-minutes first). max_groups keeps the first N groups in the current order, so to get a true top-N (e.g. busiest teams) pass count or workload — otherwise you get an alphabetical slice that can omit the largest groups.

status_categoryarray

filter by status category: triage, active, post-incident, closed, paused, declined, merged, canceled

teamarray

filter by team IDs (exact match). Mutually exclusive with team_part_of. Use team_list to discover team IDs.

team_part_ofarray

filter by team IDs including all sub-teams in the hierarchy. Mutually exclusive with team. Use team_list to discover team IDs.

Incident Unmerge

incident_unmerge
Full Description

Reverse a merge, restoring an incident as a standalone incident.

It operates on the incident that was merged away — the source. You don't say what it was merged into: that is derived from the incident's own history. The incident is restored to the status it held before the merge, falling back to triage if it was merged straight out of triage.

Only an incident currently in a merged status can be unmerged. Anything else — active, closed, declined, never merged at all — is refused rather than changed.

Unmerging is visible to responders: the incident's channel is un-archived if the merge was recent enough, the attachments copied onto the merge target are detached again, and subscribers are notified of the status change.

Read the incident with incident_show afterwards to see which status it was restored to. To merge incidents in the first place, use incident_merge.

Parameters (1 required)
Required
incident_idstring

the incident that was merged away and should be restored (ID, external ID, or reference like INC-123). This is the source of the merge, not the incident it was merged into.

Incident Update

incident_update
Full Description

Update an incident: post a status update message, rename it, change its summary, severity or status (including pausing it), set custom fields, assign roles, or set incident timestamps. Only the fields you provide change — omitted fields are left as-is.

Set everything the user asked for in a SINGLE call: accepting an incident, setting its summary, posting a message and pausing it all go in one call.

Choose an action:

  • action "execute" (the default) applies the change directly. Use it when the user asks you to make a change or post an update, or gives the exact content. To apply a draft that was already reviewed, pass only suggestion_id — execute it verbatim, without adding fields the user didn't approve.
  • action "suggest" drafts the change for a human to accept, edit or decline. Use it when the user wants an update written or drafted rather than posted, wants your opinion on a name, or is vague ("update pls") — don't ask for clarification, just draft sensible fields. In a chat conversation the draft appears as a card; elsewhere it has no card, so show it to the user yourself and find it later with suggestion_list.
  • action "edit_suggestion" revises a draft. Pass suggestion_id and the fields to change.

An "execute" that can't be applied yet changes nothing, and comes back one of two ways. Usually a draft is made for you — accepting a triage incident with no severity or incident type, or resolving and closing, which send the user through the required-fields form — and "suggestion" carries it: relay it, don't retry. Otherwise the result names required fields that are unset and asks you to draft it, and there is no "suggestion": call again once with action "suggest", filling those fields from context rather than asking the user for them.

This tool posts a real, user-visible update and is NOT idempotent, so read "incident" on the result to tell what happened. Once it is set the change is applied: never call the tool again for that request — if part of the change didn't land, tell the user. A result without it applied nothing and doesn't count against that, whether it was rejected, drafted, or asked you to draft: act on what it says and call again at most once.

Status transitions follow the incident lifecycle:

  • From triage you can accept (move to an active status), pause, decline, resolve or close (the last two decline it). Declining is only possible from triage.
  • From active you can pause, resolve, close, cancel, or move to another active status. You can't move an active incident back to triage.
  • Pausing a triage incident works in one call — it's accepted first automatically. Don't split it into two steps.
  • A closed incident can be reopened by moving it to an active status. You can't reopen a merged or cancelled incident. A declined incident must be reopened (moved back to triage or to an active status) before any other change.

Accepting an incident requires an incident type. Incidents declared from alerts often have none, so pass incident_type_id alongside incident_status in the same call — it can only be set while still in triage.

Resolving may require custom fields: some organisations require certain fields before an incident can be resolved. Set them with custom_fields in the same call — otherwise nothing is applied and the result names the fields for you to draft with.

This tool cannot merge incidents (use incident_merge), update a status page (use status_page_update), or update an action or follow-up. To have the change decided for you rather than specified, use ask with incident_id.

Roles, severities, statuses and timestamps accept their names; read config://organisation only for the IDs you cannot see (incident types, custom fields).

Parameters (1 required, 13 optional)
Required
incident_idstring

incident to update (ID, external ID, or reference like INC-123)

Optional
actionstring

'execute' (default) applies the change directly; 'suggest' drafts it for a human to accept, edit or decline; 'edit_suggestion' revises an existing draft. An execute that can't be applied yet is drafted for you rather than refused

custom_fieldsarray

custom field values to set. Not supported on streams

incident_statusstring

status to move the incident to — a status name or ID (see config://organisation), or an intent word: 'accept' (the first active status), 'resolve', or 'close'. Prefer the intent words: 'resolve' routes to the right destination (a triage incident is declined, a required post-incident flow is entered, otherwise the incident is closed) and 'close' does the same while the incident is still active, because a required post-incident flow can only be skipped from inside it; once the incident is in the flow, 'close' asks to skip the rest of it, which needs permission and a reason. Don't name a post-incident or closed status for a resolve/close request

incident_type_idstring

incident type ID to set (see config://organisation). Can only be set while the incident is in triage. Accepting an incident requires one, so set it alongside incident_status when the incident has none

messagestring

status update message to post to the incident channel (markdown). A point-in-time note to the team, distinct from the summary. Omit when no written update is needed

namestring

new incident name

role_assignmentsarray

role assignments to set

severitystring

severity to set, by name or ID (see config://organisation). Never invent one: only set this if a severity has been explicitly stated. Not supported on streams

skip_post_incident_flow_reasonstring

why the user wants to close without completing a required post-incident flow, in their own words. Closing skips the flow's outstanding tasks, so the tool asks before doing it: leave this unset, relay the choice it gives you, and only set it once the user has confirmed and said why. Never write a reason yourself or infer one from earlier messages

suggestion_idstring

the draft to act on — required with 'edit_suggestion', and with 'execute' to post a draft that was already reviewed. Accepts an id from a suggest result, suggestion_list, or an ask call with incident_id. On an edit, omitted fields keep the draft's current values

summarystring

new incident summary (markdown). Not supported on streams

timestampsarray

incident timestamps to set or clear

unpause_atstring

RFC 3339 timestamp for when a paused incident should automatically unpause (e.g. 2026-03-20T14:30:00Z). Required when moving to a paused status, unless the incident is already paused

Incident Update List

incident_update_list
Full Description

List status updates for an incident, most recent first.

Each update shows the message, any status or severity change, and when it was posted. The update that merged the incident also includes "merged_into", the incident it was merged into. The incident_show tool returns the 5 most recent updates by default — use this tool when you need the full history.

Pagination: use page_size (default 10, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Parameters (1 required, 2 optional)
Required
incident_idstring

incident ID, external ID, or reference (e.g. INC-123, 123, or a ULID)

Optional
afterstring

cursor from a previous page to fetch the next one

page_sizeinteger

results per page (default 10, max 50)

Insights Chart Explore Url

insights_chart_explore_url
Full Description

Link to a chart of the organisation's incident.io data in Insights explore. Use this when the user asks for a chart, graph or visual of incidents, alerts, pages, follow-ups, post-incident work or on-call readiness over a period. It returns a URL, not an image or values: the chart draws when the user opens it.

Call insights_chart_options first. Use preset_key whenever a preset fits the request, and chart only for a combination that is not already a preset.

A period counted back from today, e.g. the last 12 weeks, stays relative, so the chart moves on when the user opens it later. Set start_date and end_date for fixed dates.

Link the result's url in your reply, and say what the chart shows from its summary. Don't quote numbers: this tool reads none.

Parameters (0 required, 10 optional)
Optional
aggregationstring

The bucket size for charts over time: days, weeks, months or quarters. Defaults to days up to a month, weeks up to six months, and months beyond.

chartobject

A chart to open when no preset fits as it is. Start from a preset's chart in insights_chart_options, keep its filters, and change what the user asked for. Set this or preset_key, not both.

end_datestring

The last day to cover, inclusive, as YYYY-MM-DD

filtersarray

Filters to narrow a preset's data, e.g. only one severity or team. For a chart, set them in chart.filters. Use the filters insights_chart_options lists for the measure's filter_context. A preset's own filter on the same field wins.

include_current_periodboolean

Also cover the period in progress, e.g. this week so far. Without it, 'last 4 weeks' is the four whole weeks before this one.

period_countinteger

How many whole periods to cover, counted back from the current one. Defaults to 12.

period_unitstring

The unit of period_count: days, weeks, months or quarters. Defaults to weeks. Weeks start on Monday.

preset_keystring

The key of a preset from insights_chart_options, to open it as it is. Set this or chart, not both.

start_datestring

The first day to cover, as YYYY-MM-DD. Set it with end_date for a fixed range, which replaces the period fields. Use a fixed range for the current period alone, e.g. 'this month'.

titlestring

The chart's title. Required with chart. With a preset it replaces the preset's title. A chart counts only what its filters narrow it to, so name no filter it doesn't have, e.g. high urgency.

Insights Chart Options

insights_chart_options
Full Description

List the charts this organisation can draw, for a dashboard or a single chart: ready-made presets, the measures a custom chart can plot, the filters each measure takes, and the ids of the organisation's duration metrics, custom fields, teams, alert attributes and post-incident flows.

Call it before you build a chart or a dashboard, and prefer a preset when one matches the request. When a preset is close, pass its chart, filters included, with the changes the user asked for, e.g. a different series or presentation. A preset listed without a chart has filters the agent can't set, so draw it only by its key. Tiles are for custom_dashboard_create only.

Insights Dashboard Add Chart

insights_dashboard_add_chart
Full Description

Add a chart or a trend or KPI tile to one of the organisation's Insights dashboards. Only call this when the user explicitly asks to add or save a chart to a dashboard: drawing a chart doesn't need it.

Find the dashboard with insights_dashboard_list. When it isn't clear which dashboard the user means, ask them rather than pick one.

Without a placement the chart goes in a full-width row at the bottom of the dashboard. When the user says where it goes, read the layout with insights_dashboard_show and set placement from its numbers. Match a section by its title or its number, and a row by its number or by a panel it holds. "Next to" or "in the same row as" a panel is in_row on that panel's row, which fills the row's empty space if it has some, and otherwise splits the row evenly unless the user gave a size. "Under" or "above" a section is a new section next to it, and "under" or "above" a chart is a new row next to that chart's row. When it isn't clear where the user means, ask them.

When the chart's own filters clash with those of the section or dashboard it joins, nothing is added and the result lists filter_conflicts. Explain each one to the user in plain words, offer to keep the chart's filters, use the inherited ones, or put the chart somewhere else, and wait for their answer. Never choose for them: only set on_filter_conflict to what they chose.

Call insights_chart_options first. Use preset_key whenever a preset or tile fits the request, and chart only for a combination that is not already a preset. There are no period fields: the chart covers the dashboard's own date range, so say so in your reply.

Parameters (1 required, 6 optional)
Required
dashboard_idstring

The id of the dashboard to add the chart to, from insights_dashboard_list

Optional
chartobject

A chart to add when no preset fits as it is. Start from a preset's chart in insights_chart_options, keep its filters, and change what the user asked for. Set this or preset_key, not both.

kpi_metricstring

The metric a KPI tile shows, from its kpi_metrics in insights_chart_options. Defaults to the tile's first metric.

on_filter_conflictstring

Set only after a call returned filter_conflicts and the user chose: keep_chart_filters keeps the chart's own filter on each field it shares with its section or the dashboard, which replaces theirs; use_inherited_filters drops the chart's filter on those fields, so the section's or dashboard's applies.

placementobject

Where the panel goes, by the numbers insights_dashboard_show lists. Leave it unset to add a full-width row at the bottom of the dashboard.

preset_keystring

The key of a preset or a tile from insights_chart_options, to add it as it is. Set this or chart, not both.

titlestring

The chart's title. Required with chart. With a chart preset it replaces the preset's title. Tiles have no title.

Insights Dashboard List

insights_dashboard_list
Full Description

List the organisation's custom Insights dashboards that insights_dashboard_add_chart can add a chart to, by name. Call it to find the dashboard the user means before adding a chart to it.

Parameters (0 required, 1 optional)
Optional
querystring

Words from the dashboard's name, to narrow the list

Insights Dashboard Remove Panel

insights_dashboard_remove_panel
Full Description

Remove one panel (a chart, trend or KPI tile, text or divider) from one of the organisation's custom Insights dashboards, as "Delete panel" does in the editor. Its space is left empty, a row left with nothing else goes, and so does a section left with nothing else and no title, description or filters.

Only call this when the user explicitly asks to remove or delete a panel. Find the dashboard with insights_dashboard_list and the panel with insights_dashboard_show. Match the panel the user names by its title or position, and ask them when it isn't clear which one they mean.

Never remove a panel to make space or to replace a chart: to change a chart, use insights_dashboard_update_chart.

When the result says a row or section went with the panel, tell the user. Link the result's url in your reply.

Parameters (2 required)
Required
dashboard_idstring

The id of the dashboard, from insights_dashboard_list

panel_idstring

The panel's id, from insights_dashboard_show

Insights Dashboard Show

insights_dashboard_show
Full Description

Show a custom Insights dashboard's layout: its numbered sections with their titles and filters, each section's numbered rows, and each row's columns with their widths and panels. Call it before insights_dashboard_add_chart whenever the user says where the chart goes, e.g. "in section 2", "under the Response section", "next to the MTTR chart" or "in row 3", and use its numbers for the placement.

Parameters (1 required)
Required
dashboard_idstring

The id of the dashboard, from insights_dashboard_list

Insights Dashboard Update Chart

insights_dashboard_update_chart
Full Description

Change a chart, trend tile, KPI tile or text panel already on one of the organisation's custom Insights dashboards. The panel keeps its place and size.

  • A chart: its title, description, colours, background, or chart settings such as what it measures, how it's drawn (e.g. line or stacked bar), how it's grouped and split, its statistics and its filters.
  • A trend tile: the field, metric, team grouping or flow its theme breaks down by, its filters and its background. Its theme can't change: for other trends, add a new tile.
  • A KPI tile: its metric and its background.
  • A text panel: its text, in Markdown, and its background.

Find the dashboard with insights_dashboard_list, then the panel with insights_dashboard_show, which gives each panel's id and current settings. Match the panel the user names by its title, its text or its position, and ask them when it isn't clear which one they mean. To change a chart's or a trend tile's settings, send chart or trend as insights_dashboard_show gives it with only what the user asked for changed, and check insights_chart_options for the values they accept. Leave out the settings the user didn't ask to change.

When the new filters clash with those of the panel's section or dashboard, nothing is changed and the result lists filter_conflicts. Explain each one to the user, offer to keep the panel's filters or use the inherited ones, and wait for their answer. Never choose for them: only set on_filter_conflict to what they chose.

Link the result's url in your reply.

Parameters (2 required, 9 optional)
Required
dashboard_idstring

The id of the dashboard, from insights_dashboard_list

panel_idstring

The panel's id, from insights_dashboard_show

Optional
chartobject

Charts only. The chart's new settings: what it measures, how it's drawn, how it's grouped and filtered. Start from the chart's settings in insights_dashboard_show, change only what the user asked for, and send the rest back as it is. Leave it unset to keep them.

color_palettestring

Charts only. The chart's colours: a built-in palette such as classic, alarmalade, blue, green, amber, vivid, red_green or blue_yellow, or a custom palette's id, as another chart's color_palette in insights_dashboard_show gives it

descriptionstring

Charts only. The chart's new description, shown with its title. An empty string removes it.

hide_backgroundboolean

Whether to hide the panel's card background

kpi_metricstring

KPI tiles only. The metric the tile shows, from a KPI tile's kpi_metrics in insights_chart_options

on_filter_conflictstring

Set only after a call returned filter_conflicts and the user chose: keep_chart_filters keeps the panel's own filter on each field it shares with its section or the dashboard; use_inherited_filters drops the panel's filter on those fields.

textstring

Text panels only. The panel's new content, in Markdown. It replaces the whole text, so start from the panel's text in insights_dashboard_show.

titlestring

Charts only. The chart's new title

trendobject

Trend tiles only. The tile's new settings. Start from the tile's trend in insights_dashboard_show, change only what the user asked for, and send the rest back as it is.

Insights Dashboard Update Section

insights_dashboard_update_section
Full Description

Set the title or description of a section on one of the organisation's custom Insights dashboards. Its charts, rows and filters stay as they are.

Find the dashboard with insights_dashboard_list and the section's number with insights_dashboard_show. Match the section the user names by its title or number, and ask them when it isn't clear which one they mean. Only set the fields the user asked to change.

Parameters (2 required, 2 optional)
Required
dashboard_idstring

The id of the dashboard, from insights_dashboard_list

sectioninteger

The section's number from insights_dashboard_show

Optional
descriptionstring

The section's new description, in Markdown, shown below its title. Leave it unset to keep the description, or set an empty string to remove it.

titlestring

The section's new title. Leave it unset to keep the title, or set an empty string to remove it.

Investigation Feedback

investigation_feedback
Full Description

Record a user's overall feedback on an AI investigation — whether it was helpful in responding to the incident. Feedback can only be submitted once the incident reaches a terminal state (resolved, declined, or merged).

Provide either incident_id (ID, external ID, or reference like INC-123) or investigation_id. When using incident_id, the most recent completed investigation for that incident is selected.

Set sentiment to "helpful", "not_helpful", or "not_seen" (the user didn't use the investigation). Optionally include reasons matching the sentiment, plus a freeform comment (a comment can accompany any sentiment). Valid reasons per sentiment:

  • helpful: root_cause_correct, pointed_right_direction, gathered_context, caught_something_missed, confirmed_thinking, helped_prepare_fix
  • not_helpful: not_accurate, too_late, too_frequent, missing_information, didnt_do_what_asked, already_knew
  • not_seen: already_knew, too_late, too_frequent, work_elsewhere

IMPORTANT: This submits feedback on the user's behalf. Always confirm the sentiment (and any reasons/comment) with the user before calling this tool — don't infer their verdict and submit it unprompted.

Parameters (1 required, 4 optional)
Required
sentimentstring

overall verdict on the investigation: 'helpful', 'not_helpful', or 'not_seen' (the user didn't use it)

Optional
commentstring

optional freeform comment expanding on the feedback

incident_idstring

incident ID, external ID, or reference (e.g. INC-123). Resolves to the latest investigation for this incident.

investigation_idstring

specific investigation ID to give feedback on. Use this if you already know the investigation ID.

reasonsarray

optional reasons matching the sentiment — see the tool description for the valid options per sentiment

Investigation Start

investigation_start
Full Description

Start an AI SRE investigation for an incident.

An investigation runs automated checks in the background to gather context about the incident — telemetry, recent code changes, similar past incidents — and builds a hypothesis from what it finds. Use this when you want investigation artifacts or telemetry for an incident and nothing is investigating it yet.

Pass incident_id as an ID, external ID, or reference like INC-123, exactly as investigation_steer accepts it.

Starting an investigation is visible to responders, and neither effect comes back in this result: a summary message is posted and pinned into the incident's chat channel, and the user whose credentials made the call is invited into that channel. Credentials with no user attached — an API key — start an investigation attributed to nobody, and invite nobody.

If an investigation is already running for the incident this returns started: false with that investigation's ID rather than starting a second one. Use investigation_steer to redirect its focus, or investigation_sync to download its findings.

Investigations are asynchronous: this call returns as soon as the investigation is queued, and findings appear over the following minutes.

Parameters (1 required)
Required
incident_idstring

incident ID, external ID, or reference (e.g. INC-123). Starts an investigation for that incident.

Investigation Steer

investigation_steer
Full Description

Feed information into an in-progress investigation so it re-assesses its hypothesis.

Use this when you know something the investigation doesn't — for example, the responder has identified the real cause, telemetry shows a different explanation, or the investigation is going down the wrong path.

Provide either incident_id (ID, external ID, or reference like INC-123) or investigation_id. When using incident_id, the latest investigation is selected.

The directive should explain what the investigation should focus on and why its current hypothesis may be wrong. Good directives reference the current hypothesis and explain the correction:

  • "The investigation is focused on Postgres connection pooling, but Redis connections are exhausted (100% since 14:32) — focus on Redis instead"
  • "The error started immediately after the 14:30 deploy of payment-service v2.3.1 — the investigation should look at that deploy"
  • "Ignore the Sentry errors — they're a known false positive from last week, not related to this incident"

Include evidence (telemetry results, log excerpts, etc.) and telemetry_query_ids when available — the investigation unpacks query IDs into rich artifacts with query expressions, datasource details, and explore URLs.

After steering, the investigation re-assesses its hypothesis within a few minutes (checks are debounced to coalesce rapid updates).

Parameters (1 required, 4 optional)
Required
directivestring

what the investigation should focus on and why, referencing the current hypothesis where possible. Example: 'The investigation is focused on Postgres but Redis connections are exhausted since 14:32 — focus on Redis instead'

Optional
evidencestring

supporting data as markdown — telemetry results, log excerpts, conversation context, or anything that backs up the directive

incident_idstring

incident ID, external ID, or reference (e.g. INC-123). Resolves to the latest investigation.

investigation_idstring

specific investigation ID. Use this if you already know the investigation ID.

telemetry_query_idsarray

IDs of telemetry queries from ask_telemetry calls. These are unpacked into artifacts with query expressions, datasource info, and explore URLs.

Investigation Sync

investigation_sync
Full Description

Download an investigation as a tar.gz archive containing the full investigation filesystem.

Provide either incident_id (ID, external ID, or reference like INC-123) or investigation_id. When using incident_id, the latest investigation is selected.

The archive contains markdown files describing the investigation: findings, checks, incident context, conversation history, and more.

Optionally pass since (a timestamp) to include a preamble showing what changed since that time — useful for polling an in-progress investigation.

Returns a signed URL valid for 15 minutes.

Parameters (0 required, 3 optional)
Optional
incident_idstring

incident ID, external ID, or reference (e.g. INC-123). Resolves to the latest investigation for this incident.

investigation_idstring

specific investigation ID to download. Use this if you already know the investigation ID.

sincestring

if provided, includes a preamble showing what changed since this time (RFC 3339 or any common date format)

Maintenance Window Alerts

maintenance_window_alerts
Full Description

Count the alerts a maintenance window held.

Returns how many alerts the window held, how many of those are still firing versus resolved, and when it last held one. Use it to measure what a window suppressed.

stats is omitted when the window has held nothing yet. Take the window ID from maintenance_window_list.

Parameters (1 required)
Required
maintenance_window_idstring

required,the window's ID\, from maintenance_window_list

Maintenance Window Create

maintenance_window_create
Full Description

Schedule a maintenance window: a period where matching alerts are held back instead of paging anyone.

This stops real pages for real people. Say what will be held and for how long, and get agreement, before calling it.

Which alerts: alert_source_ids says which sources the window holds. Resolve names to IDs with alert_source_list first. At least one is required — a window cannot hold every alert in the organisation, so a request to mute everything needs the sources naming.

Times must be UTC RFC 3339 ending in Z. Never convert a wall-clock time to UTC by writing an offset yourself: daylight saving shifts offsets and the window lands on the wrong hours.

Filters beyond alert source, escalation overrides, notification channels and start or end reminders are dashboard-only. Say so rather than approximating them.

Returns the created window, whose ID maintenance_window_update and maintenance_window_delete take.

Parameters (4 required, 3 optional)
Required
alert_source_idsarray

required,hold alerts from these sources (IDs from alert_source_list). At least one is required: a window always names the sources it holds

end_atstring

required,when the window ends\, UTC RFC 3339 ending in Z. Same rules as start_at

namestring

required,what the maintenance is\, e.g. "Database upgrade". Shown to everyone whose alerts it holds

start_atstring

required,when the window starts\, UTC RFC 3339 ending in Z (e.g. 2026-08-25T14:00:00Z). Never write a local UTC offset yourself — resolve wall-clock times to UTC first

Optional
incident_idstring

attach the held alerts to this incident

leadstring

who is leading the maintenance: a person's name or user ID. Defaults to the caller

resolve_on_endboolean

resolve the held alerts when the window ends\, rather than letting them route. Defaults to false

Maintenance Window Delete

maintenance_window_delete
Full Description

Cancel a maintenance window that has not started.

Only an upcoming window can be cancelled. To stop a window that is already running, use maintenance_window_update with end_now.

Take the window ID from maintenance_window_list.

Parameters (1 required)
Required
idstring

required,the window's ID\, from maintenance_window_list

Maintenance Window List

maintenance_window_list
Full Description

List maintenance windows by status.

A maintenance window holds alerts matching a filter for a fixed period, instead of routing them to whoever is on call.

Returns each window's ID, name, status, lead, time range, linked incident and how many alert filter condition groups it carries. The ID is what maintenance_window_update, maintenance_window_delete and maintenance_window_alerts take.

status defaults to active. Pass "upcoming" for windows that start later, "past" for ended ones. Ordered by start time, most recent first, and capped at 10: has_more reports windows beyond the cap.

Parameters (0 required, 1 optional)
Optional
statusstring

which windows to return: active (in effect now)\, upcoming (starts later) or past (already ended). Defaults to active,enum=active,enum=upcoming,enum=past

Maintenance Window Update

maintenance_window_update
Full Description

Change a maintenance window's name, lead or times, or end an active one now.

Pass only the fields to change; the rest keep their values. Take the window ID from maintenance_window_list.

Set end_now to stop an active window immediately, which is how you unmute alerts early. To cancel a window that has not started, use maintenance_window_delete.

Refusals: a window that has ended cannot be changed; an active window's start time cannot move; no time can move into the past; the end cannot precede the start; end_now works only on an active window.

Parameters (1 required, 5 optional)
Required
idstring

required,the window's ID\, from maintenance_window_list

Optional
end_atstring

a new end time\, ISO 8601 (e.g. 2025-01-20T17:00:00Z)

end_nowboolean

end an active window immediately

leadstring

a new lead: a person's name or user ID. Use "me" for the caller

namestring

a new name for the window

start_atstring

a new start time\, ISO 8601 (e.g. 2025-01-20T14:00:00Z)

Nexus Health Show

nexus_health_show
Full Description

Show the health of the AI data sources the organisation has connected — the same view the dashboard's health page computes.

Each data source (telemetry, code, documents, catalog, past incidents, messages) gets a setup status (healthy, setting_up, or not_connected) and usage counts: how many distinct chats and investigations drew on it over the reported window. The telemetry and code sources break down further into per-datasource children — telemetry children carry query outcome stats (total, with data, failed, empty, cited) and attention_reasons naming what needs a human (needs_reconnection, low_success_rate, always_empty, no_active_memories, stale_guidance).

Use this when assessing whether the organisation's AI setup is working: which sources are connected but unused, which telemetry datasources are failing or never return data, and where usage concentrates. For the telemetry datasource inventory (capabilities and connection status, including disabled sources), read telemetry://datasources; for MCP and HTTP connectors, use extension_connector_list.

Health is only computed for organisations that can use investigations; otherwise data_sources is empty and message says why.

Notification Pause Create

notification_pause_create
Full Description

Pause someone's on-call notifications for a window: while the pause is active, escalations skip them instead of paging them.

This stops real pages reaching a real person. Say whose notifications will be paused, from when until when, and get agreement before calling it. Never invent an end time the user didn't give you: ask.

A pause doesn't take anyone off a rotation. Their shifts still show as theirs; we just skip them when we would otherwise page them. If they want someone to take their shift, that's cover_request_create (asks for volunteers) or schedule_override_create (changes who is on call). Say so rather than approximating it with a pause.

user_id defaults to the caller. Pausing anyone else needs the notification_pauses.manage_all permission. Requires user authentication (e.g. OAuth) rather than an API key.

Times must be UTC RFC 3339 ending in Z. Never convert a wall-clock time to UTC by writing an offset yourself: daylight saving shifts offsets and the pause lands on the wrong hours. A pause can last at most 6 months, and cannot end in the past.

A person's pauses can't overlap. If one already covers part of the window, extend or move it with notification_pause_update instead. Back-to-back pauses are fine.

Returns the created pause, whose ID notification_pause_update, notification_pause_resume and notification_pause_delete take.

Parameters (1 required, 3 optional)
Required
ends_atstring

when paging resumes, as UTC RFC 3339 ending in Z (e.g. 2026-08-26T09:00:00Z)

Optional
reasonstring

why they are pausing, shown to their teammates (e.g. "On holiday")

starts_atstring

when to stop paging them, as UTC RFC 3339 ending in Z (e.g. 2026-08-25T14:00:00Z); defaults to now

user_idstring

whose notifications to pause: a user ID, or "me" for the caller (the default)

Notification Pause Delete

notification_pause_delete
Full Description

Cancel an upcoming notification pause, so it never takes effect. Say whose pause you are cancelling and get agreement before calling it.

This refuses a pause that is active now: end that with notification_pause_resume, which keeps a record of the pause. To end a pause at a later time, move its ends_at with notification_pause_update instead.

You can cancel your own pauses. Cancelling anyone else's needs the notification_pauses.manage_all permission. Requires user authentication (e.g. OAuth) rather than an API key.

Take the pause ID from notification_pause_list.

Parameters (1 required)
Required
pause_idstring

the pause's ID, from notification_pause_list

Notification Pause List

notification_pause_list
Full Description

List notification pauses: windows in which someone's on-call notifications are paused, so escalations skip them instead of paging them.

Use this for "am I paused?", "is anyone on the platform rota paused this week?", and to find the pause ID that notification_pause_update, notification_pause_resume and notification_pause_delete take.

Only current and upcoming pauses are returned unless you pass from. Pass user (a user ID, or "me" for the caller) for one person's pauses, and schedule_id for everyone on a schedule over the window. Each pause carries a status: active means we would skip that person if they were paged right now.

A pause doesn't change the rota: someone who is paused still shows as on call in schedule_show.

Parameters (0 required, 4 optional)
Optional
fromstring

only pauses still in effect after this time, RFC 3339 (e.g. 2026-08-25T00:00:00Z); defaults to now

schedule_idstring

only pauses for people with a shift or override on this schedule during the window

tostring

only pauses starting before this time, RFC 3339; defaults to a week after from with schedule_id, otherwise no limit

userstring

a user ID, or "me" for the caller, to list only that user's pauses

Notification Pause Resume

notification_pause_resume
Full Description

End an active notification pause now, so that person can be paged again. The pause is kept, ending at the time it was resumed, so schedules still show when they were paused.

Resuming means that person may start getting paged again straight away. That's fine during their working hours and a nasty surprise at 3am. Say whose pause you are resuming and get agreement before calling it.

Only for a pause that is active now. To drop an upcoming pause, use notification_pause_delete. To end a pause at a later time, move its ends_at with notification_pause_update.

You can resume your own pauses. Resuming anyone else's needs the notification_pauses.manage_all permission. Requires user authentication (e.g. OAuth) rather than an API key.

Take the pause ID from notification_pause_list. Returns the resumed pause.

Parameters (1 required)
Required
pause_idstring

the active pause's ID, from notification_pause_list

Notification Pause Update

notification_pause_update
Full Description

Change a notification pause's window or reason, such as extending a holiday or coming back a day early.

Pass only what changes: omitted fields keep their current value. The pause stays with the same person.

Moving ends_at earlier resumes pages sooner, and moving starts_at later lets pages through until then. Say the new window and get agreement before calling it. To end an active pause right now, use notification_pause_resume instead: ends_at cannot be in the past.

Times must be UTC RFC 3339 ending in Z. Never convert a wall-clock time to UTC by writing an offset yourself. A pause can last at most 6 months, and can't overlap another of the same person's pauses.

You can change your own pauses. Changing anyone else's needs the notification_pauses.manage_all permission. Requires user authentication (e.g. OAuth) rather than an API key.

Returns the updated pause.

Parameters (1 required, 3 optional)
Required
pause_idstring

the pause's ID, from notification_pause_list

Optional
ends_atstring

new end as UTC RFC 3339 ending in Z; omit to keep the current one

reasonstring

new reason shown to teammates; omit to keep it, or pass an empty string to clear it

starts_atstring

new start as UTC RFC 3339 ending in Z; omit to keep the current one

Resource List

resource_list
Full Description

List all available resources. Resources provide context that helps you use the other tools effectively — organisation config, analysis playbooks, telemetry datasources, and more. Use resource_show to read a specific resource by name.

Resource Show

resource_show
Full Description

Read a resource by name. Resources provide context that helps you use the other tools effectively. This tool returns the same content as the MCP resources, for clients that don't support the resources protocol.

Use resource_list to see all available resources, or pass one of these names:

  • alert_noise_playbook: Playbook for deep alert noise analysis. Identifies noisy sources, quantifies noise cost in responder time, and produces specific tuning recommendations.
  • analysis_playbook: Index of all analysis playbooks. Describes which playbook to use for different questions (operational review, alert noise, on-call burden, team health, response effectiveness). Read this first to pick the right playbook.
  • metrics_glossary: Glossary of derived metrics used across playbooks: workload ratios, alert quality scores, escalation rates, and lifecycle timings. Includes formulas, interpretation guidance, and source tools.
  • on_call_burden_playbook: Playbook for assessing on-call sustainability. Analyses paging volume, ack rates, overnight burden, and workload distribution across people and teams.
  • onboarding_context: datasource summaries and recent successful telemetry queries
  • operational_review_playbook: Playbook for periodic operational reviews (weekly/monthly/quarterly). Covers incident volume, alert noise, paging load, responder burden, and follow-up health in one comprehensive analysis.
  • organisation: incident statuses, severities, roles, types, custom fields, alert priorities — discover IDs for filtering
  • presenting_results_guide: Guide for structuring and formatting analysis findings. Covers output structure, formatting conventions, and the branded HTML report template.
  • response_effectiveness_playbook: Playbook for measuring response effectiveness: detection speed, resolution time, escalation response, and post-incident learning outcomes.
  • scope_playbook: How to establish analysis scope with the user before running a playbook. Covers goal, time window, team/org scope, comparison periods, audience, and output format. Run this first.
  • team_health_playbook: Playbook for per-team or cross-team operational health assessment. Combines incident, alert, and escalation data scoped to a team.
  • telemetry_datasources: connected observability platforms and their capabilities
Parameters (1 required)
Required
resourcestring

which resource to read — a resource_list name (e.g. "organisation") or its URI (e.g. "config://organisation")

Schedule List

schedule_list
Full Description

List on-call schedules with optional search, user filter, and pagination.

Schedules define who is on call and when. Each result shows who is currently on call and how many rotations the schedule has.

Pass user (a user ID, an email address, or "me" for the caller) to answer "am I on call?" and "when am I next on call?" in one call: results narrow to schedules that user is on, and each carries the user's in-progress shift (when they are on call right now) and their next shift, looking ahead 3 months.

Use schedule_show for full details: rotation configuration, shifts over a chosen time window (past included), and when the next handover happens. List results carry no handover time.

Only native incident.io schedules are returned. When the organisation manages on-call in an external provider (e.g. PagerDuty, Opsgenie), an empty result carries a note saying so — that means we cannot see who is on call, not that nobody is.

Pagination: results are ordered by name. Use page_size (default 15, max 50) and pass "next_cursor" as "after" to fetch subsequent pages. Stopping before "has_more" is false means you have incomplete results.

Parameters (0 required, 4 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

page_sizeinteger

results per page (default 15, max 50)

querystring

search schedule names

userstring

a user ID, an email address, or "me" for the caller: only schedules this user is on, each carrying their current and next shift

Schedule Override Create

schedule_override_create
Full Description

Create a schedule override, placing a user on call (or clearing the schedule) for a time period.

An override changes who gets paged, immediately and for real — state what will change and get agreement before calling this. Use user_id "NOBODY" to clear the schedule for the window, and "me" for the caller.

rotation_id and layer_id are optional for simple schedules where only one rotation and layer have shifts in the window. If the schedule has multiple rotations or layers, the call is rejected until you pass both — read them from schedule_show's rotation configuration.

Times must be UTC RFC 3339 ending in Z. Never convert a wall-clock time to UTC by writing an offset yourself — daylight saving silently shifts offsets and the override lands on the wrong instant.

Returns the created override, whose ID is what schedule_override_delete takes to undo it.

Parameters (4 required, 2 optional)
Required
end_atstring

override end as UTC RFC 3339 ending in Z. Same rules as start_at

schedule_idstring

schedule ID (ULID), not the name

start_atstring

override start as UTC RFC 3339 ending in Z (e.g. 2026-08-25T14:00:00Z). Never attach a local UTC offset — resolve wall-clock times to UTC first

user_idstring

user to place on call. Use "me" for the caller, or "NOBODY" to clear the schedule for the window

Optional
layer_idstring

layer within the rotation; required when the rotation has several layers

rotation_idstring

rotation to override; required when the schedule has several rotations with shifts in the window (schedule_show carries rotation IDs)

Schedule Override Delete

schedule_override_delete
Full Description

Delete a schedule override, restoring the underlying rotation for its window.

Use this to undo an override created by mistake or no longer needed. Deleting an override changes who gets paged for its window, so confirm before calling. Override IDs come from schedule_override_create's result, or from the override_id field on shifts in schedule_show.

Parameters (1 required)
Required
override_idstring

the override's ID — from schedule_override_create's result, or the override_id on shifts in schedule_show

Schedule Show

schedule_show
Full Description

Look up an on-call schedule by ID and return its full details and shifts.

Returns: name, timezone, rotation configuration, and shifts for the requested window (default: now to 7 days ahead). Pass "from"/"until" to move the window — including into the past, for questions like "who was on call last Tuesday night?". Each rotation includes its users, handover frequency, working hours, current shift end, and next shift start.

When the window includes the current time, each rotation reports "current_shift_ends_at" and "next_shift_starts_at". Equal values mean someone takes over at that instant. Different values show a coverage gap. A missing current end means the rotation is not covered now; a missing next start means nothing is scheduled within the window.

Shifts created by an override carry an "override_id" — that ID is how an override is targeted later — and "original_user_id"/"original_user_name", naming who the override took the shift from, so you can answer "who is Ana covering for?" without reading the rotation yourself. "shifts_truncated": true means the window held more shifts than one response carries; narrow the window for the rest.

Pass include: ["holidays"] to get the time off booked by anyone this schedule can put on call, over the same window. That answers "is anyone on call while they are away?" in one call, since the shifts are in the same response.

Use this to answer questions like "who's on call for the backend schedule?", "what does the rotation look like?", "when does the next handover happen?", "who is on-call next week?", or "who was on call during the incident?"

To see who would actually get paged when an alert fires, use escalation_path_show — it resolves schedules to current on-call users at each escalation level.

Only native incident.io schedules are accessible. A schedule imported from an external provider (e.g. PagerDuty, Opsgenie) returns not-found — that means we cannot read it, not that it doesn't exist.

Parameters (1 required, 3 optional)
Required
idstring

schedule ID (ULID)

Optional
fromstring

start of the shift window (RFC 3339, e.g. 2026-08-01T00:00:00Z); defaults to now. May be in the past to read shift history

includearray

optional sections to include: holidays

untilstring

end of the shift window (RFC 3339); defaults to 7 days after from. The window may span at most 90 days

Status Page Update

status_page_update
Full Description

Draft an update to a public status page for an incident: the next update when it is already published, or the first update, which publishes it to one of your existing status pages.

This tool only drafts. The draft is posted as a card into the conversation this call arrived from, and only a human can publish it — publishing emails or texts everyone subscribed to the page. Never tell the user an update has gone out. A caller who cannot show a publishable card is refused and told where to go instead, because a draft nobody can publish could never go live.

Action "suggest" (the default) drafts the update; "edit_suggestion" (with suggestion_id) revises an existing draft, and any field you omit keeps the draft's value. "execute" (publishing directly) is not supported yet and is refused.

For a first publish (the incident isn't on a status page yet): name is required, components must come from the page's own list, and if the organisation has more than one page the error lists them — ask the user, then pass status_page_id. When the incident is already on more than one page, pass status_page_incident_id the same way.

Write the message for customers reading the status page: lead with what they are experiencing, then what is being done about it, in plain prose that follows on from the previous updates — no internal jargon, no responder names, no incident IDs, no severity names, no internal links. Never speculate on cause, and never promise a fix time you can't evidence.

to_status moves the status page incident: investigating (something is wrong, cause unknown), identified (cause known, fix in progress), monitoring (fix applied, watching it hold), or resolved (impact over, and you're confident it is over). Keep the current status unless the evidence supports moving; moving backwards is fine when a fix didn't hold — say so in the message. For an update, only components already affected by this incident may move; resolving forces every affected component to operational.

Parameters (2 required, 7 optional)
Required
incident_idstring

incident to draft the status page update for (ID, external ID, or reference like INC-123)

messagestring

the update to publish, as markdown, written for customers reading the status page

Optional
actionstring

'suggest' (default) drafts the update for a human to review and publish; 'edit_suggestion' revises an existing draft. 'execute' (publish directly) is not supported yet and is refused

component_statusesarray

status per affected component. For an update, only components already affected by this incident are accepted; for a first publish, only components on the page

namestring

customer-facing title for the new status page incident. Required for a first publish; ignored when updating

status_page_idstring

which status page to publish to, for a first publish. Only needed when the organisation has more than one, in which case a previous call will have listed the options

status_page_incident_idstring

which status page incident to update. Only needed when this incident is on more than one status page, in which case a previous call will have listed the options. An edit reuses the draft's own page

suggestion_idstring

the draft to revise, required with action 'edit_suggestion' — accepts an id from a suggest result, suggestion_list, or an ask call with incident_id; omitted fields keep the draft's current values

to_statusstring

status the status page incident moves to: investigating, identified, monitoring, or resolved. Omit to keep its current status

Suggestion List

suggestion_list
Full Description

List AI suggestions — drafts awaiting human action — with optional filters and pagination.

A suggestion is a draft the AI produced that a human accepts, edits, or declines: an incident update, summary, follow-up, escalation, or status page update. Each result carries the full drafted content (the same shape ask returns when called with incident_id), so no separate show call is needed.

Statuses:

  • pending: awaiting action — these are the live drafts
  • accepted / accepted_with_edits / declined: a human actioned it
  • overridden: superseded by a newer suggestion or a manual update
  • auto_applied: applied automatically on the org's behalf

Filters (all optional):

  • incident_id: filter to a specific incident (accepts ID, external ID, or reference like INC-123). Suggestions without an incident are org-scoped and only appear when this filter is unset.
  • suggestion_type: one or more of update, summary, follow_up, escalation, status_page
  • status: one or more of the statuses above. Use status: ["pending"] to find live drafts — e.g. to check for an existing draft before creating another, or to find a draft's ID to edit.
  • source: one or more of copilot (chatbot-drafted), copilot_edit, incident_activity, incident_update, generate_button_slack, generate_button_dashboard, request_update, orchestrator

Pagination: results are ordered newest first. Use page_size (default 10, max 50) and pass "next_cursor" as "after" to fetch subsequent pages.

To apply a pending draft, pass its id as suggestion_id with action "execute" to the tool that drafted it. Applying is real — an accepted escalation pages someone — so show the draft to a human first. Status page drafts cannot be applied this way: a human publishes them from the dashboard or Slack.

Parameters (0 required, 6 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

incident_idstring

filter to a specific incident (ID, external ID, or reference like INC-123)

page_sizeinteger

results per page (default 10, max 50)

sourcearray

filter by how the suggestion was generated, e.g. copilot, incident_activity

statusarray

filter by status: pending, accepted, accepted_with_edits, declined, overridden, auto_applied

suggestion_typearray

filter by type: update, summary, follow_up, escalation, status_page

Team List

team_list
Full Description

List teams with optional name search.

Teams are catalog entries of the organisation's configured team type. Each team owns resources like escalation paths, alert sources, and schedules — use team_show to see a specific team's owned resources.

Use this tool to discover teams when scoping analysis (e.g. "which teams exist?") or to find a team by name. Pass a query to filter by name substring.

Parameters (0 required, 3 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

page_sizeinteger

results per page (default 25, max 50)

querystring

search team names (case-insensitive substring match)

Team Show

team_show
Full Description

Look up a team by ID and return its details with all owned resources.

Returns the team name and its owned escalation paths, alert sources, schedules, and alert routes. Use these resource IDs as filters when scoping analysis to a specific team:

  • Escalation path IDs → escalation_stats(escalation_path: [...])
  • Alert source IDs → alert_stats(alert_source: [...])

Use team_list to find team IDs, or check config://organisation for your own team.

Parameters (1 required)
Required
idstring

team ID (the catalog entry ID for the team)

Telemetry Inspect

telemetry_inspect
Full Description

Inspect one telemetry datasource to see the real labels, label values and metric names that exist on it, so a query you author references things that actually exist.

Run it before executing a verbatim expression via ask_telemetry's passthrough input. This goes a level deeper than the telemetry://datasources resource: that resource lists which sources exist and their capabilities; this tool looks inside a single source you already have an ID for.

Pass a datasource_id from telemetry://datasources, then pick a kind based on that source's capabilities:

  • capability "logs" → kind="log_labels", target=<stream selector> — list the label names on matching streams (set label=<name> to list that label's values). The result's syntax_hint gives the selector syntax and how to list everything when you don't know a label yet.
  • capability "metrics" → kind="metric_labels", target=<metric name> — list the labels on a metric (set label=<name> to list its values).
  • capability "metrics" → kind="metric_search", target=<keyword> — find metric names containing that keyword, e.g. http. The result's syntax_hint says whether finer regex matching is supported.

If a source's capabilities (in telemetry://datasources) don't include the one a kind needs, that kind isn't supported for it.

Parameters (3 required, 2 optional)
Required
datasource_idstring

the telemetry datasource to inspect (an ID from telemetry://datasources)

kindstring

what to inspect: log_labels (a source with the logs capability), metric_labels or metric_search (a source with the metrics capability)

targetstring

the anchor to inspect — log_labels: a selector for the streams to inspect, in this datasource's selector language; the result's syntax_hint gives the exact syntax and how to list everything when you don't yet know a label (active=false means the selector matched nothing — it does not say whether the label name or value was wrong); metric_labels: a metric name; metric_search: a keyword to find in metric names, e.g. http (the result's syntax_hint says whether finer regex matching is supported)

Optional
filterstring

log_labels & metric_labels values mode only: case-insensitive substring filter ("-", "_", "." treated as equivalent)

labelstring

log_labels & metric_labels only: omit to list the label names on the target; set to a label name to list that label's values

Time Spent Stats

time_spent_stats
Full Description

Break down the time responders spent working on incidents, grouped by who spent it, by time bucket, or by a custom field.

Use this to answer workload-by-person questions — "responder hours by person last quarter", "who carried the most overnight load?". Each group returns the total responder-hours spent working on incidents, split by the time of day the work happened in the responder's local time — working hours, late evening, and overnight — so you can see out-of-hours burden. It also returns the number of distinct responders in the group.

Group by (combine at most two):

  • user: the responder who did the work
  • week / month / quarter: time bucket
  • custom_field:<field_id>: a custom field's values (read config://organisation to find field IDs)

This tool sources the per-responder hourly workload table, so it can attribute time to individual people — which incident_stats cannot. It counts time spent within the active_after/active_before window (when the work happened, not the incident's creation date), matching the time-spent Insights dashboard. To break this time down by severity, team, type or other incident attributes, use incident_stats instead — it sums whole-incident workload from the per-incident rollup.

Workload is synced hourly and may be absent for very recent activity.

Parameters (0 required, 12 optional)
Optional
active_afterstring

count time spent on or after this date (yyyy-mm-dd or RFC 3339). Defaults to 12 weeks before active_before.

active_beforestring

count time spent before this date (yyyy-mm-dd or RFC 3339). Defaults to now.

custom_fieldsobject

filter by custom field values: keys are custom field IDs, values are arrays of accepted value IDs

group_byarray

how to group the time responders spent working on incidents. Options: user (who spent the time), week/month/quarter (time bucket), custom_field:<field_id>. Combine at most two, e.g. ["user", "month"]. If empty, returns a single total. To break this time down by severity, team or type instead, use incident_stats — it groups whole-incident workload by any incident attribute.

incident_typearray

filter by incident type ID (read config://organisation to discover type IDs)

max_groupsinteger

limit the number of groups returned (e.g. top 10). Check total_groups to see how many existed before truncation. All groups are returned if omitted.

modearray

filter by mode: standard, retrospective, test, tutorial

severityarray

filter by severity ID

sort_groups_bystring

order groups by: alphabetical (the default — by dimension key, so time buckets come back chronological), or workload (highest total responder-hours first). max_groups keeps the first N in the current order, so for a true top-N (e.g. busiest responders) pass workload.

status_categoryarray

filter by status category: triage, active, post-incident, closed, paused, declined, merged, canceled

teamarray

filter by team IDs (exact match). Mutually exclusive with team_part_of. Use team_list to discover team IDs.

team_part_ofarray

filter by team IDs including all sub-teams in the hierarchy. Mutually exclusive with team. Use team_list to discover team IDs.

User List

user_list
Full Description

List users in the organisation. Use this to find user IDs for filtering (e.g. incident_list assigned_to), assigning follow-ups, or looking someone up by name or email.

Filters (all optional):

  • query: name or email substring (case-insensitive). Matched against email if the value contains "@", otherwise against display name and real name. e.g. "hannah", "hannah@incident.io".
  • email: exact email match. Use when you have the full address.
  • seat_type: on_call, responder, on_call_responder, viewer.
  • include_inactive: include deactivated or not-yet-active users (default false). Useful when looking up someone mentioned in an older incident who has since left.

To resolve "me" to your own user ID, read config://organisation — the "You" section contains your ID. user_list is for discovering other users.

Parameters (0 required, 6 optional)
Optional
afterstring

cursor from a previous page to fetch the next one

emailstring

exact email match (case-insensitive). Use this when you know the full address; use query for substring search.

include_inactiveboolean

include deactivated or not-yet-active users (default false). Useful for finding users mentioned in older incidents who have since left.

page_sizeinteger

results per page (default 25, max 50)

querystring

search by name or email (case-insensitive substring). If the value contains @, matched against email; otherwise against display name and real name.

seat_typestring

filter by seat: on_call, responder, on_call_responder, viewer