> For the complete documentation index, see llms.txt.
Skip to main content

Check out Port for yourself ➜ 

AI-powered incident management

Implement with AI

Send this guide to your coding agent.

Prerequisite: Install Port MCP

Open plan mode. Implement this Port guide in my org via MCP:

https://docs.port.io/guides/all/ai-powered-incident-management

Goal: get the guide's core flow working end-to-end in my org; adapting it to fit my existing setup takes priority over matching the guide 1:1.

Plan:
1. Confirm MCP is connected, in the right org, with sufficient permissions.
2. Diff the guide's data model (blueprints, properties, relations, actions, agents, automations, integrations, secrets) against mine.
3. Propose adaptations for gaps, reusing existing blueprints/relations over guide-named duplicates.
4. Flag what needs a UI click, credential, or secret from me, testing MCP capability empirically before ruling anything out.
5. Stop on any blocker and give me options. Approving this plan authorizes the writes it lists; pause only for writes beyond what's listed.

Build:
- Extend blueprint schema additively when upserting; don't remove or overwrite existing properties, and treat type conflicts as a blocker, not an auto-fix.
- List any mock data in the plan, minimal and labeled mock; once approved, seed it without re-asking, and tell me what you seeded.
- For anything the guide writes downstream (e.g. a webhook target), use a real entity, not a mock.
- For pages/widgets, use the real page identifier from the app URL, not a guessed slug.
- When you hit a UI step confirmed (not assumed) unsupported via MCP, pause, give exact clicks, then resume via MCP.
- Validate and give links after each meaningful step (only a tool-returned URL, no guessed paths); don't proceed if the last run wasn't a success.

Done:
- Confirm the guide's expected output exists and runs in Port.
- Summarize adaptations, seeded data, what was mocked or skipped, remaining UI steps, and how to verify.

This guide demonstrates how to implement an AI-powered incident management lifecycle in Port. You will use Port AI agents, workflows, automations, and self-service actions to triage incidents, coordinate response, generate stakeholder updates, capture RCA context, and create postmortems.

Use the stages independently, or combine them into a complete incident lifecycle. The standalone Incident Manager AI agent guide can be used as the prerequisite agent setup before you add lifecycle-specific actions and automations.

Common use cases

  • Assess incident severity, business impact, ownership, and response team recommendations with AI.
  • Orchestrate Slack channels, Zoom war rooms, Jira tracking tickets, and team notifications.
  • Generate contextual incident updates and send them to Slack.
  • Draft RCA and postmortem documents after incidents are resolved.
  • Add historical RCA documents as searchable context for incident AI agents.

Prerequisites

This guide assumes the following:

  • You have a Port account and have completed the onboarding process.
  • You have implemented the incident blueprint pattern for incident lifecycle workflows.
  • You have set up the Incident Manager AI agent, or you have an equivalent incident-focused AI agent.
  • You have incidents synced into Port from PagerDuty or another incident management tool.
  • You have the external tools required for the stages you want to implement, such as Slack, Zoom, Jira, GitHub, or n8n.

Set up the Incident Manager AI agent

Start with the Incident Manager AI agent if you do not already have an incident-focused AI agent. That guide covers the base agent configuration, PagerDuty data access, interaction methods, and example questions.

After the base agent is available, use the lifecycle sections below to add specific triage, orchestration, communication, RCA, and postmortem capabilities.

Triage incidents with AI

Incident triage requires quickly assessing severity, identifying affected services, calculating business impact, and mobilizing response teams. Manual triage is slow, inconsistent, and delays resolution during critical outages. This guide shows how to use Port's AI to triage incidents so on-call engineers and SREs get instant severity assessment, automatic blast radius identification, intelligent team recommendations, and pre-drafted communications, leading to a reduction in MTTR and helping prevent SLA breaches.

Incident triage AI flow diagram

Where AI triage helps

  • Instant severity assessment: AI suggests sev1–sev4 based on service tier, error rates, and business impact so you can prioritize correctly.
  • Blast radius identification: Automatically identify affected services and dependencies from your software catalog.
  • Pre-drafted communications: Get internal stakeholder and status page message drafts so you can notify quickly.

Prepare incident context for AI triage

This guide assumes the following:

  • You have a Port account and have completed the onboarding process.
  • You have implemented the incident blueprint pattern for incident management workflows.
  • You have incidents in your catalog (e.g., from PagerDuty or another alert source) with at least primary_service or alert context.

Use the incident data model for triage

You will use the incident blueprint pattern described in the incident blueprint guide. The blueprint already includes properties for AI-suggested triage (severity, business impact, communications, owner, response team) and timestamps such as triaged_at.

Configure the incident triage AI agent

You will create a triage agent that analyzes incident context, suggests severity and business impact, drafts communications, and recommends owner and response team.

  1. Go to the AI agents page of your portal.

  2. Click on + AI Agent.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Incident triage agent (Click to expand)
    Agent prompt customization

    The following agent prompt is a recommended starting point. You can customize it to match your severity definitions, escalation paths, and communication templates.

    {
    "identifier": "incident_triage_agent",
    "title": "Incident Triage Agent",
    "icon": "Details",
    "team": [],
    "properties": {
    "description": "AI agent that evaluates incidents and suggests severity, business impact, affected services, and communications",
    "status": "active",
    "prompt": "You are a Triage Agent for incidents in the Alert stage.\n\n**Your Role:**\n1. Analyze incident details from PagerDuty, monitoring systems, and service context\n2. Suggest severity level (sev1-sev4) based on:\n - Service tier and criticality\n - Error rates and affected customers\n - Revenue impact potential\n - Business hours vs off-hours\n3. Identify affected services by checking:\n - Service dependencies\n - Error rate spikes\n - Recent deployments\n4. Calculate business impact:\n - Estimated customer count\n - Revenue impact\n - SLA implications\n5. Draft communications:\n - Internal stakeholder message\n - Customer-facing status page update\n6. Recommend incident owner and response team:\n - Query Port for service ownership relations\n - Check primary_service.on_call user\n - Identify service owner team\n - Consider oncall rotation and expertise\n\n**Response Format:**\nAlways call the `update_incident_triage` action with:\n- `incident_id`: The incident identifier (required)\n- `ai_suggested_severity`: sev1-sev4 (required)\n- `business_impact`: Detailed impact analysis in markdown (required)\n- `internal_comms_message`: Draft for stakeholders (required)\n- `status_page_message`: Draft for customers (optional)\n- `ai_suggested_owner`: User email of recommended incident commander (optional)\n- `ai_suggested_response_team`: Team identifier for response team (optional)\n\n**Finding Owner & Team:**\nUse Port queries to find:\n1. Primary service's on_call user → suggest as owner\n2. Primary service's team relation → suggest as response_team\n3. If no on_call, check service owner or recent incident commanders\n4. For sev1/sev2, escalate to senior engineers or leadership teams\n\nBe specific, data-driven, and focus on speed. Time matters in incidents.",
    "execution_mode": "Automatic",
    "conversation_starters": [
    "What's the blast radius of this incident? Show me affected services and their dependencies.",
    "Assess the severity and business impact. Who should I page and what should I tell customers?",
    "Connect this alert to recent deployments or changes. Is there a correlation?"
    ],
    "tools": [
    "^(list|get|search|track|describe)_.*",
    "run_update_incident_triage"
    ]
    },
    "relations": {}
    }
  5. Click Create to save the agent.

How the agent uses tools

The AI agent uses MCP (Model Context Protocol) enhanced capabilities to discover relevant blueprint entities through its tools. The ^(list|get|search|track|describe)_.* pattern lets the agent access services, teams, users, and deployments in your catalog. You add run_update_incident_triage so the agent can persist its triage suggestions. The run_ prefix marks which self-service actions the agent is allowed to execute.

Set up triage self-service actions

You will create three self-service actions: one to trigger AI triage (user-facing), one for the agent to save results (AI-facing), and one for humans to approve triage (human-in-the-loop).

Add triage incident with AI action

  1. Go to the Self-service page of your portal.

  2. Click on the + New Action button.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Triage incident with AI action (Click to expand)
    {
    "identifier": "ai_triage_incident",
    "title": "Triage incident with AI",
    "icon": "Alert",
    "description": "AI analyzes incident and suggests severity, business impact, and response team",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "additional_context": {
    "type": "string",
    "title": "Additional Context",
    "description": "Any additional context for the AI to consider",
    "format": "markdown"
    }
    },
    "required": [],
    "order": [
    "additional_context"
    ]
    },
    "blueprintIdentifier": "incident"
    },
    "invocationMethod": {
    "type": "WEBHOOK",
    "url": "https://api.port.io/v1/agent/incident_triage_agent/invoke",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "RUN_ID": "{{ .run.id }}",
    "Content-Type": "application/json"
    },
    "body": {
    "prompt": "Incident Triage Request:\n\nIncident ID: {{.entity.identifier}}\nTitle: {{.entity.title}}\nDescription: {{.entity.properties.description}}\nAlert Source: {{.entity.properties.alert_source}}\nAlerted At: {{.entity.properties.alerted_at}}\nPrimary Service: {{.entity.relations.primary_service}}\nPagerDuty Incident: {{.entity.relations.pagerduty_incident}}\n\nAdditional Context: {{.inputs.additional_context}}\n\nPlease analyze and provide:\n1. Suggested severity (sev1-sev4)\n2. Business impact analysis\n3. Affected services identification\n4. Internal communications draft\n5. Status page message draft\n6. Recommended incident owner and response team",
    "labels": {
    "source": "ai_triage_incident",
    "incident_id": "{{.entity.identifier}}",
    "stage": "alert"
    }
    }
    },
    "requiredApproval": false
    }
  5. Click Create to save the action.

Add update incident triage action

  1. Go to the Self-service page of your portal.

  2. Click on the + New Action button.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Update incident triage action (Click to expand)
    {
    "identifier": "update_incident_triage",
    "title": "Update Incident Triage",
    "icon": "DefaultProperty",
    "description": "Called by AI triage agent to store analysis results",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "incident_id": {
    "type": "string",
    "title": "Incident ID"
    },
    "ai_suggested_severity": {
    "type": "string",
    "title": "AI Suggested Severity",
    "enum": [
    "sev1",
    "sev2",
    "sev3",
    "sev4"
    ]
    },
    "business_impact": {
    "type": "string",
    "title": "Business Impact",
    "format": "markdown"
    },
    "internal_comms_message": {
    "type": "string",
    "title": "Internal Communications Message",
    "format": "markdown"
    },
    "status_page_message": {
    "type": "string",
    "title": "Status Page Message",
    "format": "markdown"
    },
    "ai_suggested_owner": {
    "type": "string",
    "title": "AI Suggested Owner",
    "format": "user"
    },
    "ai_suggested_response_team": {
    "type": "string",
    "title": "AI Suggested Response Team",
    "format": "team"
    }
    },
    "required": [
    "incident_id",
    "ai_suggested_severity",
    "business_impact",
    "internal_comms_message"
    ],
    "order": [
    "incident_id",
    "ai_suggested_severity",
    "business_impact",
    "internal_comms_message",
    "status_page_message",
    "ai_suggested_owner",
    "ai_suggested_response_team"
    ]
    }
    },
    "invocationMethod": {
    "type": "UPSERT_ENTITY",
    "blueprintIdentifier": "incident",
    "mapping": {
    "identifier": "{{ .inputs.incident_id }}",
    "properties": {
    "ai_suggested_severity": "{{ .inputs.ai_suggested_severity }}",
    "business_impact": "{{ .inputs.business_impact }}",
    "internal_comms_message": "{{ .inputs.internal_comms_message }}",
    "status_page_message": "{{ .inputs.status_page_message }}",
    "ai_suggested_owner": "{{ .inputs.ai_suggested_owner }}",
    "ai_suggested_response_team": "{{ .inputs.ai_suggested_response_team }}"
    }
    }
    },
    "requiredApproval": false
    }
  5. Click Create to save the action.

