Skip to main content
Glama
PagerDuty MCP Server

PagerDuty MCP Server

by wpfleger96

PagerDuty MCP Server

A server that exposes PagerDuty API functionality to LLMs. This server is designed to be used programmatically, with structured inputs and outputs.

PyPI Downloads Python Versions GitHub Contributors Lines of Code PyPI version License

Overview

The PagerDuty MCP Server provides a set of tools for interacting with the PagerDuty API. These tools are designed to be used by LLMs to perform various operations on PagerDuty resources such as incidents, services, teams, and users.

Related MCP server: Logseq MCP Server

Getting Started

  1. Initialize your local Python environment:

cd pagerduty-mcp-server
brew install uv
uv sync
  1. Configure authentication (see Authentication below).

Authentication

Priority: X-PagerDuty-Token HTTP header > PAGERDUTY_API_TOKEN environment variable > OAuth 2.0 PKCE

Option 1: X-PagerDuty-Token Header (Platform Integration)

When running as part of a platform that injects per-request credentials, the server reads the X-PagerDuty-Token HTTP header. This takes highest priority and does not require any local configuration.

Set the PAGERDUTY_API_TOKEN environment variable, or add it to a .env file in the project root. The server will automatically load environment variables from the .env file if present.

Environment variable:

export PAGERDUTY_API_TOKEN=your_api_token_here

.env file (recommended):

echo "PAGERDUTY_API_TOKEN=your_api_token_here" > .env

Option 3: OAuth 2.0 PKCE (Local Interactive Use)

OAuth is available for local standalone usage. It opens a browser for authentication and stores tokens securely in the OS keyring. OAuth is opt-in — it only activates when PAGERDUTY_CLIENT_ID is set and no API token is present.

Setup:

  1. Register a PagerDuty OAuth application at Integrations → Developer Tools → My Apps.

  2. Set the required scope to read write.

  3. Set the redirect URI to http://localhost:5173/oauth/pagerduty (default port).

  4. Set the PAGERDUTY_CLIENT_ID environment variable to your application's client ID.

Optional configuration:

  • Set PAGERDUTY_CLIENT_SECRET to enable token refresh (confidential client).

  • Set PAGERDUTY_OAUTH_CALLBACK_PORT to override the default callback port (5173).

Usage

Claude/Cursor

{
  "mcpServers": {
    "pagerduty-mcp-server": {
      "command": "uvx",
      "args": ["pagerduty-mcp-server"],
      "env": {
          "PAGERDUTY_API_TOKEN": "<PAGERDUTY_API_TOKEN>"
      }
    }
  }
}

As Standalone Server

uv run pagerduty-mcp-server

Available Tools

Read Tools

  • get_escalation_policies — List or get details for escalation policies

  • get_incidents — List or get details for incidents (supports filtering by status, urgency, service, team, and time range)

  • get_oncalls — List on-call entries for a time range

  • get_schedules — List or get details for schedules

  • get_services — List or get details for services

  • get_teams — List or get details for teams

  • get_users — List or get details for users

  • list_users_oncall — List users on call for a specific schedule

  • build_user_context — Build a context object for the current authenticated user

Write Tools

  • acknowledge_incident — Acknowledge an incident (signals active investigation)

  • resolve_incident — Resolve an incident (stops further escalations)

  • add_incident_note — Add a note to an incident (for recording investigation progress or context)

The include Parameter

Most read tools accept an optional include parameter — a list of field names to return. When specified, only those fields are included in each response object, which reduces token usage in LLM contexts.

# Return only id, title, and status for each incident
get_incidents(include=["id", "title", "status"])

# Return only id and name for each service
get_services(include=["id", "name"])

See the tool documentation for the full list of available fields per tool.

Response Format

All API responses follow a consistent format:

{
  "metadata": {
    "count": "<int>",
    "description": "<str>"
  },
  "<resource_type>": [
    {
      "...": "..."
    }
  ],
  "error": {
    "message": "<str>",
    "code": "<str>"
  }
}

The error field is only present when an error occurs. Resource names in responses are always pluralized for consistency, even when a single item is returned.

Error Handling

When an error occurs, the response will include an error object with the following structure:

{
  "metadata": {
    "count": 0,
    "description": "Error occurred while processing request"
  },
  "error": {
    "message": "Invalid user ID provided",
    "code": "INVALID_USER_ID"
  }
}

Common error scenarios include:

  • Invalid resource IDs (e.g., user_id, team_id, service_id)

  • Missing required parameters

  • Invalid parameter values

  • API request failures

  • Response processing errors

Parameter Validation

  • All ID values (single-ID parameters and list filters such as team_ids) must contain only ASCII letters and digits; any other value returns an error

  • Date parameters must be valid ISO8601 timestamps

  • List parameters (e.g., statuses, team_ids) must contain valid values

  • In ID list filters, surrounding whitespace is stripped and blank IDs are ignored

  • Required parameters cannot be None or empty strings

  • For statuses in get_incidents, only triggered, acknowledged, and resolved are valid values

  • For urgency in incidents, only high and low are valid values

  • The limit parameter can be used to restrict the number of results returned by list operations

Rate Limiting and Pagination

  • The server respects PagerDuty's rate limits

  • The server automatically handles pagination for you

  • The limit parameter can be used to control the number of results returned by list operations

  • If no limit is specified, the server will return up to pagerduty_mcp_server.utils.RESPONSE_LIMIT results by default

User Context

