Skip to main content
Glama
metrxbots

Metrx MCP Server

by metrxbots

Configure Alert Threshold

metrx_configure_alert_threshold
Idempotent

Configure cost or operational alert thresholds to trigger notifications or pause agents automatically for real-time governance and safety monitoring.

Instructions

Set up cost or operational alert thresholds for a specific agent or org-wide. Alerts can trigger email notifications, webhooks, or automatically pause the agent. Use for real-time cost governance and operational safety. Thresholds run server-side automatically. Do NOT use for viewing current alerts — use get_alerts instead.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
agent_idNoSpecific agent UUID to configure alerts for. Omit for org-wide alerts.
metricYesMetric to monitor
threshold_valueYesThreshold value. For costs: cents (e.g., 500000 = $5000). For rates: decimal (e.g., 0.1 = 10%). For latency: ms.
actionYesAction to trigger when threshold is breached

Implementation Reference

  • Handler function that executes the configure_alert_threshold tool logic. It constructs the API request path based on whether an agent_id is provided (for org-wide or agent-specific alerts), makes a POST request to the API, and formats the response with the configured threshold details.
    async ({ agent_id, metric, threshold_value, action }) => {
      const scope = agent_id ? `agent/${agent_id}` : 'org-wide';
      const path = agent_id ? `/agents/${agent_id}/alerts` : '/alerts/thresholds';
    
      const body: Record<string, unknown> = {
        metric,
        threshold_value,
        action,
      };
    
      const result = await client.post<{
        configured: boolean;
        threshold_id: string;
        message: string;
      }>(path, body);
    
      if (result.error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error configuring alert threshold: ${result.error}`,
            },
          ],
          isError: true,
        };
      }
    
      const data = result.data!;
      if (!data.configured) {
        return {
          content: [
            {
              type: 'text',
              text: `Alert configuration failed: ${data.message || 'Unknown reason'}`,
            },
          ],
          isError: true,
        };
      }
    
      const text = formatAlertConfigResponse(
        data.threshold_id,
        scope,
        metric,
        threshold_value,
        action
      );
    
      return {
        content: [{ type: 'text', text }],
      };
    }
  • Input schema definition for the configure_alert_threshold tool using zod. Validates agent_id (optional UUID), metric (enum: daily_cost, monthly_cost, error_rate, latency_p99), threshold_value (positive number), and action (enum: email, webhook, pause_agent).
    inputSchema: {
      agent_id: z
        .string()
        .uuid()
        .optional()
        .describe('Specific agent UUID to configure alerts for. Omit for org-wide alerts.'),
      metric: z
        .enum(['daily_cost', 'monthly_cost', 'error_rate', 'latency_p99'])
        .describe('Metric to monitor'),
      threshold_value: z
        .number()
        .positive()
        .describe(
          'Threshold value. For costs: cents (e.g., 500000 = $5000). ' +
            'For rates: decimal (e.g., 0.1 = 10%). For latency: ms.'
        ),
      action: z
        .enum(['email', 'webhook', 'pause_agent'])
        .describe('Action to trigger when threshold is breached'),
    },
  • Tool registration block where configure_alert_threshold is registered with the MCP server. Includes the tool metadata, description, inputSchema, annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint), and the handler function.
    server.registerTool(
      'configure_alert_threshold',
      {
        title: 'Configure Alert Threshold',
        description:
          'Set up cost or operational alert thresholds for a specific agent or org-wide. ' +
          'Alerts can trigger email notifications, webhooks, or automatically pause the agent. ' +
          'Use for real-time cost governance and operational safety. Thresholds run server-side automatically. ' +
          'Do NOT use for viewing current alerts — use get_alerts instead.',
        inputSchema: {
          agent_id: z
            .string()
            .uuid()
            .optional()
            .describe('Specific agent UUID to configure alerts for. Omit for org-wide alerts.'),
          metric: z
            .enum(['daily_cost', 'monthly_cost', 'error_rate', 'latency_p99'])
            .describe('Metric to monitor'),
          threshold_value: z
            .number()
            .positive()
            .describe(
              'Threshold value. For costs: cents (e.g., 500000 = $5000). ' +
                'For rates: decimal (e.g., 0.1 = 10%). For latency: ms.'
            ),
          action: z
            .enum(['email', 'webhook', 'pause_agent'])
            .describe('Action to trigger when threshold is breached'),
        },
        annotations: {
          readOnlyHint: false,
          destructiveHint: false,
          idempotentHint: true,
          openWorldHint: false,
        },
      },
      async ({ agent_id, metric, threshold_value, action }) => {
        const scope = agent_id ? `agent/${agent_id}` : 'org-wide';
        const path = agent_id ? `/agents/${agent_id}/alerts` : '/alerts/thresholds';
    
        const body: Record<string, unknown> = {
          metric,
          threshold_value,
          action,
        };
    
        const result = await client.post<{
          configured: boolean;
          threshold_id: string;
          message: string;
        }>(path, body);
    
        if (result.error) {
          return {
            content: [
              {
                type: 'text',
                text: `Error configuring alert threshold: ${result.error}`,
              },
            ],
            isError: true,
          };
        }
    
        const data = result.data!;
        if (!data.configured) {
          return {
            content: [
              {
                type: 'text',
                text: `Alert configuration failed: ${data.message || 'Unknown reason'}`,
              },
            ],
            isError: true,
          };
        }
    
        const text = formatAlertConfigResponse(
          data.threshold_id,
          scope,
          metric,
          threshold_value,
          action
        );
    
        return {
          content: [{ type: 'text', text }],
        };
      }
    );
  • Helper function formatAlertConfigResponse that formats the alert configuration confirmation into a readable markdown response. It formats threshold values based on metric type (costs in dollars, error_rate as percentage, latency_p99 as milliseconds) and describes the action behavior.
    function formatAlertConfigResponse(
      thresholdId: string,
      scope: string,
      metric: string,
      thresholdValue: number,
      action: string
    ): string {
      const lines: string[] = ['## Alert Threshold Configured', ''];
    
      lines.push(`**Threshold ID**: ${thresholdId}`);
      lines.push(`**Scope**: ${scope}`);
      lines.push(`**Metric**: ${metric}`);
    
      // Format threshold value based on metric type
      let thresholdDisplay = '';
      if (metric === 'daily_cost' || metric === 'monthly_cost') {
        thresholdDisplay = formatCents(thresholdValue);
      } else if (metric === 'error_rate') {
        thresholdDisplay = `${(thresholdValue * 100).toFixed(2)}%`;
      } else if (metric === 'latency_p99') {
        thresholdDisplay = `${thresholdValue.toFixed(0)}ms`;
      }
    
      lines.push(`**Threshold**: ${thresholdDisplay}`);
      lines.push(`**Action**: ${action}`);
      lines.push('');
    
      lines.push('### Behavior');
      switch (action) {
        case 'email':
          lines.push(
            'When the threshold is breached, an email notification will be sent to account owners.'
          );
          break;
        case 'webhook':
          lines.push(
            'When the threshold is breached, a POST request will be sent to configured webhook endpoints.'
          );
          break;
        case 'pause_agent':
          lines.push(
            'When the threshold is breached, the agent will be automatically paused to prevent further spend.'
          );
          break;
      }
    
      lines.push('');
      lines.push(`✅ Alert threshold is now active and being monitored in real-time.`);
    
      return lines.join('\n');
    }
  • src/index.ts:74-103 (registration)
    Middleware wrapper in index.ts that automatically adds the 'metrx_' prefix to all tool registrations. The original 'configure_alert_threshold' becomes 'metrx_configure_alert_threshold'. Also wraps handlers with rate limiting (60 requests per minute).
    // ── Rate limiting middleware + metrx_ namespace prefix ──
    // All tools are registered exclusively as metrx_{name}.
    // The metrx_ prefix namespaces our tools to avoid collisions when
    // multiple MCP servers are used together.
    const METRX_PREFIX = 'metrx_';
    const originalRegisterTool = server.registerTool.bind(server);
    (server as any).registerTool = function (
      name: string,
      config: any,
      handler: (...handlerArgs: any[]) => Promise<any>
    ) {
      const wrappedHandler = async (...handlerArgs: any[]) => {
        if (!rateLimiter.isAllowed(name)) {
          return {
            content: [
              {
                type: 'text' as const,
                text: `Rate limit exceeded for tool '${name}'. Maximum 60 requests per minute allowed.`,
              },
            ],
            isError: true,
          };
        }
        return handler(...handlerArgs);
      };
    
      // Register with metrx_ prefix (only — no deprecated aliases)
      const prefixedName = name.startsWith(METRX_PREFIX) ? name : `${METRX_PREFIX}${name}`;
      originalRegisterTool(prefixedName, config, wrappedHandler);
    };
Behavior4/5

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

The description adds valuable behavioral context beyond annotations: it explains that 'Thresholds run server-side automatically' and mentions the types of notifications (email, webhooks, pause agent). While annotations cover idempotency and non-destructive nature, the description provides operational details that enhance understanding without contradicting annotations.

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 efficiently structured with four sentences, each adding distinct value: purpose, usage context, operational detail, and exclusion guidance. It's front-loaded with the core function and avoids any redundant or unnecessary information.

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 tool's complexity (configuration with multiple parameters) and lack of output schema, the description provides good context about what the tool does and when to use it. However, it doesn't detail the response format or potential error cases, leaving some gaps in completeness.

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?

With 100% schema description coverage, the input schema already documents all parameters thoroughly. The description doesn't add significant semantic details about parameters beyond what's in the schema, so it meets the baseline of 3 for adequate but not enhanced parameter explanation.

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 specific action ('Set up cost or operational alert thresholds') and resource ('for a specific agent or org-wide'), distinguishing it from siblings like 'get_alerts' for viewing alerts. It explicitly mentions the tool's scope and purpose beyond just the title.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool ('for real-time cost governance and operational safety') and when not to use it ('Do NOT use for viewing current alerts — use get_alerts instead'), naming a specific alternative. This clearly differentiates it from sibling tools.

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

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/metrxbots/metrx-mcp-server'

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