Add approve incident triage action

  1. Go to the Self-service page of your portal.

  2. Click on the + New Action button.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Approve incident triage action (Click to expand)
    {
    "identifier": "approve_incident_triage",
    "title": "Approve incident triage",
    "icon": "UpArrow",
    "description": "Human reviews and approves AI triage suggestions",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "severity": {
    "type": "string",
    "title": "Final Severity",
    "default": {
    "jqQuery": ".entity.properties.ai_suggested_severity"
    },
    "enum": [
    "sev1",
    "sev2",
    "sev3",
    "sev4"
    ]
    },
    "owner": {
    "type": "string",
    "title": "Incident Owner",
    "default": {
    "jqQuery": ".entity.properties.ai_suggested_owner"
    },
    "format": "user"
    },
    "response_team": {
    "type": "string",
    "title": "Response Team",
    "default": {
    "jqQuery": ".entity.properties.ai_suggested_response_team"
    },
    "format": "team"
    },
    "override_business_impact": {
    "type": "string",
    "title": "Override Business Impact (optional)",
    "format": "markdown",
    "default": {
    "jqQuery": ".entity.properties.business_impact"
    }
    },
    "override_comms": {
    "type": "string",
    "title": "Override Internal Comms (optional)",
    "format": "markdown",
    "default": {
    "jqQuery": ".entity.properties.internal_comms_message"
    }
    }
    },
    "required": [
    "severity",
    "owner",
    "response_team"
    ],
    "order": [
    "severity",
    "owner",
    "response_team",
    "override_business_impact",
    "override_comms"
    ]
    },
    "condition": {
    "type": "SEARCH",
    "rules": [
    {
    "operator": "isNotEmpty",
    "property": "ai_suggested_severity"
    },
    {
    "operator": "isEmpty",
    "property": "triaged_at"
    }
    ],
    "combinator": "and"
    },
    "blueprintIdentifier": "incident"
    },
    "invocationMethod": {
    "type": "UPSERT_ENTITY",
    "blueprintIdentifier": "incident",
    "mapping": {
    "identifier": "{{ .entity.identifier }}",
    "properties": {
    "business_impact": "{{ if .inputs.override_business_impact then .inputs.override_business_impact else .entity.properties.business_impact end }}",
    "internal_comms_message": "{{ if .inputs.override_comms then .inputs.override_comms else .entity.properties.internal_comms_message end }}",
    "severity": "{{ .inputs.severity }}",
    "status": "investigating",
    "triaged_at": "{{ now | todateiso8601 }}"
    },
    "relations": {
    "owner": "{{ .inputs.owner }}",
    "response_team": "{{ .inputs.response_team }}"
    }
    }
    },
    "requiredApproval": false
    }
  5. Click Create to save the action.

Human-in-the-loop workflow

The three actions implement a human-in-the-loop flow: the AI suggests severity, impact, comms, owner, and team; a human reviews and approves (or overrides) before the incident moves to investigating. This keeps triage consistent while avoiding fully automated escalation.

Add triage widgets to the incident page

Add a Triage & Response tab to the incident entity page so you can run the triage agent, use the self-service actions, and view business impact.

  1. Go to the Catalog page in your portal.

  2. Select the Incident entity page.

  3. Add a new tab named Triage & Response.

  4. Add an Action card for Triage incident with AI.

  5. Add an Action card for Approve incident triage (and any other triage-related actions you use).

  6. Add a Markdown widget with the following configuration:

    • Title: Business impact.
    • Description: AI-suggested business impact analysis. Run Triage incident with AI to generate.
    • Data source: Property, then select the Business Impact property.

Optionally add Markdown widgets for Internal Comms Message and Status Page Message so reviewers can see and edit the drafts before approving.

Test AI triage

  1. Open an Incident in the Alert stage (no triaged_at yet).

  2. Run Triage incident with AI.

  3. Confirm the agent writes ai_suggested_severity, business_impact, internal_comms_message, and optionally status_page_message, ai_suggested_owner, and ai_suggested_response_team to the incident.

  4. Open the Triage & Response tab and review the business impact and suggested owner/team.

    Incident triage tab with AI-suggested business impact
  5. Run Approve incident triage, adjust severity/owner/team or override business impact and comms as needed, then confirm.

  6. Verify the incident gets severity, owner, response_team, triaged_at, and status set to investigating.

  7. Use the AI invocations page to debug runs, tool calls, and failures.

Orchestrate incident response with AI

When incidents occur, engineers waste critical minutes manually coordinating response logistics instead of fixing the actual problem. They need to create dedicated Slack channels, set up Zoom meetings for war rooms, create tracking tickets in Jira, and notify the right people, all while gathering context about affected services.

This guide demonstrates how to implement an AI-powered incident response system in Port. When an incident is created, orchestration can run in one of two ways:

  1. Workflow: A single workflow runs a fixed sequence of steps (Slack channel, Zoom meeting, Jira ticket, notifications) based on severity.

  2. Actions & Automations: An AI agent has access to Port actions and automatically chooses and runs the right sequence based on the incident context.

Both approaches use the same data model, external tools, and secrets. Only the implementation (workflow vs. actions + automations + AI agent) differs.

Incident orchestration workflow

Where AI orchestration helps

  • Eliminate manual coordination delays by automating incident setup tasks
  • Ensure consistent incident response with standardized communication channels and tracking
  • Scale incident management across teams without requiring every engineer to know all setup steps
  • Accelerate time to resolution by removing logistics overhead during high-stress situations

Prepare external incident response tools

This guide assumes the following:

  • You have a Port account and have completed the onboarding process
  • You have access to one of Port's incident management integrations (we'll use PagerDuty in this guide)
  • You have access to a Slack developer account with permissions to create apps
  • You have access to a Zoom developer account with permissions to create Server-to-Server OAuth apps
  • You have access to a Jira instance with API access
  • For the Workflow option: you have access to workflows in Port. Workflows are currently in open beta and available to all users.
Alternative integrations

While this guide uses PagerDuty for incident management, you can adapt it for other incident management tools like FireHydrant, Incident.io, or Opsgenie. The same principles apply regardless of the incident source.

Set up the incident orchestration data model

We will configure the necessary blueprint to support our AI-powered incident orchestration workflow.

Create PagerDuty incident blueprint

