Skip to main content
Glama
wpfleger96

PagerDuty MCP Server

by wpfleger96

get_incidents

Retrieve and filter PagerDuty incidents by ID, user context, service, team, status, date range, or include notes, past incidents, and related incidents for detailed insights.

Instructions

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

Args: incident_id (str): The incident ID or number to retrieve (optional, cannot be used with any other filters). current_user_context (bool): Filter by current user's context (default: True). Not used if incident_id is provided. service_ids (List[str]): Filter by services (optional, excludes current_user_context). Not used if incident_id is provided. team_ids (List[str]): Filter by teams (optional, excludes current_user_context). Not used if incident_id is provided. statuses (List[str]): Filter by status (optional). Not used if incident_id is provided. Must be input as a list of strings, valid values are ["triggered", "acknowledged", "resolved"]. since (str): Start of query range in ISO8601 format (default range: 1 month, max range: 6 months). Not used if incident_id is provided. until (str): End of query range in ISO8601 format (default range: 1 month, max range: 6 months). Not used if incident_id is provided. limit (int): Max results (optional). Not used if incident_id is provided. include_past_incidents (Optional[bool]): If True and incident_id is provided, includes similar past incidents in the response. Defaults to False. Cannot be used without incident_id. include_related_incidents (Optional[bool]): If True and incident_id is provided, includes related incidents impacting other services/responders in the response. Defaults to False. Cannot be used without incident_id. include_notes (Optional[bool]): If True, includes notes for each incident in the response. Defaults to False.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
current_user_contextNo
incident_idNo
include_notesNo
include_past_incidentsNo
include_related_incidentsNo
limitNo
service_idsNo
sinceNo
statusesNo
team_idsNo
untilNo

