- Brand
- incident.io
- Category
- Operations
- Primary Subcategory
- Pending
Integration details
Description
Makes your agent fluent in incident.io: responding to and investigating incidents, working with on-call schedules and escalations, and authoring the operational content — runbooks, skills, and plugins — that incident.io investigations draw on. Bundles the official incident.io MCP server.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Pending
- Secondary Subcategories
- None listed
- Brand
- incident.io
- Access
- Account required
- First tracked
- 2026-10-08
- Tool count
- 108
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your score is coming
ChatGPT now suggests Plugins on its own when they match a user's request.Your Plugin Discovery Score measures how often yours appears, and it will show here as soon as it’s ready.
What discovery looks like

Get alerts for incident.io
Get updates when incident.io’s Discoverability Score or category rank changes.
Competitive lineup
108 tools agents can invoke
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.
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.
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.
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.
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.
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.
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.
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?"
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.
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.
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.
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.
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.
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.
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.
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.
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.).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
incident.io ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve incident.io's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.