The incident blueprint will store incident data from your incident management tool and track orchestration results.

  1. Go to the builder page of your portal.

  2. Click on + Blueprint.

  3. Click on the {...} Edit JSON button.

  4. Copy and paste the following JSON configuration:

    PagerDuty incident blueprint (Click to expand)
    {
    "identifier": "pagerdutyIncident",
    "description": "This blueprint represents a PagerDuty incident in our software catalog",
    "title": "PagerDuty Incident",
    "icon": "pagerduty",
    "schema": {
    "properties": {
    "status": {
    "icon": "DefaultProperty",
    "title": "Incident Status",
    "type": "string",
    "enum": [
    "triggered",
    "annotated",
    "acknowledged",
    "reassigned",
    "escalated",
    "reopened",
    "resolved",
    "escalated to human"
    ],
    "enumColors": {
    "triggered": "red",
    "annotated": "blue",
    "acknowledged": "yellow",
    "reassigned": "blue",
    "escalated": "yellow",
    "reopened": "red",
    "resolved": "green",
    "escalated to human": "bronze"
    }
    },
    "url": {
    "type": "string",
    "format": "url",
    "title": "Incident URL"
    },
    "urgency": {
    "title": "Incident Urgency",
    "type": "string",
    "enum": ["high", "low"],
    "enumColors": {
    "high": "red",
    "low": "green"
    }
    },
    "priority": {
    "title": "Priority",
    "type": "string"
    },
    "severity": {
    "type": "string",
    "title": "Severity",
    "enum": ["Critical", "High", "Medium", "Low"],
    "enumColors": {
    "Critical": "red",
    "High": "red",
    "Medium": "yellow",
    "Low": "lime"
    }
    },
    "description": {
    "type": "string",
    "title": "Description"
    },
    "assignees": {
    "title": "Assignees",
    "type": "array",
    "items": {
    "type": "string",
    "format": "user"
    }
    },
    "escalation_policy": {
    "type": "string",
    "title": "Escalation Policy"
    },
    "created_at": {
    "title": "Created At",
    "type": "string",
    "format": "date-time"
    },
    "updated_at": {
    "title": "Updated At",
    "type": "string",
    "format": "date-time"
    },
    "resolved_at": {
    "title": "Incident Resolution Time",
    "type": "string",
    "format": "date-time",
    "description": "The timestamp when the incident was resolved"
    },
    "recovery_time": {
    "title": "Time to Recovery",
    "type": "number",
    "description": "The time (in minutes) between the incident being triggered and resolved"
    },
    "triggered_by": {
    "type": "string",
    "title": "Triggered By"
    },
    "slack_channel": {
    "type": "string",
    "title": "Slack Channel",
    "description": "The Slack channel created for this incident",
    "icon": "Slack"
    },
    "zoom_meeting_link": {
    "type": "string",
    "title": "Zoom Meeting Link",
    "description": "The Zoom meeting link for the war room",
    "icon": "Team",
    "format": "url"
    },
    "jira_tracking_ticket": {
    "type": "string",
    "title": "Jira Tracking Ticket",
    "icon": "Jira",
    "format": "url",
    "description": "The Jira ticket created to track this incident"
    }
    },
    "required": []
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "relations": {
    "pagerdutyService": {
    "title": "PagerDuty Service",
    "target": "pagerdutyService",
    "required": false,
    "many": false
    }
    }
    }
  5. Click Create to save the blueprint.

If you already have PagerDuty integration installed

Port's PagerDuty integration creates a pagerdutyIncident blueprint by default. You can extend this existing blueprint by adding the following properties to enable orchestration tracking:

  1. Go to the builder page of your portal.

  2. Select the PagerDuty Incident blueprint.

  3. Click on the {...} Edit JSON button.

  4. Add the following properties under the properties schema:

    PagerDuty incident blueprint extended properties (Click to expand)
    "slack_channel": {
    "type": "string",
    "title": "Slack Channel",
    "description": "The Slack channel created for this incident"
    },
    "zoom_meeting_link": {
    "type": "string",
    "format": "url",
    "title": "Zoom Meeting Link",
    "description": "The Zoom meeting link for the war room"
    },
    "jira_tracking_ticket": {
    "type": "string",
    "format": "url",
    "title": "Jira Tracking Ticket",
    "description": "The Jira ticket created to track this incident"
    }

The rest of this guide will reference pagerdutyIncident as the blueprint identifier.

Connect Slack, Zoom, and Jira

We need to configure integrations with Slack, Zoom, and Jira to enable the orchestration actions.

Set up the Slack app

  1. Create a Slack app and install it on a workspace.

  2. Add the following permissions to the Slack app:

    • Create channel (Required):

      • channels:manage
      • groups:write
      • im:write
      • mpim:write
    • Find a user with an email address (Optional):

      • users:read.email
    • Invite users to channel (Optional):

      • channels:write.invites
      • groups:write.invites
      • mpim:write.invites
    • Send messages (Required):

      • chat:write
      • chat:write.public
    User permissions

    Without scopes for Find a user with an email address and Invite users to channel, the channel will be created but users will not be added to it automatically.

  3. Install the app in your Slack workspace.

  4. Navigate back to the OAuth & Permissions page. You will see an access token under OAuth Tokens for Your Workspace that you will use in the SLACK_BOT_TOKEN Port secret.

Slack app OAuth and Permissions page

Set up the Zoom app

Create a Server-to-Server OAuth app:

  1. Go to Zoom Marketplace.

  2. Click Develop → Build App → select Server-to-Server OAuth.

  3. Fill in the app details and make note of:

    • Account ID
    • Client ID
    • Client Secret
  4. Under Scopes, add:

    • meeting:write
    • meeting:read
    • (optionally) user:read
    Zoom app credentials page with OAuth details

Set up Jira API access

  1. Log in to your Jira instance.

  2. Generate an API token:

Add Port secrets for orchestration

To add secrets to your portal:

  1. In your Port application, click on your profile picture .

  2. Click on Credentials.

  3. Click on the Secrets tab.

  4. Click on + Secret and add the following secrets:

    • SLACK_BOT_TOKEN - Your Slack bot token from the OAuth & Permissions page
    • ZOOM_ACCOUNT_ID - Your Zoom account ID
    • ZOOM_CLIENT_ID - Your Zoom client ID
    • ZOOM_CLIENT_SECRET - Your Zoom client secret
    • JIRA_AUTH - Base64 encoded string of your Jira credentials. Generate this by running:
      echo -n "your-email@domain.com:your-api-token" | base64
      Replace your-email@domain.com with your Jira email and your-api-token with your Jira API token.

Build the orchestration implementation in Port

Choose one implementation. The data model and external tools above are the same for both.

  • Workflow: One workflow defines the full sequence. When an incident is created, the workflow runs and branches by severity (critical/high, medium, low). No AI agent, the flow is deterministic and visible in the workflow editor.
  • Actions & Automations: You create separate actions (Slack, Zoom, Jira, notify) and automations that trigger an AI agent and update the incident when actions complete. The AI agent decides which actions to run based on incident context.

Build the incident orchestration workflow

Use Port's workflow feature to chain nodes (Slack, Zoom, Jira, notifications, entity update) in a single workflow. The workflow runs automatically when a PagerDuty incident is created.

PagerDuty incident response workflow with branching

We will build the workflow using the workflow editor and the AI assistant to generate the initial structure. You can also skip the AI assistant and paste the workflow template directly.

  1. Go to the workflows page of your portal.

  2. Click + Workflow button in the top-right corner.

  3. Click on Skip to editor to open the workflow editor.

  4. Copy and paste this JSON template directly into the workflow editor.

    Incident orchestration workflow template (Click to expand)
    {
    "identifier": "incident_orchestration_workflow",
    "title": "Automated Incident Orchestration",
    "icon": "Alert",
    "description": "Automatically orchestrates incident response by creating Slack channels, Zoom meetings, Jira tickets, and notifications based on incident severity. Updates the incident entity with all created resources in a single bulk update.",
    "allowAnyoneToViewRuns": true,
    "nodes": [
    {
    "identifier": "create_jira_ticket_critical",
    "title": "Create Jira Tracking Ticket",
    "icon": "Jira",
    "description": "Creates Jira bug ticket for critical/high incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "<YOUR_JIRA_ORGANIZATION_URL>/rest/api/3/issue",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
    "Authorization": "Basic {{ .secrets.JIRA_AUTH }}"
    },
    "body": {
    "fields": {
    "labels": ["port-workflow", "incident"],
    "project": {
    "key": "<YOUR_JIRA_PROJECT>"
    },
    "summary": "{{.outputs.trigger.incident_title}}",
    "issuetype": {
    "name": "Bug"
    },
    "description": {
    "type": "doc",
    "content": [
    {
    "type": "paragraph",
    "content": [
    {
    "text": "Incident Details\n\n- Priority: {{ .outputs.trigger.incident_priority }}\n- Urgency: {{ .outputs.trigger.incident_urgency }}\n- Status: {{ .outputs.trigger.incident_status }}\n- PagerDuty URL: {{ .outputs.trigger.incident_url }}\n\nDescription:\n{{ .outputs.trigger.incident_description }}\n\nResponse Resources:\n- Slack Channel: {{ .outputs.create_slack_channel_critical.slack_channel_name }}\n- Zoom Meeting: {{.outputs.create_zoom_meeting_critical.zoom_meeting_url }}",
    "type": "text"
    }
    ]
    }
    ],
    "version": 1
    }
    }
    }
    },
    "variables": {
    "jira_ticket_url": "https://{{ (.response.data.self | capture(\"https://(?<domain>[^/]+)\") ).domain }}/browse/{{ .response.data.key }}"
    }
    },
    {
    "identifier": "create_jira_ticket_medium",
    "title": "Create Jira Tracking Ticket",
    "icon": "Jira",
    "description": "Creates Jira bug ticket for medium priority incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "<YOUR_JIRA_ORGANIZATION_URL>/rest/api/3/issue",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
    "Authorization": "Basic {{ .secrets.JIRA_AUTH }}"
    },
    "body": {
    "fields": {
    "labels": ["port-workflow", "incident"],
    "project": {
    "key": "<YOUR_JIRA_PROJECT>"
    },
    "summary": "{{.outputs.trigger.incident_title}}",
    "issuetype": {
    "name": "Bug"
    },
    "description": {
    "type": "doc",
    "content": [
    {
    "type": "paragraph",
    "content": [
    {
    "text": "Incident Details\n\n- Priority: {{ .outputs.trigger.incident_priority }}\n- Urgency: {{ .outputs.trigger.incident_urgency }}\n- Status: {{ .outputs.trigger.incident_status }}\n- PagerDuty URL: {{ .outputs.trigger.incident_url }}\n\nDescription:\n{{ .outputs.trigger.incident_description }}\n\nResponse Resources:\n- Slack Channel: {{ .outputs.create_slack_channel_medium.slack_channel_name }}",
    "type": "text"
    }
    ]
    }
    ],
    "version": 1
    }
    }
    }
    },
    "variables": {
    "jira_ticket_url": "https://{{ (.response.data.self | capture(\"https://(?<domain>[^/]+)\") ).domain }}/browse/{{ .response.data.key }}"
    }
    },
    {
    "identifier": "create_slack_channel_critical",
    "title": "Create Incident Slack Channel (C)",
    "icon": "Slack",
    "description": "Creates dedicated Slack channel for critical/high incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "https://slack.com/api/conversations.create",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
    "Authorization": "Bearer {{ .secrets.SLACK_BOT_TOKEN }}"
    },
    "body": {
    "name": "{{ .outputs.trigger.incident_id | ascii_downcase }}",
    "is_private": false
    }
    },
    "variables": {
    "slack_channel_name": "#{{ .response.data.channel.name }}"
    }
    },
    {
    "identifier": "create_slack_channel_medium",
    "title": "Create Incident Slack Channel (M)",
    "icon": "Slack",
    "description": "Creates dedicated Slack channel for medium priority incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "https://slack.com/api/conversations.create",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
    "Authorization": "Bearer {{ .secrets.SLACK_BOT_TOKEN }}"
    },
    "body": {
    "name": "{{ .outputs.trigger.incident_id | ascii_downcase }}",
    "is_private": false
    }
    },
    "variables": {
    "slack_channel_name": "#{{ .response.data.channel.name }}"
    }
    },
    {
    "identifier": "create_zoom_meeting_critical",
    "title": "Create War Room Meeting",
    "icon": "Team",
    "description": "Set up a Zoom meeting for the war room after obtaining access token",
    "config": {
    "type": "WEBHOOK",
    "url": "https://api.zoom.us/v2/users/me/meetings",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json",
    "Authorization": "Bearer {{ .outputs.get_zoom_meeting_access_token.zoom_access_token }}"
    },
    "body": {
    "type": 2,
    "topic": "{{ .outputs.trigger.incident_title }}",
    "duration": 60,
    "settings": {
    "mute_upon_entry": true,
    "join_before_host": true
    },
    "timezone": "UTC",
    "start_time": "{{ now | todateiso8601 }}"
    }
    },
    "variables": {
    "zoom_meeting_url": "{{ .response.data.join_url }}"
    }
    },
    {
    "identifier": "determine_severity",
    "title": "Determine Severity Level",
    "icon": null,
    "description": "Evaluates priority and urgency to determine response level",
    "config": {
    "type": "CONDITION",
    "options": [
    {
    "identifier": "critical_high",
    "title": "Critical/High Priority",
    "expression": "(.outputs.trigger.incident_priority == \"P1\" or .outputs.trigger.incident_priority == \"P2\" or .outputs.trigger.incident_urgency == \"Critical\" or .outputs.trigger.incident_urgency == \"High\" or .outputs.trigger.incident_urgency == \"high\")"
    },
    {
    "identifier": "medium",
    "title": "Medium Priority",
    "expression": "(.outputs.trigger.incident_priority == \"P3\" or .outputs.trigger.incident_urgency == \"Medium\" or .outputs.trigger.incident_urgency == \"medium\")"
    },
    {
    "identifier": "low",
    "title": "Low Priority",
    "expression": "(.outputs.trigger.incident_priority == \"P4\" or .outputs.trigger.incident_urgency == \"Low\" or .outputs.trigger.incident_urgency == \"low\")"
    }
    ]
    },
    "variables": {}
    },
    {
    "identifier": "get_zoom_meeting_access_token",
    "title": "Get Zoom Access Token",
    "icon": "Key",
    "description": "Set up a Zoom meeting for the war room by first obtaining access token and then proceeding to call the create zoom meeting link",
    "config": {
    "type": "WEBHOOK",
    "url": "https://zoom.us/oauth/token",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": "Basic {{ .secrets.ZOOM_CLIENT_ID + \":\" + .secrets.ZOOM_CLIENT_SECRET | @base64 }}"
    },
    "body": {
    "account_id": "{{ .secrets.ZOOM_ACCOUNT_ID }}",
    "grant_type": "account_credentials"
    }
    },
    "variables": {
    "zoom_access_token": "{{ .response.data.access_token }}"
    }
    },
    {
    "identifier": "notify_teams_critical",
    "title": "Notify Teams (Critical/High)",
    "icon": "Slack",
    "description": "Sends comprehensive Slack notification for critical/high incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "https://slack.com/api/chat.postMessage",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "Bearer {{ .secrets.SLACK_BOT_TOKEN }}"
    },
    "body": {
    "blocks": [
    {
    "text": "🚨 *INCIDENT ALERT* 🚨\n\n*Incident:* {{ .outputs.trigger.incident_title }}\n*Priority:* `{{ .outputs.trigger.incident_priority }}` | *Urgency:* `{{ .outputs.trigger.incident_urgency }}`\n*Status:* {{ .outputs.trigger.incident_status }}\n\n📋 *Response Resources Created:*\n• Slack Channel: {{ .outputs.create_slack_channel_critical.slack_channel_name }} \n• Jira Ticket: <{{ .outputs.create_jira_ticket_critical.jira_ticket_url }}|View ticket in Jira>\n• PagerDuty: <{{ .outputs.trigger.incident_url }}|View incident in PagerDuty>\n• Zoom meeting: <{{ .outputs.create_zoom_meeting_critical.zoom_meeting_url}}|Join Zoom>\n\n <{{.outputs.trigger.incident_url}}|View incident in Port>⚡ *Action Required:* Join the Slack channel and Zoom meeting immediately!",
    "type": "markdown"
    }
    ],
    "channel": "{{ .outputs.create_slack_channel_critical.slack_channel_name }}"
    }
    },
    "variables": {}
    },
    {
    "identifier": "notify_teams_low",
    "title": "Notify Teams (Low)",
    "icon": "Slack",
    "description": "Sends simple Slack notification for low priority incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "https://slack.com/api/chat.postMessage",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "Bearer {{ .secrets.SLACK_BOT_TOKEN }}"
    },
    "body": {
    "blocks": [
    {
    "text": "ℹ️ *Low Priority Incident*\n\n*Incident:* {{ .outputs.trigger.incident_title }}\n*Priority:* `{{ .outputs.trigger.incident_priority }}` | *Urgency:* `{{ .outputs.trigger.incident_urgency }}`\n*Status:* {{ .outputs.trigger.incident_status }}\n\n🔗 <{{ .outputs.trigger.incident_url }}|View incident in Port>\n\n📝 No immediate action required. Monitor as needed.",
    "type": "markdown"
    }
    ],
    "channel": "#isaac-test"
    }
    },
    "variables": {}
    },
    {
    "identifier": "notify_teams_medium",
    "title": "Notify Teams (Medium)",
    "icon": "Slack",
    "description": "Sends Slack notification for medium priority incidents",
    "config": {
    "type": "WEBHOOK",
    "url": "https://slack.com/api/chat.postMessage",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "Bearer {{ .secrets.SLACK_BOT_TOKEN }}"
    },
    "body": {
    "blocks": [
    {
    "text": "⚠️ *Incident Alert*\n\n*Incident:* {{ .outputs.trigger.incident_title }}\n*Priority:* `{{ .outputs.trigger.incident_priority }}` | *Urgency:* `{{ .outputs.trigger.incident_urgency }}`\n*Status:* {{ .outputs.trigger.incident_status }}\n\n📋 *Response Resources Created:*\n• Slack Channel: {{ .outputs.create_slack_channel_medium.slack_channel_name }} \n• Jira Ticket: <{{ .outputs.create_jira_ticket_medium.jira_ticket_url }}|View in Jira>\n• PagerDuty: <{{ .outputs.trigger.incident_url }}|View in PagerDuty>\n\n:link: <{{.outputs.trigger.incident_url}}|View incident in Port>👀 Please review and coordinate in the Slack channel.",
    "type": "markdown"
    }
    ],
    "channel": "{{ .outputs.create_slack_channel_medium.slack_channel_name }}"
    }
    },
    "variables": {}
    },
    {
    "identifier": "trigger",
    "title": "Incident Created",
    "icon": null,
    "description": "Triggers when a PagerDuty incident is created",
    "config": {
    "type": "EVENT_TRIGGER",
    "event": {
    "type": "ENTITY_CREATED",
    "blueprintIdentifier": "pagerdutyIncident"
    }
    },
    "variables": {
    "service_id": "{{ .diff.after.relations.pagerdutyService }}",
    "incident_id": "{{ .diff.after.identifier }}",
    "incident_url": "{{ .diff.after.properties.url }}",
    "incident_title": "{{ .diff.after.title }}",
    "incident_status": "{{ .diff.after.properties.status }}",
    "incident_urgency": "{{ .diff.after.properties.urgency }}",
    "incident_priority": "{{ .diff.after.properties.priority }}",
    "incident_description": "{{ .diff.after.properties.description }}"
    }
    },
    {
    "identifier": "update_incident_critical",
    "title": "Update Incident (All Resources)",
    "icon": null,
    "description": "Bulk updates the incident entity with Slack, Zoom, and Jira URLs",
    "config": {
    "type": "UPSERT_ENTITY",
    "blueprintIdentifier": "pagerdutyIncident",
    "mapping": {
    "identifier": "{{ .outputs.trigger.incident_id }}",
    "properties": {
    "slack_channel": "{{ .outputs.create_slack_channel_critical.slack_channel_name // .outputs.create_slack_channel_medium.slack_channel_name}}",
    "zoom_meeting_link": "{{ .outputs.create_zoom_meeting_critical.zoom_meeting_url }}",
    "jira_tracking_ticket": "{{ .outputs.create_jira_ticket_critical.jira_ticket_url // .outputs.create_jira_ticket_medium.jira_ticket_url }}"
    }
    }
    },
    "variables": {}
    }
    ],
    "connections": [
    {
    "description": "Analyze incident severity",
    "sourceIdentifier": "trigger",
    "targetIdentifier": "determine_severity"
    },
    {
    "description": "Critical/High → Create Slack channel",
    "sourceIdentifier": "determine_severity",
    "targetIdentifier": "create_slack_channel_critical",
    "sourceOptionIdentifier": "critical_high"
    },
    {
    "description": "Then get Zoom API acces token",
    "sourceIdentifier": "create_slack_channel_critical",
    "targetIdentifier": "get_zoom_meeting_access_token"
    },
    {
    "description": "Then create Zoom meeting",
    "sourceIdentifier": "get_zoom_meeting_access_token",
    "targetIdentifier": "create_zoom_meeting_critical"
    },
    {
    "description": "Then create Jira ticket",
    "sourceIdentifier": "create_zoom_meeting_critical",
    "targetIdentifier": "create_jira_ticket_critical"
    },
    {
    "description": "Then notify teams",
    "sourceIdentifier": "create_jira_ticket_critical",
    "targetIdentifier": "notify_teams_critical"
    },
    {
    "description": "Finally Bulk update incident with all resources",
    "sourceIdentifier": "notify_teams_critical",
    "targetIdentifier": "update_incident_critical"
    },
    {
    "description": "Medium → Create Slack channel",
    "sourceIdentifier": "determine_severity",
    "targetIdentifier": "create_slack_channel_medium",
    "sourceOptionIdentifier": "medium"
    },
    {
    "description": "Then create Jira ticket",
    "sourceIdentifier": "create_slack_channel_medium",
    "targetIdentifier": "create_jira_ticket_medium"
    },
    {
    "description": "Then notify team",
    "sourceIdentifier": "create_jira_ticket_medium",
    "targetIdentifier": "notify_teams_medium"
    },
    {
    "description": "Finally update incident with Slack & Jira",
    "sourceIdentifier": "notify_teams_medium",
    "targetIdentifier": "update_incident_critical"
    },
    {
    "description": "Low → Notify only",
    "sourceIdentifier": "determine_severity",
    "targetIdentifier": "notify_teams_low",
    "sourceOptionIdentifier": "low"
    }
    ]
    }
  5. Click Publish in the top right corner of the editor. If you encounter validation errors, refer to the troubleshooting page.

