Skip to main content
Glama
alerting.ts15 kB
import { z } from 'zod'; import { zodToJsonSchema } from 'zod-to-json-schema'; import { ToolRegistry } from '../tool-registry.js'; import { AlertingService } from '../services/alerting.js'; /** * Register alerting-related MCP tools */ export function registerAlertingTools( registry: ToolRegistry, alertingService: AlertingService, ) { // List alert rules registry.registerTool( { name: 'list_alert_rules', description: 'List all alert rules in Grafana', inputSchema: zodToJsonSchema( z.object({ folderUID: z.string().optional(), ruleGroup: z.string().optional(), }), ), }, async (request) => { try { const { folderUID, ruleGroup } = request.params.arguments as { folderUID?: string; ruleGroup?: string; }; let rules = await alertingService.listAlertRules(); // Filter by folderUID if provided if (folderUID) { rules = rules.filter((rule) => rule.folderUID === folderUID); } // Filter by ruleGroup if provided if (ruleGroup) { rules = rules.filter((rule) => rule.ruleGroup === ruleGroup); } return { content: [ { type: 'text', text: `**Alert Rules (${rules.length} total)**\\n\\n${rules .map( (rule) => `**${rule.title}** (${rule.uid})\\n` + ` Folder: ${rule.folderUID}\\n` + ` Rule Group: ${rule.ruleGroup}\\n` + ` Condition: ${rule.condition}\\n` + ` Interval: ${rule.intervalSeconds}s\\n` + ` For: ${rule.for}\\n` + ` No Data State: ${rule.noDataState}\\n` + ` Exec Error State: ${rule.execErrState}\\n` + ` Updated: ${rule.updated}`, ) .join('\\n\\n')}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error listing alert rules: ${errorMessage}`, }, ], isError: true, }; } }, ); // Get alert rule by UID registry.registerTool( { name: 'get_alert_rule', description: 'Get detailed information about a specific alert rule', inputSchema: zodToJsonSchema( z.object({ uid: z.string().min(1), }), ), }, async (request) => { try { const { uid } = request.params.arguments as { uid: string }; const rule = await alertingService.getAlertRuleByUid(uid); return { content: [ { type: 'text', text: `**Alert Rule: ${rule.title}**\\n\\n` + '**Basic Information:**\\n' + `- UID: ${rule.uid}\\n` + `- Title: ${rule.title}\\n` + `- Folder UID: ${rule.folderUID}\\n` + `- Rule Group: ${rule.ruleGroup}\\n` + `- Org ID: ${rule.orgID}\\n\\n` + '**Configuration:**\\n' + `- Condition: ${rule.condition}\\n` + `- Interval: ${rule.intervalSeconds} seconds\\n` + `- For Duration: ${rule.for}\\n` + `- No Data State: ${rule.noDataState}\\n` + `- Execution Error State: ${rule.execErrState}\\n\\n` + '**Metadata:**\\n' + `- Updated: ${rule.updated}\\n\\n` + `**Labels:**\\n${ Object.keys(rule.labels).length > 0 ? Object.entries(rule.labels) .map(([key, value]) => `- ${key}: ${value}`) .join('\\n') : 'No labels defined' }\\n\\n` + `**Annotations:**\\n${ Object.keys(rule.annotations).length > 0 ? Object.entries(rule.annotations) .map(([key, value]) => `- ${key}: ${value}`) .join('\\n') : 'No annotations defined' }\\n\\n` + `**Query Data:**\\n${rule.data .map( (query: any, index: number) => `Query ${index + 1}: ${JSON.stringify(query, null, 2)}`, ) .join('\\n\\n')}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error getting alert rule: ${errorMessage}`, }, ], isError: true, }; } }, ); // Create alert rule registry.registerTool( { name: 'create_alert_rule', description: 'Create a new alert rule', inputSchema: zodToJsonSchema( z.object({ title: z.string().min(1), condition: z.string().min(1), data: z.array(z.any()), folderUID: z.string().min(1), ruleGroup: z.string().min(1), intervalSeconds: z.number().default(60), forDuration: z.string().default('5m'), noDataState: z.enum(['NoData', 'Alerting', 'OK']).default('NoData'), execErrState: z.enum(['Alerting', 'OK']).default('Alerting'), labels: z.record(z.string()).optional(), annotations: z.record(z.string()).optional(), }), ), }, async (request) => { try { const params = request.params.arguments as any; const result = await alertingService.createAlertRule(params); return { content: [ { type: 'text', text: 'Alert rule created successfully:\\n\\n' + `- UID: ${result.uid}\\n` + `- Title: ${result.title}\\n` + `- Folder: ${result.folderUID}\\n` + `- Rule Group: ${result.ruleGroup}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error creating alert rule: ${errorMessage}`, }, ], isError: true, }; } }, ); // Update alert rule registry.registerTool( { name: 'update_alert_rule', description: 'Update an existing alert rule', inputSchema: zodToJsonSchema( z.object({ uid: z.string().min(1), title: z.string().optional(), condition: z.string().optional(), data: z.array(z.any()).optional(), intervalSeconds: z.number().optional(), forDuration: z.string().optional(), noDataState: z.enum(['NoData', 'Alerting', 'OK']).optional(), execErrState: z.enum(['Alerting', 'OK']).optional(), labels: z.record(z.string()).optional(), annotations: z.record(z.string()).optional(), }), ), }, async (request) => { try { const params = request.params.arguments as any; const result = await alertingService.updateAlertRule( params.uid, params, ); return { content: [ { type: 'text', text: 'Alert rule updated successfully:\\n\\n' + `- UID: ${result.uid}\\n` + `- Title: ${result.title}\\n` + `- Updated: ${result.updated}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error updating alert rule: ${errorMessage}`, }, ], isError: true, }; } }, ); // Delete alert rule registry.registerTool( { name: 'delete_alert_rule', description: 'Delete an alert rule by UID', inputSchema: zodToJsonSchema( z.object({ uid: z.string().min(1), }), ), }, async (request) => { try { const { uid } = request.params.arguments as { uid: string }; await alertingService.deleteAlertRule(uid); return { content: [ { type: 'text', text: `Alert rule ${uid} deleted successfully.`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error deleting alert rule: ${errorMessage}`, }, ], isError: true, }; } }, ); // List contact points registry.registerTool( { name: 'list_contact_points', description: 'List all notification contact points', inputSchema: zodToJsonSchema(z.object({})), }, async () => { try { const contactPoints = await alertingService.listContactPoints(); return { content: [ { type: 'text', text: `**Contact Points (${contactPoints.length} total)**\\n\\n${contactPoints .map( (cp) => `**${cp.name}** (${cp.uid})\\n` + ` Type: ${cp.type}\\n` + ` Disable Resolve Message: ${cp.disableResolveMessage}\\n` + ` Settings: ${Object.keys(cp.settings).length} configuration items`, ) .join('\\n\\n')}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error listing contact points: ${errorMessage}`, }, ], isError: true, }; } }, ); // Get contact point registry.registerTool( { name: 'get_contact_point', description: 'Get detailed information about a specific contact point', inputSchema: zodToJsonSchema( z.object({ uid: z.string().min(1), }), ), }, async (request) => { try { const { uid } = request.params.arguments as { uid: string }; const contactPoint = await alertingService.getContactPointByUid(uid); return { content: [ { type: 'text', text: `**Contact Point: ${contactPoint.name}**\\n\\n` + `- UID: ${contactPoint.uid}\\n` + `- Type: ${contactPoint.type}\\n` + `- Disable Resolve Message: ${contactPoint.disableResolveMessage}\\n\\n` + `**Settings:**\\n${Object.entries(contactPoint.settings) .map( ([key, value]) => `- ${key}: ${typeof value === 'string' ? value : JSON.stringify(value)}`, ) .join('\\n')}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error getting contact point: ${errorMessage}`, }, ], isError: true, }; } }, ); // Test contact point registry.registerTool( { name: 'test_contact_point', description: 'Send a test notification to a contact point', inputSchema: zodToJsonSchema( z.object({ uid: z.string().min(1), message: z .string() .default('Test notification from Grafana MCP Server'), }), ), }, async (request) => { try { const { uid, message = 'Test notification from Grafana MCP Server' } = request.params.arguments as { uid: string; message?: string; }; const contactPoint = await alertingService.getContactPointByUid(uid); const result = await alertingService.testContactPoint(contactPoint); return { content: [ { type: 'text', text: `Test notification sent to contact point ${uid}:\\n\\n` + `Status: ${result.status || 'Success'}\\n` + `Message: ${message}\\n${ result.details ? `Details: ${JSON.stringify(result.details, null, 2)}` : '' }`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error testing contact point: ${errorMessage}`, }, ], isError: true, }; } }, ); // Get alert rule groups registry.registerTool( { name: 'list_alert_rule_groups', description: 'List all alert rule groups', inputSchema: zodToJsonSchema( z.object({ folderUID: z.string().optional(), }), ), }, async (request) => { try { const { folderUID: _folderUID } = request.params.arguments as { folderUID?: string; }; const groups = await alertingService.getAlertRuleGroups(); return { content: [ { type: 'text', text: `**Alert Rule Groups (${groups.length} total)**\\n\\n${groups .map( (group: any) => `**${group.name}**\\n` + ` Folder: ${group.folderUID}\\n` + ` Interval: ${group.interval}\\n` + ` Rules: ${group.rules.length}`, ) .join('\\n\\n')}`, }, ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; return { content: [ { type: 'text', text: `Error listing alert rule groups: ${errorMessage}`, }, ], isError: true, }; } }, ); }

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/quanticsoul4772/grafana-mcp'

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