Skip to main content
Glama
angelus-h

PagerDuty MCP Server

by angelus-h
README.md
# PagerDuty MCP Server

**Model Context Protocol server for PagerDuty incident management**

Integrate PagerDuty with AI assistants (Claude Desktop, Claude Code) for intelligent incident management and on-call support.

---

## šŸŽÆ Features

### **Incident Management (9 Tools)**

- `list_incidents` - List incidents with filters (status, urgency, team)
- `get_incident` - Get detailed incident information
- `get_my_incidents` - Get incidents assigned to you
- `acknowledge_incident` - Mark incident as acknowledged
- `resolve_incident` - Resolve incident with notes
- `add_incident_note` - Add investigation notes
- `get_incident_alerts` - Get all alerts for an incident
- `get_incident_timeline` - View incident activity history
- `get_oncall` - Check current on-call schedules

### **Read-Only by Default**
- List, query, and analyze incidents
- View alerts and timelines
- Check on-call schedules

### **Write Operations (Controlled)**
- Acknowledge/resolve incidents (requires confirmation)
- Add investigation notes
- Secure: Uses From-email header for audit trail

---

## šŸš€ Quick Start

### **Prerequisites**

- Python 3.10+
- PagerDuty account with API access
- Claude Desktop or Claude Code

### **1. Get PagerDuty API Token**

1. Login to PagerDuty: https://your-company.pagerduty.com
2. User Icon → **My Profile**
3. **User Settings** → **API Access**
4. Click **"Create API User Token"**
5. Description: `MCP-Integration`
6. Copy token (starts with `u+` or `y1_`)

### **2. Install Dependencies**

```bash
cd pagerduty-mcp-server

# Using uv (recommended)
uv sync

# Or using pip
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e .
```

### **3. Set Environment Variable**

```bash
# Linux/macOS
export PAGERDUTY_API_TOKEN="u+your-token-here"

# Or add to ~/.bashrc
echo 'export PAGERDUTY_API_TOKEN="u+your-token-here"' >> ~/.bashrc
source ~/.bashrc
```

### **4. Test the Server**

```bash
# Run server (stdio mode)
uv run python main.py

# Or with pip
python main.py
```

---

## āš™ļø MCP Configuration

### **Claude Desktop**

**Config file:** `~/.config/mcp/mcpServers.json` (Linux) or `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)

```json
{
 "mcpServers": {
  "pagerduty": {
   "command": "uv",
   "args": [
    "--directory",
    "/path/to/pagerduty-mcp-server",
    "run",
    "python",
    "main.py"
   ],
   "env": {
    "PAGERDUTY_API_TOKEN": "${PAGERDUTY_API_TOKEN}"
   }
  }
 }
}
```

### **Claude Code (VS Code)**

**Config file:** `~/.config/Code/User/mcp.json`

```json
{
 "mcpServers": {
  "pagerduty": {
   "command": "uv",
   "args": [
    "--directory",
    "/path/to/pagerduty-mcp-server",
    "run",
    "python",
    "main.py"
   ],
   "env": {
    "PAGERDUTY_API_TOKEN": "${PAGERDUTY_API_TOKEN}"
   }
  }
 }
}
```

**Restart Claude Desktop/Code after config changes.**

---

## šŸ“š Tool Usage Examples

### **List Active Incidents**

```
"List all triggered PagerDuty incidents"
```

Claude will use: `list_incidents(status="triggered")`

### **Check Your Incidents**

```
"Show me my assigned PagerDuty incidents"
```

Claude will use: `get_my_incidents()`

### **Investigate Incident**

```
"Get details for PagerDuty incident Q26N8MQQHA6R0P"
```

Claude will use: `get_incident(incident_id="Q26N8MQQHA6R0P")`

### **View Alerts**

```
"Show all alerts for this incident"
```

Claude will use: `get_incident_alerts(incident_id="...")`

### **Acknowledge Incident**

```
"Acknowledge incident Q26N8MQQHA6R0P with note: Investigating database slowdown"
```

Claude will use: `acknowledge_incident(incident_id="...", note="Investigating database slowdown")`

### **Check On-Call**

```
"Who is on-call right now?"
```

Claude will use: `get_oncall()`

---

## šŸ”§ Advanced Configuration

### **Environment Variables**

| Variable | Required | Description |
|----------|----------|-------------|
| `PAGERDUTY_API_TOKEN` | Yes | API User Token from PagerDuty |
| `PYTHONUNBUFFERED` | No | Set to `1` for proper logging (recommended) |

### **Custom Filters**

```python
# List high-urgency triggered incidents
list_incidents(status="triggered", urgency="high", limit=50)