Configure the incident orchestration workflow

After publishing, replace placeholder values in the workflow nodes.

Specify Jira project key

  • In the create_jira_ticket_critical and create_jira_ticket_medium nodes:
    • Replace <YOUR_JIRA_ORGANIZATION_URL> in the webhook URL with your Jira organization URL (e.g., example.atlassian.net).
    • Set the <YOUR_JIRA_PROJECT> value to your Jira project key.
    • Ensure that the Jira authorization header is set to Basic {{ .secrets.JIRA_AUTH }}.

Configure Slack

  • In the create_slack_channel_critical, create_slack_channel_medium, and notify_teams_low nodes:
    • Set the authorization header to Bearer {{ .secrets.SLACK_BOT_TOKEN }}.
    • Update the low-priority channel name if needed.

Configure Zoom

In the get_zoom_meeting_access_token node, set the authorization header to Basic {{ .secrets.ZOOM_CLIENT_ID + ":" + .secrets.ZOOM_CLIENT_SECRET | @base64 }}.

Test incident orchestration

After you complete either the Workflow or the Actions & Automations setup, use the steps below to verify that orchestration runs correctly.

Create a test incident

  1. Go to your PagerDuty instance and create a new incident, or use Port's API to create a test incident entity.

  2. Verify that the incident appears in your Port catalog.

Verify execution

If you used Workflow: Open the run from the Audit log and confirm each node completed successfully. Check node outputs for Slack, Zoom, and Jira responses.

If you used Actions & Automations: Check the AI agent's execution logs in the AI Invocation page. Verify that the agent analyzed the incident severity and executed the appropriate actions (Slack channel, Zoom meeting for high/critical, Jira ticket, notifications).

Verify incident updates

  1. Go to your Port catalog and find the incident entity.

  2. Check that the incident has been updated with:

    • Slack channel ID
    • Zoom meeting link (if applicable)
    • Jira tracking ticket URL
  3. Verify the links are functional and accessible.

PagerDuty incident entity with Slack and Zoom links

Test in Slack

  1. Go to your Slack workspace.

  2. Verify that:

    • A new channel was created with the incident identifier
    • Notification messages were posted to the channel
    • The channel contains relevant incident information
    Slack incident alert with severity and status

Generate incident updates with AI


This guide demonstrates how to build an AI agent that generates incident updates and sends Slack notifications with relevant technical context.

When you are busy fixing an incident, you do not have time to write updates. Others still need to know what is going on, so this guide also includes an n8n workflow option that uses Port as a context lake for incident updates.

AI agent incident summaries architecture diagram

Where AI incident updates help

  • Automatically generate contextual incident updates when incidents are updated.
  • Send notifications to Slack with relevant technical context.
  • Provide on-call engineers with enriched incident information.

Prepare incident update prerequisites

This guide assumes the following:

Alternative integrations

While this guide uses PagerDuty and GitHub, you can adapt it for other incident management tools like OpsGenie or FireHydrant, and other Git providers like GitLab or Azure DevOps.

Set up incident update context

We will create and configure blueprints to support our AI-enhanced incident management workflow. This includes setting up the incident data model and enriching it with repository metadata.

Update the incident and service blueprints

To enable AI-generated incident updates and Slack notifications, update your blueprints as follows:

  1. Add an ai_update property to the incident blueprint

    • Go to the builder page of your portal.

    • Find and select your incident blueprint (e.g., pagerdutyIncident).

    • Click on {...} Edit JSON.

    • Add the following property to the properties section:

      AI update property (Click to expand)
      "ai_update": {
      "type": "string",
      "title": "AI Update"
      }
    • Click Save to update the blueprint.

  2. Add a slack_channel property to the service blueprint

    • Go to the builder page of your portal.

    • Find and select your service blueprint (e.g., pagerdutyService).

    • Click on {...} Edit JSON.

    • Add the following property to the properties section:

      Slack channel property (Click to expand)
      "slack_channel": {
      "type": "string",
      "title": "Slack Channel"
      }
    • Click Save to update the blueprint.

      Slack channel configuration

      This step is optional. You can choose to:

      • Send notifications to a static channel (hardcoded in the automation).
      • Store the Slack channel in other hierarchies (e.g., on the incident itself).
      • Use different channels based on incident severity or team.