Implementation Reference

  • Primary handler and registration for the get_incidents tool via @mcp.tool(). Handles input validation, user context, and delegates to incidents.list_incidents() or incidents.show_incident().
    @mcp.tool()
    def get_incidents(
        *,
        incident_id: Optional[str] = None,
        current_user_context: bool = True,
        service_ids: Optional[List[str]] = None,
        team_ids: Optional[List[str]] = None,
        statuses: Optional[List[str]] = None,
        since: Optional[str] = None,
        until: Optional[str] = None,
        limit: Optional[int] = None,
        include_past_incidents: Optional[bool] = False,
        include_related_incidents: Optional[bool] = False,
        include_notes: Optional[bool] = False,
    ) -> Dict[str, Any]:
        """Get PagerDuty incidents by filters or get details for a specific incident ID or number.
    
        Args:
            incident_id (str): The incident ID or number to retrieve (optional, cannot be used with any other filters).
            current_user_context (bool): Filter by current user's context (default: True). Not used if `incident_id` is provided.
            service_ids (List[str]): Filter by services (optional, excludes current_user_context). Not used if `incident_id` is provided.
            team_ids (List[str]): Filter by teams (optional, excludes current_user_context). Not used if `incident_id` is provided.
            statuses (List[str]): Filter by status (optional). Not used if `incident_id` is provided. Must be input as a list of strings, valid values are `["triggered", "acknowledged", "resolved"]`.
            since (str): Start of query range in ISO8601 format (default range: 1 month, max range: 6 months). Not used if `incident_id` is provided.
            until (str): End of query range in ISO8601 format (default range: 1 month, max range: 6 months). Not used if `incident_id` is provided.
            limit (int): Max results (optional). Not used if `incident_id` is provided.
            include_past_incidents (Optional[bool]): If True and `incident_id` is provided, includes similar past incidents
                in the response. Defaults to False. Cannot be used without `incident_id`.
            include_related_incidents (Optional[bool]): If True and `incident_id` is provided, includes related incidents
                impacting other services/responders in the response. Defaults to False. Cannot be used without `incident_id`.
            include_notes (Optional[bool]): If True, includes notes for each incident in the response. Defaults to False.
        """
        if incident_id is not None:
            disallowed_filters_present = (
                service_ids is not None
                or team_ids is not None
                or statuses is not None
                or since is not None
                or until is not None
                or limit is not None
            )
            if disallowed_filters_present:
                raise ValueError(
                    "When `incident_id` is provided, other filters (like service_ids, team_ids, statuses, etc.) cannot be used. See `docs://tools` for more information."
                )
    
            incident_response = incidents.show_incident(
                incident_id=incident_id,
                include_past_incidents=include_past_incidents,
                include_related_incidents=include_related_incidents,
                include_notes=include_notes,
            )
    
            return incident_response
    
        if include_past_incidents or include_related_incidents or include_notes:
            raise ValueError(
                "`include_past_incidents`, `include_related_incidents`, and `include_notes` can only be used when a specific `incident_id` is provided. See `docs://tools` for more information."
            )
    
        if current_user_context:
            if service_ids is not None or team_ids is not None:
                raise ValueError(
                    "Cannot specify service_ids or team_ids when current_user_context is True. See `docs://tools` for more information."
                )
            user_context = users.build_user_context()
            team_ids = user_context["team_ids"]
            service_ids = user_context["service_ids"]
        elif not (service_ids or team_ids):
            raise ValueError(
                "Must specify at least service_ids or team_ids when current_user_context is False. See `docs://tools` for more information."
            )
    
        incidents_response = incidents.list_incidents(
            service_ids=service_ids,
            team_ids=team_ids,
            statuses=statuses,
            since=since,
            until=until,
            limit=limit,
        )
    
        return incidents_response
  • Core helper function for listing incidents with filtering, API calls to PagerDuty, parsing, and metadata calculation. Called by get_incidents handler.
    def list_incidents(
        *,
        service_ids: Optional[List[str]] = None,
        team_ids: Optional[List[str]] = None,
        statuses: Optional[List[str]] = None,
        urgencies: Optional[List[str]] = None,
        since: Optional[str] = None,
        until: Optional[str] = None,
        limit: Optional[int] = None,
    ) -> Dict[str, Any]:
        """List PagerDuty incidents based on specified filters. Exposed in `get_incidents`.
    
        Args:
            service_ids (List[str]): List of PagerDuty service IDs to filter by (optional)
            team_ids (List[str]): List of PagerDuty team IDs to filter by (optional)
            statuses (List[str]): List of status values to filter by (optional). Valid values are:
                - 'triggered' - The incident is currently active (included by default)
                - 'acknowledged' - The incident has been acknowledged by a user (included by default)
                - 'resolved' - The incident has been resolved (included by default)
                Defaults to ['triggered', 'acknowledged', 'resolved'] if not specified.
            urgencies (List[str]): List of urgency values to filter by (optional). Valid values are:
                - 'high' - High urgency incidents (included by default)
                - 'low' - Low urgency incidents (included by default)
                Defaults to ['high', 'low'] if not specified.
            since (str): Start of date range in ISO8601 format (optional). Default is 1 month ago
            until (str): End of date range in ISO8601 format (optional). Default is now
            limit (int): Limit the number of results returned (optional)
    
        Returns:
            See the "Standard Response Format" section in `tools.md` for the complete standard response structure.
            The response will contain a list of incidents with additional metadata about status counts and autoresolve counts.
    
        Raises:
            See the "Error Handling" section in `tools.md` for common error scenarios.
        """
        pd_client = create_client()
    
        if statuses is None:
            statuses = DEFAULT_STATUSES
        else:
            invalid_statuses = [s for s in statuses if s not in VALID_STATUSES]
            if invalid_statuses:
                raise ValueError(
                    f"Invalid status values: {invalid_statuses}. Valid values are: {VALID_STATUSES}"
                )
    
        if urgencies is None:
            urgencies = DEFAULT_URGENCIES
        else:
            invalid_urgencies = [u for u in urgencies if u not in VALID_URGENCIES]
            if invalid_urgencies:
                raise ValueError(
                    f"Invalid urgency values: {invalid_urgencies}. Valid values are: {VALID_URGENCIES}"
                )
    
        params = {"statuses": statuses, "urgencies": urgencies}
        if service_ids:
            params["service_ids"] = service_ids
        if team_ids:
            params["team_ids"] = team_ids
        if since is not None:
            utils.validate_iso8601_timestamp(since, "since")
            params["since"] = since
        if until is not None:
            utils.validate_iso8601_timestamp(until, "until")
            params["until"] = until
        if limit:
            params["limit"] = limit
    
        try:
            response = pd_client.list_all(INCIDENTS_URL, params=params)
            metadata = _calculate_incident_metadata(response)
            parsed_response = [parse_incident(result=result) for result in response]
    
            return utils.api_response_handler(
                results=parsed_response,
                resource_name="incidents",
                additional_metadata=metadata,
            )
        except Exception as e:
            utils.handle_api_error(e)
  • Core helper function for showing a single incident details, optionally fetching past incidents, related incidents, and notes. Called by get_incidents handler.
    def show_incident(
        *,
        incident_id: str,
        include_past_incidents: Optional[bool] = False,
        include_related_incidents: Optional[bool] = False,
        include_notes: Optional[bool] = False,
    ) -> Dict[str, Any]:
        """Get detailed information about a given incident. Exposed as MCP server tool.
    
        Args:
            incident_id (str): The ID or number of the incident to get
            include_past_incidents (Optional[bool]): If True, includes similar past incidents. Defaults to False.
            include_related_incidents (Optional[bool]): If True, includes related incidents. Defaults to False.
            include_notes (Optional[bool]): If True, includes notes for the incident. Defaults to False.
    
        Returns:
            See the "Standard Response Format" section in `tools.md` for the complete standard response structure.
            The response will contain a single incident in the standard format.
    
        Raises:
            See the "Error Handling" section in `tools.md` for common error scenarios.
        """
    
        if not incident_id:
            raise ValueError("incident_id cannot be empty")
    
        pd_client = create_client()
        params = {"include[]": "body"}
    
        try:
            incident_metadata = {}
    
            response = pd_client.jget(f"{INCIDENTS_URL}/{incident_id}", params=params)
            try:
                incident_data = response["incident"]
            except KeyError:
                raise RuntimeError(
                    f"Failed to fetch or process incident {incident_id}: 'incident'"
                )
    
            parsed_main_incident = parse_incident(result=incident_data)
    
            if include_past_incidents:
                try:
                    past_incidents_response = _list_past_incidents(incident_id=incident_id)
                    if past_incidents_response and past_incidents_response.get("incidents"):
                        parsed_main_incident["past_incidents"] = past_incidents_response[
                            "incidents"
                        ]
    
                    if parsed_main_incident.get("past_incidents"):
                        incident_metadata["past_incidents_count"] = len(
                            parsed_main_incident["past_incidents"]
                        )
                except Exception as e_past:
                    logger.error(
                        f"Error fetching past incidents for {incident_id}: {e_past}"
                    )
    
            if include_related_incidents:
                try:
                    related_incidents_response = _list_related_incidents(
                        incident_id=incident_id
                    )
                    if related_incidents_response and related_incidents_response.get(
                        "incidents"
                    ):
                        parsed_main_incident["related_incidents"] = (
                            related_incidents_response["incidents"]
                        )
    
                    if parsed_main_incident.get("related_incidents"):
                        incident_metadata["related_incidents_count"] = len(
                            parsed_main_incident["related_incidents"]
                        )
                except Exception as e_related:
                    logger.error(
                        f"Error fetching related incidents for {incident_id}: {e_related}"
                    )
    
            if include_notes:
                try:
                    notes_response = _list_notes(incident_id=incident_id)
                    if notes_response and notes_response.get("notes"):
                        parsed_main_incident["notes"] = notes_response["notes"]
    
                    if parsed_main_incident.get("notes"):
                        incident_metadata["notes_count"] = len(
                            parsed_main_incident["notes"]
                        )
                except Exception as e_notes:
                    logger.error(
                        f"Error fetching notes for incident {incident_id}: {e_notes}"
                    )
    
            return utils.api_response_handler(
                results=parsed_main_incident,
                resource_name="incident",
                additional_metadata=incident_metadata,
            )
        except Exception as e:
            utils.handle_api_error(e)
  • Input schema defined by function parameters and docstring in the handler.
    def get_incidents(
        *,
        incident_id: Optional[str] = None,
        current_user_context: bool = True,
        service_ids: Optional[List[str]] = None,
        team_ids: Optional[List[str]] = None,
        statuses: Optional[List[str]] = None,
        since: Optional[str] = None,
        until: Optional[str] = None,
        limit: Optional[int] = None,
        include_past_incidents: Optional[bool] = False,
        include_related_incidents: Optional[bool] = False,
        include_notes: Optional[bool] = False,
    ) -> Dict[str, Any]:
        """Get PagerDuty incidents by filters or get details for a specific incident ID or number.
    
        Args:
            incident_id (str): The incident ID or number to retrieve (optional, cannot be used with any other filters).
            current_user_context (bool): Filter by current user's context (default: True). Not used if `incident_id` is provided.
            service_ids (List[str]): Filter by services (optional, excludes current_user_context). Not used if `incident_id` is provided.
            team_ids (List[str]): Filter by teams (optional, excludes current_user_context). Not used if `incident_id` is provided.
            statuses (List[str]): Filter by status (optional). Not used if `incident_id` is provided. Must be input as a list of strings, valid values are `["triggered", "acknowledged", "resolved"]`.
            since (str): Start of query range in ISO8601 format (default range: 1 month, max range: 6 months). Not used if `incident_id` is provided.
            until (str): End of query range in ISO8601 format (default range: 1 month, max range: 6 months). Not used if `incident_id` is provided.
            limit (int): Max results (optional). Not used if `incident_id` is provided.
            include_past_incidents (Optional[bool]): If True and `incident_id` is provided, includes similar past incidents
                in the response. Defaults to False. Cannot be used without `incident_id`.
            include_related_incidents (Optional[bool]): If True and `incident_id` is provided, includes related incidents
                impacting other services/responders in the response. Defaults to False. Cannot be used without `incident_id`.
            include_notes (Optional[bool]): If True, includes notes for each incident in the response. Defaults to False.
        """
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Since no annotations are provided, the description carries the full burden of behavioral disclosure. It does well by explaining the two operational modes (filtered list vs. specific incident), default behaviors (current_user_context defaults to True), constraints (max range: 6 months), and response inclusions (notes, past incidents, related incidents). It could improve by mentioning pagination, rate limits, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized for an 11-parameter tool and well-structured with a clear opening statement followed by detailed parameter documentation. Every sentence serves a purpose, though the parameter explanations could be slightly more concise in places (e.g., repetitive 'Not used if incident_id is provided' phrases).

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (11 parameters, no annotations, no output schema), the description does an excellent job covering parameter semantics and behavioral context. It explains the two operational modes, constraints, defaults, and response inclusions. The main gap is the lack of output format description, which would be helpful since there's no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description fully compensates by providing comprehensive parameter documentation. Each of the 11 parameters gets clear explanations including purpose, constraints, default values, valid values (e.g., statuses), format requirements (ISO8601), and interdependencies (e.g., 'Not used if incident_id is provided'). This adds substantial meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('Get PagerDuty incidents by filters or get details for a specific incident ID or number'), identifies the resource ('PagerDuty incidents'), and distinguishes between two distinct modes of operation. It differentiates from sibling tools by focusing specifically on incidents rather than users, services, teams, or other PagerDuty entities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use different parameter combinations (e.g., 'cannot be used with any other filters' for incident_id, exclusions when incident_id is provided). However, it doesn't explicitly mention when to use this tool versus potential alternatives or provide guidance about prerequisites or authentication requirements.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wpfleger96/pagerduty-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server