# List incidents for specific team
list_incidents(team_ids=["P5KZERF"], status="acknowledged")
```

---

## šŸ› ļø Development

### **Project Structure**

```
pagerduty-mcp-server/
ā”œā”€ā”€ main.py           # Entry point
ā”œā”€ā”€ src/
│  ā”œā”€ā”€ server_mcp.py     # MCP server with 9 tools
│  └── helpers/
│    ā”œā”€ā”€ pagerduty_client.py  # Async API client
│    ā”œā”€ā”€ utils.py       # Formatting utilities
│    └── constants.py     # API constants
ā”œā”€ā”€ pyproject.toml
ā”œā”€ā”€ uv.lock
└── README.md
```

### **Adding New Tools**

1. Implement in `src/server_mcp.py`
2. Add helper functions to `src/helpers/` if needed
3. Test with Claude

---

## šŸ“– API Reference

### **Incident Statuses**

- `triggered` - New incident, not acknowledged
- `acknowledged` - Someone is working on it
- `resolved` - Incident fixed

### **Urgencies**

- `high` - High urgency (pages on-call)
- `low` - Low urgency (notification only)

### **Common Fields**

- `incident_id` - PagerDuty incident ID (e.g., `Q26N8MQQHA6R0P`)
- `incident_number` - Human-readable number (e.g., `2914407`)
- `service` - Affected service
- `assigned_to` - List of assigned users
- `html_url` - Link to incident in PagerDuty web UI

---

## šŸ”’ Security

### **API Token Security**

- āœ… Store token in environment variable (NOT in code)
- āœ… Use `.gitignore` to prevent token commits
- āœ… Token has same permissions as your PagerDuty user
- āœ… Audit trail: All actions logged with your email

### **Read-Only Tools**

Safe to use without confirmation:
- `list_incidents`
- `get_incident`
- `get_my_incidents`
- `get_incident_alerts`
- `get_incident_timeline`
- `get_oncall`

### **Write Tools (Require Confirmation)**

- `acknowledge_incident` - Marks incident as acknowledged
- `resolve_incident` - Closes incident
- `add_incident_note` - Adds investigation notes

---

## šŸ› Troubleshooting

### **"Missing PAGERDUTY_API_TOKEN"**

```bash
# Check environment variable
echo $PAGERDUTY_API_TOKEN

# If empty, set it
export PAGERDUTY_API_TOKEN="u+your-token-here"
source ~/.bashrc
```

### **"Authentication failed"**

- Token expired or invalid
- Get new token from PagerDuty User Settings
- Verify token starts with `u+` or `y1_`

### **"No incidents found"**

- Check filters (status, urgency)
- Verify you have access to incidents
- Try without filters: `list_incidents(limit=10)`

### **MCP Server Not Loading**

- Restart Claude Desktop/Code
- Check config file path
- Verify `uv` is installed: `uv --version`
- Check logs: `tail -f ~/.config/Claude/logs/mcp*.log`

---

## šŸŽÆ Use Cases

### **1. Morning Incident Check**

```
"Show me all active PagerDuty incidents from the last 24 hours"
```

### **2. On-Call Handoff**

```
"Who is currently on-call? Show all open incidents."
```

### **3. Incident Investigation**

```
"Get incident Q26N8MQQHA6R0P details, alerts, and timeline"
```

### **4. Alert Analysis**

```
"Show all alerts for incident XYZ and summarize the root cause"
```

### **5. Team Status**

```
"List all triggered incidents for my team"
```

---

## šŸš€ Integration with ServiceNow (Future)

**Planned feature:** Create ServiceNow incidents from PagerDuty alerts

```
PagerDuty Incident
  ↓
Claude AI (parses alert)
  ↓
ServiceNow MCP (create incident)
  ↓
Link PagerDuty ↔ ServiceNow
```

---


## šŸ¤ Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

---

## šŸ“„ License

Apache License 2.0 - see [LICENSE](LICENSE) file.

---

**Last updated:** 2026-03-11

TDQS

A3.8/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct resource and action: specific incident retrieval, user-specific incident listing, general listing, and incident lifecycle actions (acknowledge, resolve, note) are clearly separated. Specialized views like alerts and timeline also have unique purposes with no overlap.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (e.g., get_incident, resolve_incident, list_incidents). The only slight deviation is get_my_incidents and get_oncall, but they still fit the verb_noun convention clearly.

Tool Count5/5

With 9 tools, the server is well-scoped for incident management and on-call visibility. Each tool serves a distinct purpose without redundancy or unnecessary bloat.

Completeness4/5

The server covers the core incident lifecycle: list, view, acknowledge, resolve, add notes, plus related context (alerts, timeline, on-call). However, it lacks the ability to create or reassign incidents, which are common operational actions, representing a minor gap.

Maintenance

ActivityInactive
ResponsivenessNo issues