Update repository blueprint with additional context

When installing the GitHub app, the Repository blueprint is created by default. However, we need to add additional properties to enrich incident updates with repository metadata.

  1. Go to the builder page of your portal.

  2. Find and select your existing repository blueprint (e.g., githubRepository).

  3. Click on {...} Edit JSON.

  4. Add the following properties to the properties section:

    Additional repository properties (Click to expand)
    "last_contributor": {
    "title": "Last contributor",
    "icon": "TwoUsers",
    "type": "string",
    "format": "user"
    },
    "last_push": {
    "icon": "GitPullRequest",
    "title": "Last push",
    "description": "Last commit to the main branch",
    "type": "string",
    "format": "date-time"
    },
    "vulnerabilities": {
    "type": "number",
    "title": "Known Vulnerabilities",
    "description": "Number of critical security vulnerabilities"
    }
  5. Click Save to update the blueprint.

Add repository relation and mirror properties

We will now enhance the incident blueprint with mirror properties from the repository blueprint to provide better context for AI-generated incident updates.

  1. Go to the builder page of your portal.

  2. Find the pagerdutyIncident blueprint and click on it.

  3. Add a relation to the Repository blueprint.

  4. Add the following mirror properties:

    Mirror properties configuration (Click to expand)
    {
    "mirrorProperties": {
    "repository_last_push": {
    "title": "Repository Last Push",
    "path": "repository.last_push"
    },
    "repository_last_contributor": {
    "title": "Repository Last Contributor",
    "path": "repository.last_contributor"
    },
    "repository_vulnerabilities": {
    "title": "Repository Vulnerabilities",
    "path": "repository.vulnerabilities"
    },
    "repository_readme": {
    "title": "Repository README",
    "path": "repository.readme"
    },
    "slack_channel": {
    "title": "Slack Channel",
    "path": "pagerdutyService.slack_channel"
    }
    }
    }
  5. Click Save to apply the mirror properties.

Set up the incident update self-service action

We will create a self-service action that the AI agent can run automatically to update the incident with the AI update. This approach provides more flexibility and allows manual triggering.

  1. Go to the self-service page of your portal.

  2. Click on + New Action.

  3. Click on the {...} Edit JSON button.

  4. Copy and paste the following JSON configuration:

    Update incident with AI update action (Click to expand)
    {
    "identifier": "update_incident_with_ai_update",
    "title": "Update Incident with AI Update",
    "icon": "Alert",
    "description": "Updates an incident with the AI-generated update",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "ai_update": {
    "title": "AI Update",
    "type": "string",
    "format": "markdown"
    }
    },
    "required": [
    "ai_update"
    ],
    "order": [
    "ai_update"
    ]
    },
    "blueprintIdentifier": "pagerdutyIncident"
    },
    "invocationMethod": {
    "type": "WEBHOOK",
    "url": "https://api.port.io/v1/blueprints/pagerdutyIncident/entities/{{ .entity.identifier }}",
    "agent": false,
    "synchronized": true,
    "method": "PATCH",
    "headers": {
    "RUN_ID": "{{ .run.id }}",
    "Content-Type": "application/json"
    },
    "body": {
    "properties": {
    "ai_update": "{{ .inputs.ai_update }}"
    }
    }
    },
    "requiredApproval": false
    }
  5. Click Save to create the action.

Create the incident update AI agent

Next, we will create an AI agent that generates helpful incident updates with contextual information.

Configure the incident update AI agent

  1. Go to the AI Agents page of your portal.

  2. Click on + AI Agent.

  3. Toggle Json mode on.

  4. Copy and paste the following JSON schema:

    Incident update AI agent configuration (Click to expand)
    {
    "identifier": "incident_update_ai",
    "title": "Incident Update AI",
    "icon": "Alert",
    "team": [],
    "properties": {
    "description": "AI agent that generates helpful incident updates and sends them to Slack with on-call tagging",
    "status": "active",
    "prompt": "You are an expert incident management AI agent generating clear, contextual summaries for Slack notifications.\nYour task is to produce Slack-compatible summaries for incident updates shared with engineering and on-call teams. Focus on clarity, relevance, and next steps.\n\nYour Slack summary MUST follow this structure and tone:\n\n- 🚨 *Problem:* Brief summary of what changed and why it triggered this update.\n- 📊 *Impact:* Which services or what is affected? Any delivery, uptime, or user-facing issues?\n- 🧠 *Insights / Diagnostics:* Add key technical context from repository metadata: last commit, contributor, vulnerabilities, etc or draw from your technical knowledge on what would have caused this.\n- 🔧 *Action Required:* List next steps for the on-call team. Be specific about what they need to check or resolve.\n\n🔧 **Slack Output Rules**\n* NEVER USE `**bold**` or `[text](url)` — instead use:\n * `*bold*` for emphasis\n * `<https://url.com|Label>` for links\n* Use emoji to indicate sections: `🚨`, `📋`, `👥`, `🔄`\n* Use bullet points (`-`) for clarity\n* Separate sections with one line space (not headers)\n* Never include raw markdown headers like `###` or `---`\n* Your final output **must** look clean when copy-pasted into a Slack message.\n\n*After generating your update, you MUST ALWAYS run the 'update_incident_with_ai_update' action to save the update to the incident record.*\n\n## Sample Response Format\n🚨 *Incident Update: API Latency Spike on analytics-service*\n\n*Problem:*\n`analytics-service` has breached its latency SLO for the past 15 minutes. Response time spiked from 800ms to 4.5s\n\n*Impact:*\nThis service powers real-time analytics for customer dashboards. Users may experience slow or failing dashboard loads, particularly in high-traffic regions.\n\n*Insights/Diagnostics:*\n- The latest deployment (2025-07-21 13:03 UTC) introduced new filtering logic\n- Recent commits by Maria include changes to Redis query batching and fallback caching\n- Maria is not currently on-call. Assigned engineers: Omri and Tal.\n- 2 known vulnerability exists—could be a contributing factor.\n\n🔧 *Action Required:*\n- On-call engineers Marvin and Tal should roll back to the previous deploy version while isolating the Redis call regressions.\n- Re-run load tests locally with Maria's changes to confirm memory/caching issues.\n",
    "execution_mode": "Automatic",
    "conversation_starters": [
    "What is the latest update on INC-123?",
    "Generate an update for INC-123, we've found the root cause",
    "Create a Slack update for incident INC-456",
    "Summarize the current status of incident INC-789",
    "What's the latest on the database outage incident?"
    ],
    "tools": [
    "^(list|search|track|describe)_.*",
    "^run_update_incident_with_ai_update$"
    ]
    },
    "relations": {}
    }
    MCP Enhanced Capabilities

    The AI agent uses MCP (Model Context Protocol) enhanced capabilities to automatically discover important and relevant blueprint entities via its tools. The ^(list|search|track|describe)_.* pattern allows the agent to access and analyze related entities in your software catalog such as incidents, services, deployment etc., providing richer context for incident analysis. Additionally, we allow the corresponding self-service action in the agent's Allowed Actions input (or include ^run_update_incident_with_ai_update$ in the tools list in Advanced mode (regex)), which instructs the AI agent to call this specific action to update incident records with AI-generated summaries.

  5. Click Create to save the agent.

Send AI incident updates to Slack

We will create two automations to orchestrate the AI-enhanced incident management workflow:

  1. Trigger the AI agent when incidents are updated

  2. Send the update to Slack

Automation to trigger AI agent

  1. Go to the automations page of your portal.

  2. Click on + Automation.

  3. Copy and paste the following JSON schema:

    Auto-generate incident update automation (Click to expand)
    {
    "identifier": "auto_generate_incident_update_on_update",
    "title": "Auto-Generate Incident Update on Update",
    "description": "Automatically generate incident update on update",
    "trigger": {
    "type": "automation",
    "event": {
    "type": "ENTITY_UPDATED",
    "blueprintIdentifier": "pagerdutyIncident"
    },
    "condition": {
    "type": "JQ",
    "expressions": [
    ".diff.after.properties.status != .diff.before.properties.status or .diff.after.properties.urgency != .diff.before.properties.urgency or .diff.after.properties.priority != .diff.before.properties.priority"
    ],
    "combinator": "or"
    }
    },
    "invocationMethod": {
    "type": "WEBHOOK",
    "url": "https://api.port.io/v1/agent/incident_update_ai/invoke",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "RUN_ID": "{{ .run.id }}",
    "Content-Type": "application/json"
    },
    "body": {
    "prompt": "Generate a Slack incident update for incident with target identifier {{ .event.context.entityIdentifier }}. The incident was updated with the following changes:\n\nPrevious Status: {{ .event.diff.before.properties.status }}\nNew Status: {{ .event.diff.after.properties.status }}\nPrevious Urgency: {{ .event.diff.before.properties.urgency }}\nNew Urgency: {{ .event.diff.after.properties.urgency }}\nPrevious Priority: {{ .event.diff.before.properties.priority }}\nNew Priority: {{ .event.diff.after.properties.priority }}\n\nIncident Details:\nTitle: {{ .event.diff.after.title }}\nDescription: {{ .event.diff.after.properties.description }}\nAffected Services: {{ .event.diff.after.relations.service }}\nOn-Call Engineer: {{ .event.diff.after.properties.assignees }}\nAssigned Team: {{ .event.diff.after.relations.assignedTeam }}\n\nRepository Metadata:\n- README Overview: {{ .event.diff.after.properties.readme }}\n- Last Push Date: {{ .event.diff.after.properties.repository_last_push }}\n- Last Contributor: {{ .event.diff.after.properties.repository_last_contributor }}\n- Known Vulnerabilities: {{ .event.diff.after.properties.repository_vulnerabilities }}\n\nIMPORTANT: This will be sent directly to Slack. You MUST format the response using Slack-compatible syntax:\n- Use *bold* for emphasis\n- Use emojis inline (🚨, 📋, 👥, etc.)\n- Use dashes - for bullet points\n- Use <https://url|label> for links\n- DO NOT use headers (###), raw markdown, or [label](url)\n- Add single line breaks between sections for readability\n\nYour incident update must adhere to the problem/impact/insight/action format",
    "labels": {
    "source": "Incident Update",
    "entityIdentifier": "{{ .event.context.entityIdentifier }}",
    "blueprintIdentifier": "{{ .event.context.blueprintIdentifier }}"
    }
    }
    },
    "publish": true
    }
  4. Click Create to save the automation.

