Skip to main content
Glama
ennuiii

Azure DevOps MCP Server with PAT Authentication

by ennuiii

advsec_get_alerts

Retrieve Azure DevOps Advanced Security alerts for a repository, filtering by type, state, severity, or rule. Manage code and dependency vulnerabilities effectively with specified criteria.

Instructions

Retrieve Advanced Security alerts for a repository.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
alertTypeNoFilter alerts by type. If not specified, returns all alert types.
confidenceLevelsYesFilter alerts by confidence levels. Only applicable for secret alerts. Defaults to both 'high' and 'other'.
continuationTokenNoContinuation token for pagination.
onlyDefaultBranchNoIf true, only return alerts found on the default branch. Defaults to true.
orderByNoOrder results by specified field. Defaults to 'severity'.severity
projectYesThe name or ID of the Azure DevOps project.
refNoFilter alerts by git reference (branch). If not provided and onlyDefaultBranch is true, only includes alerts from default branch.
repositoryYesThe name or ID of the repository to get alerts for.
ruleIdNoFilter alerts by rule ID.
ruleNameNoFilter alerts by rule name.
severitiesNoFilter alerts by severity level. If not specified, returns alerts at any severity.
statesNoFilter alerts by state. If not specified, returns alerts in any state.
toolNameNoFilter alerts by tool name.
topNoMaximum number of alerts to return. Defaults to 100.
validityNoFilter alerts by validity status. Only applicable for secret alerts.

Implementation Reference

  • The handler function that implements the core logic of the 'advsec_get_alerts' tool. It constructs filter criteria from input parameters, calls the Azure DevOps Alert API to retrieve alerts, and returns the results as JSON or an error message.
    async ({ project, repository, alertType, states, severities, ruleId, ruleName, toolName, ref, onlyDefaultBranch, confidenceLevels, validity, top, orderBy, continuationToken }) => {
      try {
        const connection = await connectionProvider();
        const alertApi = await connection.getAlertApi();
    
        const isSecretAlert = !alertType || alertType.toLowerCase() === "secret";
        const criteria = {
          ...(alertType && { alertType: mapStringToEnum(alertType, AlertType) }),
          ...(states && { states: mapStringArrayToEnum(states, State) }),
          ...(severities && { severities: mapStringArrayToEnum(severities, Severity) }),
          ...(ruleId && { ruleId }),
          ...(ruleName && { ruleName }),
          ...(toolName && { toolName }),
          ...(ref && { ref }),
          ...(onlyDefaultBranch !== undefined && { onlyDefaultBranch }),
          ...(isSecretAlert && confidenceLevels && { confidenceLevels: mapStringArrayToEnum(confidenceLevels, Confidence) }),
          ...(isSecretAlert && validity && { validity: mapStringArrayToEnum(validity, AlertValidityStatus) }),
        };
    
        const result = await alertApi.getAlerts(
          project,
          repository,
          top,
          orderBy,
          criteria,
          undefined, // expand parameter
          continuationToken
        );
    
        return {
          content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
        };
      } catch (error) {
        const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
    
        return {
          content: [
            {
              type: "text",
              text: `Error fetching Advanced Security alerts: ${errorMessage}`,
            },
          ],
          isError: true,
        };
      }
    }
  • The Zod input schema defining all parameters for the 'advsec_get_alerts' tool, including filters for alerts, pagination, and repository details.
    {
      project: z.string().describe("The name or ID of the Azure DevOps project."),
      repository: z.string().describe("The name or ID of the repository to get alerts for."),
      alertType: z
        .enum(getEnumKeys(AlertType) as [string, ...string[]])
        .optional()
        .describe("Filter alerts by type. If not specified, returns all alert types."),
      states: z
        .array(z.enum(getEnumKeys(State) as [string, ...string[]]))
        .optional()
        .describe("Filter alerts by state. If not specified, returns alerts in any state."),
      severities: z
        .array(z.enum(getEnumKeys(Severity) as [string, ...string[]]))
        .optional()
        .describe("Filter alerts by severity level. If not specified, returns alerts at any severity."),
      ruleId: z.string().optional().describe("Filter alerts by rule ID."),
      ruleName: z.string().optional().describe("Filter alerts by rule name."),
      toolName: z.string().optional().describe("Filter alerts by tool name."),
      ref: z.string().optional().describe("Filter alerts by git reference (branch). If not provided and onlyDefaultBranch is true, only includes alerts from default branch."),
      onlyDefaultBranch: z.boolean().optional().default(true).describe("If true, only return alerts found on the default branch. Defaults to true."),
      confidenceLevels: z
        .array(z.enum(getEnumKeys(Confidence) as [string, ...string[]]))
        .optional()
        .default(["high", "other"])
        .describe("Filter alerts by confidence levels. Only applicable for secret alerts. Defaults to both 'high' and 'other'."),
      validity: z
        .array(z.enum(getEnumKeys(AlertValidityStatus) as [string, ...string[]]))
        .optional()
        .describe("Filter alerts by validity status. Only applicable for secret alerts."),
      top: z.number().optional().default(100).describe("Maximum number of alerts to return. Defaults to 100."),
      orderBy: z.enum(["id", "firstSeen", "lastSeen", "fixedOn", "severity"]).optional().default("severity").describe("Order results by specified field. Defaults to 'severity'."),
      continuationToken: z.string().optional().describe("Continuation token for pagination."),
    },
  • Registers the 'advsec_get_alerts' tool on the MCP server using server.tool(), providing the tool name, description, input schema, and handler function.
      ADVSEC_TOOLS.get_alerts,
      "Retrieve Advanced Security alerts for a repository.",
      {
        project: z.string().describe("The name or ID of the Azure DevOps project."),
        repository: z.string().describe("The name or ID of the repository to get alerts for."),
        alertType: z
          .enum(getEnumKeys(AlertType) as [string, ...string[]])
          .optional()
          .describe("Filter alerts by type. If not specified, returns all alert types."),
        states: z
          .array(z.enum(getEnumKeys(State) as [string, ...string[]]))
          .optional()
          .describe("Filter alerts by state. If not specified, returns alerts in any state."),
        severities: z
          .array(z.enum(getEnumKeys(Severity) as [string, ...string[]]))
          .optional()
          .describe("Filter alerts by severity level. If not specified, returns alerts at any severity."),
        ruleId: z.string().optional().describe("Filter alerts by rule ID."),
        ruleName: z.string().optional().describe("Filter alerts by rule name."),
        toolName: z.string().optional().describe("Filter alerts by tool name."),
        ref: z.string().optional().describe("Filter alerts by git reference (branch). If not provided and onlyDefaultBranch is true, only includes alerts from default branch."),
        onlyDefaultBranch: z.boolean().optional().default(true).describe("If true, only return alerts found on the default branch. Defaults to true."),
        confidenceLevels: z
          .array(z.enum(getEnumKeys(Confidence) as [string, ...string[]]))
          .optional()
          .default(["high", "other"])
          .describe("Filter alerts by confidence levels. Only applicable for secret alerts. Defaults to both 'high' and 'other'."),
        validity: z
          .array(z.enum(getEnumKeys(AlertValidityStatus) as [string, ...string[]]))
          .optional()
          .describe("Filter alerts by validity status. Only applicable for secret alerts."),
        top: z.number().optional().default(100).describe("Maximum number of alerts to return. Defaults to 100."),
        orderBy: z.enum(["id", "firstSeen", "lastSeen", "fixedOn", "severity"]).optional().default("severity").describe("Order results by specified field. Defaults to 'severity'."),
        continuationToken: z.string().optional().describe("Continuation token for pagination."),
      },
      async ({ project, repository, alertType, states, severities, ruleId, ruleName, toolName, ref, onlyDefaultBranch, confidenceLevels, validity, top, orderBy, continuationToken }) => {
        try {
          const connection = await connectionProvider();
          const alertApi = await connection.getAlertApi();
    
          const isSecretAlert = !alertType || alertType.toLowerCase() === "secret";
          const criteria = {
            ...(alertType && { alertType: mapStringToEnum(alertType, AlertType) }),
            ...(states && { states: mapStringArrayToEnum(states, State) }),
            ...(severities && { severities: mapStringArrayToEnum(severities, Severity) }),
            ...(ruleId && { ruleId }),
            ...(ruleName && { ruleName }),
            ...(toolName && { toolName }),
            ...(ref && { ref }),
            ...(onlyDefaultBranch !== undefined && { onlyDefaultBranch }),
            ...(isSecretAlert && confidenceLevels && { confidenceLevels: mapStringArrayToEnum(confidenceLevels, Confidence) }),
            ...(isSecretAlert && validity && { validity: mapStringArrayToEnum(validity, AlertValidityStatus) }),
          };
    
          const result = await alertApi.getAlerts(
            project,
            repository,
            top,
            orderBy,
            criteria,
            undefined, // expand parameter
            continuationToken
          );
    
          return {
            content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
          };
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : "Unknown error occurred";
    
          return {
            content: [
              {
                type: "text",
                text: `Error fetching Advanced Security alerts: ${errorMessage}`,
              },
            ],
            isError: true,
          };
        }
      }
    );
  • src/tools.ts:29-29 (registration)
    Top-level call to configure and register Advanced Security tools, including 'advsec_get_alerts', as part of configuring all tools.
    configureAdvSecTools(server, tokenProvider, connectionProvider);
  • Constant object defining the string name for the 'advsec_get_alerts' tool used in registration.
    const ADVSEC_TOOLS = {
      get_alerts: "advsec_get_alerts",
      get_alert_details: "advsec_get_alert_details",
    };
