Prerequisites
- A git repository connected to your workspace, with the GitHub App installed so the agent can open pull requests.
- Slack connected, and a channel for the agent’s summaries with the Paradime bot invited.
- The Admin, Workspace Admin, or Developer role, to create incoming webhooks.
- In incident.io: admin access to Settings → MCP and Settings → Webhooks, and a service account for the agent to connect as.
- Familiarity with programmable agents and external MCP servers.
Steps
1
Connect the incident.io MCP server
incident.io runs a remote MCP server at
https://mcp.incident.io/mcp (incident.io: Remote MCP server). It uses the standard MCP OAuth flow with automatic client registration, which is what Paradime expects.In incident.io:- Turn the server on under Settings → MCP.
- Under Settings → MCP server → Allowed redirect domains, add the host you open Paradime at, for example
app.paradime.io. incident.io trusts a few AI clients automatically; any other client’s redirect host must be allowed first, or authorization fails. Paradime’s redirect URI ishttps://<your Paradime host>/mcp-client/callback.
- Go to Settings → Integrations, find MCP Servers, and select Add MCP Server.
- Server URL:
https://mcp.incident.io/mcp. Display name:incident.io. The display name sets the tool prefix, so the agent’s tools are namedmcp__incident_io__<tool>. - Authentication: OAuth 2.1. Leave Client ID empty.
- Select Connect & Authorize. Sign in as the service account. Choose Read and write if the agent should update incidents, or Read only for a first test.
- The server’s page lists its tools. Turn off any the agent should never have, such as the ones that create incidents or change who is on call.
Paradime connects to MCP servers over Streamable HTTP with OAuth or no auth. The API key that incident.io offers for automation is sent as a header, which Paradime can’t configure for an MCP server, so OAuth is the route here.
2
Add a skill for each type of incident
The agent’s goal says how to triage. The detail for each failure type lives in a skill, so the team can add a new type without touching the agent. DinoAI discovers skills from Add
.claude/skills/<name>/SKILL.md in the repository and loads one only when its description matches the task.Commit one skill per incident type. This one covers a failed dbt™ model or test:.claude/skills/incident-dbt-failure/SKILL.md
incident-airflow-failure, incident-data-quality, and so on the same way. Keep each description specific: it is the only thing DinoAI reads to decide whether to load the skill.The agent can only change code in the repository connected to the workspace. For a failure in a system whose code lives elsewhere, write the skill as report only: diagnose, name the system and the owner, and stop.
3
Create the agent
In the Agent app, open Agents, select New agent, and fill in the builder with the content below. See Build an agent in the UI for a tour of the builder. Select Deploy and choose Open a pull request to keep the agent as code under Goal:Backstory:Allowed tools:
.dinoai/agents/on-call-agent.yml.Name: on-call-agentRole:load_skill_instructions, get_bolt_run_logs, list_bolt_schedules, retry_bolt_run, run_sql_query, get_sql_query_result, run_terminal_command, write_file, edit_file, get_lineage, get_node_details, get_model_health, get_column_level_lineage, post_slack_message, and under the incident.io group, All incident.io tools. Narrow the incident.io tools to the ones the agent uses once you have seen a few sessions.Output: your Slack channel, answer in thread, updates Final.The same agent as YAML:.dinoai/agents/on-call-agent.yml
retry_bolt_run is available only because the allowlist names it. Remove it if the agent must never retry. Skills load only when load_skill_instructions is in the allowlist.4
Create the Bolt schedule and its Trigger URL
Create a Bolt schedule with one command, Run Paradime DinoAI Agent (Triggering from Bolt):The file doesn’t create the Trigger URL. After you deploy, open the schedule in Bolt and create it in the Trigger URLs card.
-
Agent name:
on-call-agent. -
Task: Paradime adds the webhook body after this message, so refer to it by name:
- Select Save command.
-
Under Trigger type, select Incoming webhook. In the Trigger URLs card, select New Trigger URL, name it
incident.io, and select Create. Copy the URL. The secret shows only once, but you won’t need it after the next step. - Select Deploy.
paradime_schedules.yml
5
Point incident.io at the Trigger URL
incident.io delivers its webhooks through Svix and signs each one with
webhook-id, webhook-timestamp and webhook-signature headers (incident.io: Webhooks). Paradime verifies that scheme as the Standard Webhooks sender.In incident.io, go to Settings → Webhooks and create an endpoint with the Trigger URL. Subscribe it to public_incident.incident_created_v2. Copy the endpoint’s signing secret, which starts with whsec_.In Paradime, on the Trigger URL:- Select Auth.
- Sender: Standard Webhooks.
- Signing secret: paste the
whsec_secret. Select Save.
webhook-id, so a Svix retry can’t start a second run. See Authenticate the sender.Subscribe to one event to start.
public_incident.incident_status_updated_v2 starts a run on every status change, which is rarely what you want for an investigating agent.6
Filter which incidents start a run
incident.io sends every incident to the endpoint. On the Trigger URL, select Filter, choose all conditions match, and add conditions on body fields (Filter which deliveries start a run). The incident sits under a key named after the event, so the paths are:
Team and service are custom fields, under
custom_field_entries in the same object. Open a test incident first, then pick the path from the field suggestions in the Filter dialog, which come from recent deliveries. Check recent deliveries shows which of the last 20 would run.7
Test with a real incident
Send test request in Bolt starts a run with no body, which proves the trigger but not the payload. Open a test incident in incident.io that matches your filter, then check:
- Bolt → Webhooks → Incoming: the delivery, and whether it ran, was skipped, or was filtered out.
- The run page says Triggered by an incoming webhook, and the agent’s messages stream into the run log.
- Agent sessions, under the Bolt source, with every tool call.
- Slack: the agent’s thread in your channel.
- incident.io: the update the agent left on the incident.
For a test incident with a deliberate dbt™ error, the agent posts a Slack summary with the incident reference, the class, the root cause and a pull request link, and the same text appears on the incident’s timeline. If nothing starts, open Bolt → Webhooks → Incoming: Skipped with “Did not match the filter” means the filter paths are wrong, and no delivery at all means the signing secret or the URL in incident.io is wrong.
What the agent receives
Paradime adds the request body after the task in a<webhook_payload> block, marked as data from outside Paradime that the agent must not follow as instructions (Run an agent from a webhook). For an incident created event the useful fields are:
Private incidents send only the
id. The goal above tells the agent to fetch the rest with incident_show, so both cases work. Anyone who can open an incident can put text in these fields, so every instruction lives in the task and the goal, and the agent gets only the tools it needs.
How it works
- A Bolt run waits up to 1 hour for the agent. A longer investigation keeps going, but the run shows as failed. Keep the skills focused.
- Up to 5 runs of the schedule at once. A sixth request is skipped, not queued. A burst of incidents from one outage needs grouping in incident.io first.
- If your observability tools are connected to incident.io Investigations, the same MCP server exposes their logs and metrics to the agent, so the links in the incident become something the agent can follow.
Next steps
Run an agent from a webhook
The general pattern this recipe builds on, with Jira as the sender.
Send failures to your incident tools
The other direction: a failed Bolt run opens the incident in incident.io.
Incoming webhooks reference
Senders, filters, responses, deliveries, and limits.
Connect external MCP servers
Tool names, per-environment and per-agent tool lists, and reconnecting.