Automation to send summary to Slack

  1. Go back to the automations page of your portal.

  2. Click on + Automation.

  3. Copy and paste the following JSON schema:

    Send AI incident update to Slack automation (Click to expand)
    {
    "identifier": "send_ai_update_to_slack",
    "title": "Send AI Incident Update to Slack",
    "description": "Automation to post the response of the AI incident update to Slack",
    "icon": "Slack",
    "trigger": {
    "type": "automation",
    "event": {
    "type": "ENTITY_UPDATED",
    "blueprintIdentifier": "pagerdutyIncident"
    },
    "condition": {
    "type": "JQ",
    "expressions": [
    ".diff.after.properties.ai_update != .diff.before.properties.ai_update"
    ],
    "combinator": "and"
    }
    },
    "invocationMethod": {
    "type": "WEBHOOK",
    "url": "https://slack.com/api/chat.postMessage",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "RUN_ID": "{{ .run.id }}",
    "Content-Type": "application/json; charset=utf-8",
    "Authorization": "Bearer {{ .secrets.__SLACK_APP_BOT_TOKEN_<TEAM-ID> }}"
    },
    "body": {
    "channel": "{{ .event.diff.after.properties.slack_channel }}",
    "username": "Incident AI Assistant",
    "text": "{{ .event.diff.after.properties.ai_update }}"
    }
    },
    "publish": true
    }
  4. Click Create to save the automation.

Slack token setup

You will need to add your Slack bot token as a secret in Port. Head to our guide on how to install the Slack app.

Below is an example notification sent to Slack:

Incident AI Assistant Slack notification example

Deploy the n8n incident update workflow

Use this path when you want n8n to receive PagerDuty webhooks, call Port for contextual data, and send enriched Slack notifications.

This workflow uses Port as a context lake. It retrieves service metadata, ownership, dependencies, recent deployments, related code changes, vulnerabilities, and topology data before generating the Slack update.

Before using the n8n path, make sure you have:

Import the n8n workflow template

  1. Open your n8n instance.

  2. Click Workflows and select Import from File or Import from URL.

  3. Copy the workflow JSON from the template below.

    n8n workflow template (Click to expand)
    {
    "name": "Generate Incident Updates with Port AI",
    "nodes": [
    {
    "parameters": {
    "httpMethod": "POST",
    "path": "a3c02869-071e-4bc7-bebe-28c692f26b68",
    "options": {}
    },
    "type": "n8n-nodes-base.webhook",
    "typeVersion": 2.1,
    "position": [
    0,
    0
    ],
    "id": "4438b0a6-e3d6-4d8e-bfc4-4b667527439d",
    "name": "On PagerDuty Incident Update",
    "webhookId": "a3c02869-071e-4bc7-bebe-28c692f26b68"
    },
    {
    "parameters": {
    "operation": "generalInvoke",
    "userPrompt": "=A PagerDuty incident has been created or updated with the following details: {{ JSON.stringify($json.body.incident, null, 2) }}\n\nYou are an expert incident management AI assistant.\nYour job is to enrich PagerDuty incident updates with contextual intelligence from the Port catalog using the provided tools. Always retrieve the most relevant metadata and relationships including affected services and owners, current on-call engineers, recent deployments, related pull requests, commits, known vulnerabilities, risks, past incidents, dependencies, and topology information.\n\nGenerate a concise, high-signal Slack notification summarizing the incident update with contextual insights that help engineers quickly understand impact, likely cause, and recommended next actions.\n\nYour Slack summary must follow this structure:\n\n- Problem: Brief summary of what changed and why it triggered this update.\n- Impact: Which services or what is affected.\n- Insights / Diagnostics: Precise metadata from Port.\n- Action Required: Specific next steps for the on-call team.\n\nSlack output rules: use *bold* for emphasis, <https://url.com|Label> for links, and bullet points for clarity.",
    "tools": "[\"^(list|search|track|describe)_.*\"]",
    "generalModel": "gpt-5",
    "systemPrompt": "You are a helpful assistant"
    },
    "type": "CUSTOM.portIo",
    "typeVersion": 1,
    "position": [
    208,
    0
    ],
    "id": "dcb95f48-554b-45bb-8734-e652167959a0",
    "name": "Extract Incident Context from Port",
    "credentials": {
    "portIoApi": {
    "id": "vphYNYaTZimXT7su",
    "name": "Port.io account"
    }
    }
    },
    {
    "parameters": {
    "operation": "getInvocation",
    "invocationId": "={{ $json.invocationIdentifier }}"
    },
    "type": "CUSTOM.portIo",
    "typeVersion": 1,
    "position": [
    416,
    0
    ],
    "id": "27168b70-560b-49bb-ab6b-0cf90c0e3bcf",
    "name": "Get Port Context Response",
    "credentials": {
    "portIoApi": {
    "id": "vphYNYaTZimXT7su",
    "name": "Port.io account"
    }
    }
    },
    {
    "parameters": {
    "select": "channel",
    "channelId": {
    "__rl": true,
    "value": "#incident-updates",
    "mode": "name"
    },
    "text": "={{ $json.result.message }}",
    "otherOptions": {}
    },
    "type": "n8n-nodes-base.slack",
    "typeVersion": 2.3,
    "position": [
    624,
    0
    ],
    "id": "2c8d4a08-8b21-42ce-8b76-7af1b6122684",
    "name": "Send a message",
    "credentials": {
    "slackApi": {
    "id": "WbMbgVb4paOjFSiI",
    "name": "Slack account"
    }
    }
    },
    {
    "parameters": {
    "content": "## Generate Incident Updates with Port AI\n\nThis workflow automatically generates contextual incident updates using Port's Context Lake and sends enriched Slack notifications with relevant technical information.\n\n### How it works\n1. A PagerDuty incident create/update arrives through the webhook trigger.\n2. The workflow calls Port to gather contextual metadata: affected services, owners, on-call, recent deployments, related PRs/commits, vulnerabilities, and topology.\n3. An AI step synthesizes a concise incident summary.\n4. The final message is posted to the #incident-updates Slack channel.",
    "height": 608,
    "width": 416
    },
    "type": "n8n-nodes-base.stickyNote",
    "typeVersion": 1,
    "position": [
    -464,
    -224
    ],
    "id": "67b8c149-f1d8-47ab-803c-d9a2a1d90d1a",
    "name": "Sticky Note"
    }
    ],
    "connections": {
    "On PagerDuty Incident Update": {
    "main": [
    [
    {
    "node": "Extract Incident Context from Port",
    "type": "main",
    "index": 0
    }
    ]
    ]
    },
    "Extract Incident Context from Port": {
    "main": [
    [
    {
    "node": "Get Port Context Response",
    "type": "main",
    "index": 0
    }
    ]
    ]
    },
    "Get Port Context Response": {
    "main": [
    [
    {
    "node": "Send a message",
    "type": "main",
    "index": 0
    }
    ]
    ]
    }
    },
    "active": false,
    "settings": {
    "executionOrder": "v1"
    },
    "tags": []
    }
  4. Configure the following in n8n:

    • Port.io credentials - Use the Port.io credential you created when installing the Port n8n node.
    • Slack credentials - Add your Slack API token and update the channel name.
    • Webhook URL - Configure PagerDuty to send webhooks to the URL from the On PagerDuty Incident Update node.

Test the n8n workflow

  1. Trigger a test incident in PagerDuty or use PagerDuty's webhook testing feature.

  2. Check that the Extract Incident Context from Port and Get Port Context Response nodes retrieve related services, ownership information, recent deployments, on-call engineers, and dependencies.

  3. Check the Slack notification and verify that it includes incident details, contextual information from Port, and a clear action list.

The message should look similar to this:

AI-generated PagerDuty incident Slack notification

Test AI incident updates

Now let us test the complete workflow to ensure everything works correctly.

Trigger a test incident update

  1. Go to your software catalog.

  2. Find an existing PagerDuty incident or create a test incident.

  3. Update the incident's status, urgency, or priority to trigger the automation.

Verify the AI incident update generation

  1. Go to the AI Agents page of your portal.

  2. Click on the Incident Update AI agent.

  3. Check the AI Invocations tab to see the generated incident update.

Check Slack notification

The AI-generated incident update should appear in your configured Slack channel with proper formatting and context.

Use incident update best practices

To get the most out of your AI-enhanced incident management workflow:

  1. Monitor AI responses: Regularly review the quality and accuracy of AI-generated incident updates.

  2. Refine the prompt: Adjust the AI agent prompt based on your team's specific needs and communication style.

  3. Customize Slack channels: Configure different Slack channels for different teams or incident severities.

  4. Add more context: Consider enriching incidents with additional metadata from other integrations.

Generate RCA and postmortems with AI

After resolving production incidents, teams need to generate comprehensive RCA (Root Cause Analysis) and postmortem documents that capture timeline, impact, root cause, action items, and lessons learned. This process is typically manual, time-consuming, and often inconsistent in quality or completeness. Teams either skip RCAs due to time pressure or produce low-quality retrospectives that don't prevent future incidents.

This guide shows how to use Port's AI to automatically generate postmortem documents so you can ensure every incident gets documented consistently, capture all context while it's fresh, and free engineers to focus on prevention rather than documentation.

RCA postmortem generation flow to human approval

Where AI postmortems help

  • Consistent postmortem documentation: Ensure every resolved incident gets a postmortem document without manual effort.
  • Faster incident closure: generate postmortem drafts immediately after resolution while context is fresh.
  • Organizational learning: capture lessons learned, action items, and process improvements automatically.

Prepare resolved incident context

This guide assumes the following:

  • You have a Port account and have completed the onboarding process.
  • You have implemented the incident blueprint pattern for incident management workflows.
  • You already have incidents in your catalog with resolved_at timestamps.

Set up RCA and postmortem data

You will use the incident blueprint pattern described in the incident blueprint guide. The blueprint already includes properties for AI-suggested and final approved postmortem content.

Add optional postmortem template blueprint