Behavior2/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions retrieval but fails to describe key traits like pagination behavior (implied by 'continuationToken' in schema), rate limits, authentication needs, or what the return format looks like. This is inadequate for a tool with 15 parameters and no output schema.

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

Conciseness5/5

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

The description is a single, direct sentence that efficiently conveys the core purpose without unnecessary words. It is front-loaded and appropriately sized for the tool's complexity, making it easy to parse quickly.

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

Completeness2/5

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

Given the tool's complexity (15 parameters, no output schema, and no annotations), the description is insufficient. It does not explain the return structure, pagination, error handling, or behavioral nuances, leaving significant gaps for the agent to operate effectively in a real-world context.

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

Parameters3/5

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

The input schema has 100% description coverage, so parameters are well-documented in the schema itself. The description does not add any meaningful semantic context beyond what the schema provides, such as explaining interactions between parameters or usage examples. This meets the baseline for high schema coverage.

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

Purpose4/5

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

The description clearly states the action ('Retrieve') and resource ('Advanced Security alerts for a repository'), making the purpose specific and understandable. However, it does not explicitly differentiate from its sibling 'advsec_get_alert_details', which likely fetches details for a specific alert, so it misses full sibling distinction.

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

Usage Guidelines2/5

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

The description provides no guidance on when to use this tool versus alternatives, such as its sibling 'advsec_get_alert_details' or other alert-related tools. It lacks context on prerequisites, timing, or exclusions, leaving the agent to infer usage based on the tool name alone.

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/ennuiii/DevOpsMcpPAT'

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