Many functions accept a current_user_context parameter (defaults to True) which automatically filters results based on this context. When current_user_context is True, you cannot use certain filter parameters as they would conflict with the automatic filtering:

  • For incidents:

    • team_ids and service_ids cannot be used with current_user_context=True

    • Pass all_visible=True to list incidents across the whole account that the API token can see, not scoped to the current user; this implies current_user_context=False

  • For services:

    • team_ids cannot be used with current_user_context=True

  • For escalation policies:

    • user_ids and team_ids cannot be used with current_user_context=True

  • For users:

    • team_ids cannot be used with current_user_context=True

  • For on-calls:

    • user_ids and escalation_policy_ids cannot be used with current_user_context=True

    • schedule_ids can still be used to filter by specific schedules

    • The query will show on-calls for the escalation policies the current user is a target of

    • If the current user is not a target of any escalation policy and no schedule_ids are given, the tool returns an error; use current_user_context=False with explicit filters instead

Development

Running Tests

The test suite includes both unit tests and integration tests. Integration tests require a real connection to the PagerDuty API, while unit tests can run without API access.

The pytest-cov args are optional, use them to include a test coverage report in the output.

To run all tests (integration tests will be automatically skipped if PAGERDUTY_API_TOKEN is not set):

uv run pytest [--cov=src --cov-report=term-missing]

To run only unit tests (no API token required):

uv run pytest -m unit [--cov=src --cov-report=term-missing]

To run only integration tests (requires PAGERDUTY_API_TOKEN set in environment):

uv run pytest -m integration [--cov=src --cov-report=term-missing]

To run only tests related to a specific submodule:

uv run pytest -m <client|escalation_policies|...> [--cov=src --cov-report=term-missing]

Debug Server with MCP Inspector

npx @modelcontextprotocol/inspector uv run pagerduty-mcp-server

Documentation

Tool Documentation - Detailed information about available tools including parameters, return types, and example queries

Conventions

  • All API responses follow the standard format with metadata, resource list, and optional error

  • Resource names in responses are always pluralized for consistency

  • All functions that return a single item still return a list with one element

  • Error responses include both a message and a code

  • All timestamps are in ISO8601 format

  • Tests are marked with pytest markers to indicate their type (unit/integration) and the resource they test (incidents, teams, etc.)

Example Queries

  • Are there any incidents assigned to me currently in pagerduty?

  • Do I have any upcoming on call schedule in next 2 weeks?

  • Who else is a member of the personalization team?

Available Tools

12 tools
acknowledge_incidentB

Acknowledge a PagerDuty incident. This signals that someone is actively working on the incident.

Inputs: incident_id (required), include. Returns: object

add_incident_noteA

Add a note to a PagerDuty incident. Notes are used to record additional context, investigation progress, or resolution details.

Inputs: content (required), incident_id (required). Returns: object

build_user_contextA

Validate and build the current user's context into a dictionary with the following format: { "user_id": str, "team_ids": List[str], "service_ids": List[str], "escalation_policy_ids": List[str] } The MCP server tools use this user context to filter the following resources: - Escalation policies - Incidents - Oncalls - Services - Users

Inputs: no named parameters. Returns: object

get_escalation_policiesA

Get PagerDuty escalation policies by filters or get details for a specific policy ID.

Inputs: limit, query, include, team_ids, +3 more. Returns: object

get_incidentsB

Get PagerDuty incidents by filters or get details for a specific incident ID or number.

Inputs: limit, since, until, include, +10 more. Returns: object

get_oncallsA

List on-call entries for schedules, policies, or time ranges.

Behavior varies by time parameters:

  1. Without since/until: Returns current on-calls Example: get_oncalls(current_user_context=False, schedule_ids=["PSCHED123"])

  2. With since/until: Returns all on-calls in range Example: get_oncalls(current_user_context=False, schedule_ids=["PSCHED123"], since="2024-03-20T00:00:00Z", until="2024-03-27T00:00:00Z")

Inputs: limit, since, until, include, +5 more. Returns: object

get_schedulesB

Get PagerDuty schedules by filters or get details for a specific schedule ID.

Inputs: limit, query, since, until, +2 more. Returns: object

get_servicesB

Get PagerDuty services by filters or get details for a specific service ID.

Inputs: limit, query, include, team_ids, +2 more. Returns: object

get_teamsA

Get PagerDuty teams by filters or get details for a specific team ID.

Inputs: limit, query, include, team_id. Returns: object

get_usersB

Get PagerDuty users by filters or get details for a specific user ID.

Inputs: limit, query, include, user_id, +2 more. Returns: object

list_users_oncallC

List the users on call for a schedule during the specified time range.

Inputs: schedule_id (required), since, until, include. Returns: object

resolve_incidentA

Resolve a PagerDuty incident. This marks the incident as resolved and stops any further escalations.

Inputs: incident_id (required), include. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 12 tools

    Disambiguation4/5

    Most tools map to distinct resource+action pairs (get_incidents, get_schedules, get_services, etc.). The only real overlap is between get_oncalls and list_users_oncall, which both deal with on-call data, though their descriptions differentiate entry-level vs user-level queries.

    Naming Consistency4/5

    The set follows a clear verb_noun pattern (get_*, list_*, build_*, acknowledge_*, resolve_*, add_*), with the verb matching the action semantics. Minor deviation in mixing 'get_' and 'list_' prefixes for read operations, but overall predictable and readable.

    Tool Count5/5

    12 tools is well-scoped for a PagerDuty integration, covering the key read resources plus incident lifecycle actions without bloat. Each tool earns its place.

    Completeness3/5

    Incident lifecycle is partially covered (get, acknowledge, resolve, add note) but there is no create_incident or update/reassign incident, which are core PagerDuty operations. Read coverage across users, teams, services, schedules, and policies is solid, so the gap is notable but not crippling.

    Maintenance

    ActivityActive
    ResponsivenessLimited data

    Related MCP Connectors

    Related MCP Servers