If you want the AI agent to follow different postmortem formats based on incident type or severity (e.g., Google SRE format, Atlassian format, etc), you can add a postmortem_template blueprint and link it to incidents via the incident blueprint's postmortem_template relation. The RCA agent will use the linked template's structure and content to guide postmortem generation.

  1. Go to the builder page of your portal.

  2. Click on + Blueprint.

  3. Click on {...} Edit JSON.

  4. Use the following configuration:

    Postmortem template blueprint (Click to expand)
    {
    "identifier": "postmortem_template",
    "title": "Postmortem Template",
    "icon": "Book",
    "schema": {
    "properties": {
    "template_content": {
    "type": "string",
    "title": "Template Content",
    "format": "markdown",
    "description": "The markdown content of the postmortem template"
    },
    "template_type": {
    "type": "string",
    "title": "Template Type",
    "enum": ["google_sre", "atlassian", "five_whys", "custom"],
    "enumColors": {
    "google_sre": "blue",
    "atlassian": "orange",
    "five_whys": "green",
    "custom": "lightGray"
    }
    }
    },
    "required": [
    "template_content"
    ]
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {},
    "relations": {}
    }
  5. Click Create to save the blueprint.

Configure the incident RCA AI agent

You will create a dedicated RCA agent that analyzes incident context, builds timelines, and generates comprehensive postmortem documents.

  1. Go to the AI agents page of your portal.

  2. Click on + AI Agent.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Incident RCA agent (Click to expand)
    Using postmortem templates

    When an incident has a postmortem template linked, the AI agent can access the template structure through the relation and use it to guide the postmortem generation format. This allows you to use different templates based on incident type or severity (e.g., Google SRE format, Atlassian format, Five Whys, or custom templates). The agent reads the template structure to generate consistent, well-organized postmortems that match your organization's standards.

    {
    "identifier": "incident_rca_agent",
    "title": "Incident RCA Agent",
    "icon": "Details",
    "team": [],
    "properties": {
    "description": "AI agent that generates comprehensive postmortem documents using Port context and template structures",
    "status": "active",
    "prompt": "You are an RCA Agent for incidents in the Postmortem stage.\n\n**Your Role:**\n1. Generate comprehensive postmortem document including:\n - **Executive Summary**: One-paragraph overview\n - **Timeline**: Key events from alert to resolution\n - **Root Cause**: Detailed technical analysis\n - **Impact**: Customer, revenue, SLA effects\n - **Resolution**: Steps taken to fix\n - **Action Items**: Prevent recurrence (with owners)\n - **Lessons Learned**: What went well, what to improve\n2. Identify gaps in monitoring, alerting, or processes\n3. Suggest action items with specific owners\n4. Reference similar past incidents\n5. Calculate key metrics (MTTR, MTTD, impact duration)\n6. If the incident has a `postmortem_template` relation, use the template structure to guide the postmortem format and ensure consistency with your organization's standards\n\n**Response Format:**\nGenerate comprehensive markdown document with all sections. If a postmortem template is linked to the incident, follow its structure and format.\n\nYou MUST always call the `update_incident_postmortem` action with inputs: `ai_suggested_postmortem` field and `incident_id` to save the results of the postmortem.\n\n**Tone:**\nFactual, blame-free, focused on system improvements.",
    "execution_mode": "Automatic",
    "conversation_starters": [
    "Generate postmortem for this incident",
    "What learnings can we extract?",
    "Create action items to prevent recurrence"
    ],
    "tools": [
    "^(list|get|search|track|describe)_.*",
    "^run_update_incident_postmortem$"
    ]
    },
    "relations": {}
    }
  5. Click Create to save the agent.

How the agent uses tools

The AI agent uses MCP (Model Context Protocol) enhanced capabilities to discover relevant blueprint entities through its tools. The ^(list|search|track|describe)_.* pattern lets the agent access and analyze related entities in your software catalog, which gives it richer context. You can allow the corresponding self-service action in the agent's Allowed Actions input (or include ^run_update_incident_postmortem$ in the tools list in Advanced mode (regex)) to instruct the agent to call this specific action and update the incident with the AI-generated postmortem. The run_ prefix marks which self-service actions the agent is allowed to execute.

Set up RCA and postmortem actions

You will create three self-service actions that work together: one triggers the AI analysis (user-facing), one saves the AI results (AI-facing tool), and one completes the postmortem with human approval (human-in-the-loop).

Add generate postmortem with AI action

  1. Go to the Self-service page of your portal.

  2. Click on the + New Action button.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Generate postmortem with AI action (Click to expand)
    {
    "identifier": "ai_generate_postmortem",
    "title": "Generate postmortem with AI",
    "icon": "Alert",
    "description": "Use AI to generate postmortem document of a triaged incident",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "include_sections": {
    "type": "string",
    "title": "Include Section",
    "description": "Additional sections to include in the postmortem report",
    "icon": "DefaultProperty",
    "format": "multi-line"
    }
    },
    "required": [],
    "order": [
    "include_sections"
    ]
    },
    "executeActionButtonText": "Generate Report",
    "condition": {
    "type": "SEARCH",
    "rules": [
    {
    "property": "resolved_at",
    "operator": "isNotEmpty"
    },
    {
    "property": "postmortem_completed_at",
    "operator": "isEmpty"
    }
    ],
    "combinator": "and"
    },
    "blueprintIdentifier": "incident"
    },
    "invocationMethod": {
    "type": "WEBHOOK",
    "url": "https://api.port.io/v1/agent/incident_rca_agent/invoke",
    "agent": false,
    "synchronized": true,
    "method": "POST",
    "headers": {
    "RUN_ID": "{{ .run.id }}",
    "Content-Type": "application/json"
    },
    "body": {
    "prompt": "Postmortem Generation Request:\n\nIncident ID: {{.entity.identifier}}\nTitle: {{.entity.title}}\nSeverity: {{.entity.properties.severity}}\nAlerted At: {{.entity.properties.alerted_at}}\nResolved At: {{.entity.properties.resolved_at}}\nMTTR: {{.entity.properties.mttr_minutes}} minutes\n\nRoot Cause: {{.entity.properties.ai_suggested_root_cause}}\nRemediation Plan: {{.entity.properties.ai_remediation_plan}}\nBusiness Impact: {{.entity.properties.business_impact}}\n\nPlease generate a comprehensive postmortem including:\n1. Executive summary\n2. Timeline of events\n3. Root cause analysis\n4. Impact assessment\n5. Remediation steps taken\n6. Action items to prevent recurrence\n7. What went well / What could improve\n\n**CRITICAL: After completing the postmortem generation, you MUST use the \"Update Incident Postmortem\" self-service action to save the results:**\n- Call the \"Update Incident Postmortem\" action with:\n - `incident_id`: {{.entity.identifier}}\n - `ai_suggested_postmortem`: The complete markdown formatted postmortem document\n- This saves the postmortem to the incident properties for human review\n\nAdditional sections to include: {{.inputs.include_sections}}",
    "labels": {
    "source": "ai_generate_postmortem",
    "incident_id": "{{.entity.identifier}}",
    "stage": "postmortem"
    }
    }
    }
    }
  5. Click Create to save the action.

Add update incident postmortem action

  1. Go to the Self-service page of your portal.

  2. Click on the + New Action button.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Update incident postmortem action (Click to expand)
    {
    "identifier": "update_incident_postmortem",
    "title": "Update Incident Postmortem",
    "icon": "DefaultProperty",
    "description": "Called by AI RCA agent to store suggested postmortem content for human review",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "ai_suggested_postmortem": {
    "type": "string",
    "title": "AI Suggested Postmortem",
    "format": "markdown"
    },
    "incident_id": {
    "type": "string",
    "title": "Incident ID"
    }
    },
    "required": [
    "incident_id",
    "ai_suggested_postmortem"
    ],
    "order": [
    "incident_id",
    "ai_suggested_postmortem"
    ]
    }
    },
    "invocationMethod": {
    "type": "UPSERT_ENTITY",
    "blueprintIdentifier": "incident",
    "mapping": {
    "identifier": "{{ .inputs.incident_id }}",
    "properties": {
    "ai_suggested_postmortem": "{{ .inputs.ai_suggested_postmortem }}"
    }
    }
    },
    "requiredApproval": false
    }
  5. Click Create to save the action.

Add approve and complete postmortem action

  1. Go to the Self-service page of your portal.

  2. Click on the + New Action button.

  3. Click on the {...} Edit JSON button.

  4. Use the following configuration:

    Approve and complete postmortem action (Click to expand)
    {
    "identifier": "approve_and_complete_postmortem",
    "title": "Approve and complete postmortem",
    "description": "Approves the suggested postmortem result from the triage agent and closes the incident",
    "trigger": {
    "type": "self-service",
    "operation": "DAY-2",
    "userInputs": {
    "properties": {
    "postmortem_content": {
    "type": "string",
    "title": "Postmortem Content",
    "format": "markdown",
    "default": {
    "jqQuery": ".entity.properties.ai_suggested_postmortem"
    }
    }
    },
    "required": [
    "postmortem_content"
    ],
    "order": [
    "postmortem_content"
    ]
    },
    "condition": {
    "type": "SEARCH",
    "rules": [
    {
    "property": "resolved_at",
    "operator": "isNotEmpty"
    },
    {
    "property": "postmortem_completed_at",
    "operator": "isEmpty"
    }
    ],
    "combinator": "and"
    },
    "blueprintIdentifier": "incident"
    },
    "invocationMethod": {
    "type": "UPSERT_ENTITY",
    "blueprintIdentifier": "incident",
    "mapping": {
    "identifier": "{{ .entity.identifier }}",
    "properties": {
    "postmortem_completed_at": "{{ now | todateiso8601 }}",
    "postmortem_content": "{{ .inputs.postmortem_content }}",
    "status": "closed"
    }
    }
    },
    "requiredApproval": false,
    "allowAnyoneToViewRuns": true,
    "icon": "Bolt"
    }
  5. Click Create to save the action.

Human-in-the-loop workflow

The three actions work together to create a human-in-the-loop workflow: the AI generates the postmortem draft, saves it for review, and then a human reviews, edits if needed, and approves it to complete the incident. This ensures quality while reducing manual effort.

Add postmortem widgets to the incident page

You will add widgets to the incident entity page to display the AI-generated postmortem and provide easy access to the actions.

  1. Go to the Catalog page in your portal.

  2. Select the Incident entity page.

  3. Add a new tab named Completed with Postmortem.

  4. Add an Action card for Generate postmortem with AI.

  5. Add a Markdown widget with the following configuration:

    • Title: AI suggested postmortem.
    • Description: AI-generated postmortem document awaiting review. Run Generate postmortem with AI to generate.
    • Data source: Property, then select the AI Suggested Postmortem property.
  6. Add another Action card for Approve and complete postmortem.

Test RCA and postmortem generation

  1. Open an Incident that has a resolved_at timestamp and no postmortem_completed_at timestamp.

  2. Run Generate postmortem with AI action.

  3. Confirm the agent writes the postmortem draft to the ai_suggested_postmortem property.

  4. Review the AI-generated postmortem in the Postmortem tab.

  5. Edit the postmortem content if needed, then run Approve and complete postmortem action.

  6. Verify the incident status changes to closed and postmortem_completed_at is set.

  7. Debug the run from the AI invocations page to review execution logs, tool calls, and failures.

    AI-generated postmortem for checkout service webhook failure

Add RCA context to AI agents

Use RCA documents as AI context

This guide demonstrates how to provide additional context to your AI agents beyond what's available through Port's integrations.

For this guide, we will leverage on the Incident Manager AI agent by adding Root Cause Analysis (RCA) documents to enable it to reference past incidents and their resolutions when answering questions.

Where RCA context helps

  • Provide historical context when responding to new incidents that are similar to past ones.
  • Reference documented solutions and preventive measures from previous incidents.
  • Help identify patterns across multiple incidents and suggest proactive measures.
  • Store and access organizational knowledge in runbooks, architecture documents, and best practices.

Prepare an agent for RCA context

This guide assumes you have:

Set up an RCA knowledge base

For this guide, we will create a custom blueprint to store RCA documents, populate it with sample data, and configure an existing AI agent to access this context.

Create root cause analysis blueprint

We will create a custom blueprint to store RCA documents, populate it with sample data, and configure an existing AI agent to access this context.

Follow the steps below to create the blueprint:

  1. Go to the Builder page of your portal.

  2. Click on + Blueprint.

  3. Click on {...} Edit JSON.

  4. Copy and paste the JSON schema from below:

    Root Cause Analysis blueprint (Click to expand)

    The entities of this blueprint will represent different RCA documents from past incidents.

    {
    "identifier": "rootCauseAnalysis",
    "title": "Root Cause Analysis",
    "icon": "Bug",
    "description": "Historical Root Cause Analysis documents from past incidents, including resolutions, lessons learned, and preventive measures",
    "schema": {
    "properties": {
    "summary": {
    "type": "string",
    "title": "Summary",
    "description": "Brief summary of the incident"
    },
    "incidentDate": {
    "type": "string",
    "format": "date-time",
    "title": "Incident Date",
    "description": "When the incident occurred"
    },
    "severity": {
    "type": "string",
    "title": "Severity",
    "enum": ["Critical", "High", "Medium", "Low"],
    "enumColors": {
    "Critical": "red",
    "High": "orange",
    "Medium": "yellow",
    "Low": "green"
    }
    },
    "affectedServices": {
    "type": "array",
    "title": "Affected Services",
    "description": "Services impacted by this incident"
    },
    "rootCause": {
    "type": "string",
    "format": "markdown",
    "title": "Root Cause",
    "description": "Detailed analysis of what caused the incident"
    },
    "resolution": {
    "type": "string",
    "format": "markdown",
    "title": "Resolution",
    "description": "How the incident was resolved"
    },
    "preventiveMeasures": {
    "type": "string",
    "format": "markdown",
    "title": "Preventive Measures",
    "description": "Actions taken to prevent similar incidents"
    },
    "lessonsLearned": {
    "type": "string",
    "format": "markdown",
    "title": "Lessons Learned",
    "description": "Key takeaways and learnings from this incident"
    },
    "tags": {
    "type": "array",
    "title": "Tags",
    "description": "Tags for categorizing and searching RCAs"
    }
    },
    "required": ["summary", "incidentDate", "severity", "rootCause", "resolution"]
    },
    "mirrorProperties": {},
    "calculationProperties": {},
    "aggregationProperties": {},
    "relations": {}
    }
  5. Click Create to save the blueprint.

Populate with sample RCA data

Now let's populate the RCA blueprint with sample data that our AI agent can reference. You can ingest this data using any of these three methods:

Database Connection Pool Exhaustion incident

Let's create our first RCA entity using the Port UI:

  1. Go to your software catalog.

  2. Find the "Root Cause Analysis" tab and click on + Root Cause Analysis.

  3. Toggle JSON mode and copy and paste the following JSON:

    Database Connection Pool Exhaustion incident (Click to expand)
    {
    "properties": {
    "summary": "Payment service experienced 5-minute outage due to database connection pool exhaustion",
    "incidentDate": "2024-01-15T14:20:00.000Z",
    "severity": "High",
    "affectedServices": [
    "payment-service",
    "checkout-service"
    ],
    "tags": [
    "payment-service",
    "checkout-service"
    ],
    "rootCause": "## Analysis\nThe payment service database connection pool was configured with a maximum of 10 connections. During peak traffic (Black Friday promotion), the service received 5x normal load, causing all connections to be exhausted.\n\n## Timeline\n- 14:30 - First alerts for payment service timeouts\n- 14:32 - Database monitoring showed 100% connection pool utilization \n- 14:35 - Root cause identified as connection pool exhaustion",
    "resolution": "## Immediate Fix\n1. Increased database connection pool size from 10 to 50\n2. Restarted payment service instances\n3. Service restored at 14:35\n\n## Technical Details\n- Updated `application.yml` configuration\n- Deployed hotfix version 1.2.1\n- Verified connection pool metrics in monitoring dashboard",
    "preventiveMeasures": "1. **Monitoring**: Added alerts for connection pool utilization >80%\n2. **Load Testing**: Implemented regular load testing with 10x normal traffic\n3. **Configuration**: Set connection pool size based on expected peak load + 50% buffer\n4. **Documentation**: Updated runbooks with connection pool troubleshooting steps",
    "lessonsLearned": "- Always configure connection pools based on peak load, not average load\n- Monitor connection pool utilization as a key metric\n- Include database load in regular performance testing\n- Have connection pool size adjustment procedures documented"
    },
    "relations": {},
    "icon": "Bug",
    "identifier": "rca-db-pool-exhaustion-2024-01",
    "title": "Database Connection Pool Exhaustion - Payment Service"
    }
  4. Click Create to save the RCA entity.

Memory Leak incident

Let us add another RCA entity:

  1. Click on + Root Cause Analysis.

  2. Toggle JSON mode and copy and paste the following JSON:

    Memory Leak incident (Click to expand)
    {
    "properties": {
    "summary": "Gradual memory leak in user service caused OOM crashes every 6 hours",
    "incidentDate": "2024-02-08T09:15:00.000Z",
    "severity": "Critical",
    "affectedServices": [
    "user-service",
    "authentication-service"
    ],
    "tags": [
    "memory-leak",
    "authentication",
    "jvm"
    ],
    "rootCause": "## Analysis\nThe user service authentication module had a memory leak in the session cache implementation. The cache was not properly clearing expired sessions, causing memory usage to grow continuously until OutOfMemory errors occurred.\n\n## Timeline\n- 09:15 - First OOM crash reported\n- 09:20 - Service automatically restarted\n- 15:15 - Second OOM crash (6 hours later)\n- 15:25 - Pattern identified, memory leak suspected",
    "resolution": "## Immediate Fix\n1. Implemented proper session cleanup in authentication cache\n2. Added memory monitoring and alerting\n3. Deployed hotfix version 2.1.3\n4. Increased heap size as temporary measure\n\n## Technical Details\n- Fixed session expiration logic in AuthenticationCache.java\n- Added automated cleanup job running every 30 minutes\n- Configured JVM garbage collection tuning",
    "preventiveMeasures": "1. **Memory Monitoring**: Added heap usage alerts at 80% and 90% thresholds\n2. **Code Review**: Enhanced review process to check for potential memory leaks\n3. **Testing**: Added memory leak detection to integration test suite\n4. **Documentation**: Created memory management guidelines for developers",
    "lessonsLearned": "- Always implement proper cleanup mechanisms for caches and session storage\n- Memory monitoring should be a standard part of service deployment\n- Regular heap dumps and analysis can help identify memory issues early\n- Consider using weak references for cache implementations to allow garbage collection"
    },
    "relations": {},
    "icon": "Bug",
    "identifier": "rca-memory-leak-user-service-2024-02",
    "title": "Memory Leak in User Service Authentication Module"
    }
  3. Click Create to save the RCA entity.

Add more RCA entities

For a more comprehensive knowledge base, consider adding 5-10 RCA documents covering different types of incidents your organization has experienced.

Update the AI agent to use RCA context

The Incident Manager AI agent uses the MCP tools pattern (^(list|search|track|describe)_.*), which automatically provides access to all blueprints in your catalog - including the RCA blueprint you just created. This means the agent can already search and reference RCA documents without any configuration changes.

Automatic blueprint discovery

With the MCP tools pattern, AI agents automatically discover new blueprints you create. You don't need to manually add "rootCauseAnalysis" to any configuration - the agent already has access to query and reference these documents.

Update the agent prompt (optional)

While the agent can automatically access RCA documents, updating the prompt helps guide it on when and how to use this information effectively.

  1. Go to the AI Agents page.

  2. Find the Incident Manager agent and click on the ... on the far right of the row.

  3. Click on Edit.

  4. Click on Edit property on the Prompt field.

  5. Replace the existing content with the following:

    Enhanced agent prompt (Click to expand)
    You are an agent responsible for answering questions about PagerDuty incidents, services, escalation policies, schedules, and on-call rotations.
    You also have access to historical Root Cause Analysis (RCA) documents from past incidents.

    ### Guidelines
    - Provide clear information about incidents
    - Identify who is on-call for services (both primary and secondary on-call)
    - Report on incident statistics and resolution times
    - When relevant, reference past RCA documents to provide context and suggest solutions
    - Use RCA lessons learned to help prevent similar incidents
    - Suggest preventive measures based on historical incident patterns
  6. Click Save to save the changes.

Add RCA-focused conversation starters (optional)

  1. Click on Edit property on the Conversation starters field.

  2. Replace the existing content with the following:

    Conversation starters (Click to expand)
    [
    "Who is on call for the payment service?",
    "What are the active incidents right now?",
    "What is our average incident resolution time?",
    "Have we seen database connection issues before?",
    "What can we learn from past payment service incidents?",
    "Show me RCAs for incidents similar to the current one"
    ]
  3. Click Update to save the changes to the agent.

Using RCA Context

You can now use these RCA context in your agent's responses:

  • Search RCA documents when users ask about similar past incidents.
  • Reference specific resolution steps from past incidents when applicable.
  • Highlight patterns across multiple incidents.
  • Suggest preventive measures from historical data.

Test RCA-aware incident responses

Let's test that our agent can now reference RCA documents with some example questions.

Question: "We're seeing database connection timeouts in the payment service. Have we experienced this before?"

Expected response: The agent should reference the RCA document we created and provide details about the previous database connection pool exhaustion incident, including the resolution steps and preventive measures.

AI agent response with past database timeout incidents

Question: "What lessons have we learned from past payment service incidents?"

Expected response: The agent should search through RCA documents tagged with payment-related services and summarize key lessons learned.

AI agent listing lessons from payment service incidents

Question: "How should we prevent memory leaks in our services?"

Expected response: The agent should reference preventive measures from relevant RCA documents.

AI agent memory leak prevention guidance from RCA

Review the RCA context setup

You have successfully enhanced your AI agent with custom context using entities! Your Incident Manager agent now has access to historical incident knowledge, making it significantly more valuable for both current incident response and prevention of future issues.

The approach we've demonstrated here can be extended to other types of documentation:

  • Runbooks: Create a "Runbook" blueprint with markdown procedures.
  • Architecture docs: Store system architecture information.
  • Process documentation: Include incident response procedures.
  • Best practices: Capture organizational standards and guidelines.

Extend the same context pattern

Beyond incident management, you can use the same approach to enhance your AI agents with various types of organizational knowledge:

Documentation agent

Create a "Documentation" blueprint to store:

  • API documentation: Store OpenAPI specs, endpoint descriptions, and usage examples.
  • Onboarding guides: New team member checklists and getting-started resources.
  • Technical standards: Coding standards, architectural patterns, and best practices.
Example question
"Where can I find the API documentation for the user authentication service?"

Deployment agent

Create a "Deployment Guide" blueprint to store:

  • Environment-specific configs: Production, staging, and development deployment procedures.
  • Release notes: Feature descriptions, breaking changes, and migration guides.
  • Rollback procedures: Step-by-step recovery instructions for different scenarios.
Example question
"What's the rollback procedure for the payment service in production?"

Security agent

Create a "Security Policy" blueprint to store:

  • Compliance requirements: SOC2, GDPR, and other regulatory guidelines.
  • Security reviews: Vulnerability assessments and remediation procedures.
  • Access control policies: Permission matrices and approval workflows.
Example question
"What are the security requirements for handling customer data?"

Knowledge base agent

Create a "FAQ" or "Knowledge Article" blueprint to store:

  • Common issues: Frequently asked questions and their solutions.
  • Troubleshooting guides: Step-by-step diagnostic procedures.
  • Team knowledge: Tribal knowledge, tips, and tricks from experienced team members.
Example question
"How do I debug slow database queries in our application?"
Start small and expand

Begin with one additional use case that addresses your team's most common questions, then gradually expand to cover more areas as you see value from the AI agent interactions.

Expand the RCA knowledge base

Here are some ways to expand and improve your setup:

  • Automate RCA creation: Set up automations to create RCA entities from incident post-mortems.
  • Cross-reference data: Link RCAs to services, teams, and other relevant entities using relations.
  • Monitor agent usage: Review AI invocation logs to see how effectively the agent uses RCA context.
  • Add more context types: Create additional blueprints for different types of organizational knowledge.
  • Regular maintenance: Periodically review and update RCA documents as processes evolve.

More relevant guides