@quorum-us/opsgenie-mcp
Version:
MCP server for Opsgenie alert management with comprehensive filtering, custom queries, and AI-friendly interface
136 lines (135 loc) • 3.84 kB
JavaScript
/**
* Constants and utility functions for Opsgenie MCP Server
*/
import { ALERT_STATES, ALERT_SORT_FIELDS, SORT_ORDERS, ALERT_STATUSES } from './types.js';
/**
* Default values for various operations
*/
export const DEFAULTS = {
// Alert defaults
ALERT_LIMIT: 20,
ALERT_OFFSET: 0,
ALERT_SORT: ALERT_SORT_FIELDS.LAST_OCCURRED_AT,
ALERT_ORDER: SORT_ORDERS.DESC,
ALERT_STATE: ALERT_STATES.ALL,
// API defaults
BASE_URL: 'https://api.opsgenie.com/v2',
TIMEOUT: 30000,
};
/**
* API endpoints
*/
export const ENDPOINTS = {
ALERTS: '/alerts',
ALERT_BY_ID: (id) => `/alerts/${id}`,
};
/**
* Error messages
*/
export const ERROR_MESSAGES = {
API_KEY_MISSING: 'Opsgenie API key is not set in the environment variable OPSGENIE_API_KEY.',
INVALID_IDENTIFIER: 'Alert identifier is required and cannot be empty.',
INVALID_LIMIT: 'Limit must be between 1 and 100.',
INVALID_OFFSET: 'Offset must be a non-negative number.',
UNKNOWN_ERROR: 'An unknown error occurred.',
};
/**
* Validation limits
*/
export const LIMITS = {
MIN_LIMIT: 1,
MAX_LIMIT: 100,
MIN_OFFSET: 0,
};
/**
* Utility function to validate limit parameter
*/
export function validateLimit(limit) {
if (limit === undefined) {
return DEFAULTS.ALERT_LIMIT;
}
if (limit < LIMITS.MIN_LIMIT || limit > LIMITS.MAX_LIMIT) {
throw new Error(ERROR_MESSAGES.INVALID_LIMIT);
}
return limit;
}
/**
* Utility function to validate offset parameter
*/
export function validateOffset(offset) {
if (offset === undefined) {
return DEFAULTS.ALERT_OFFSET;
}
if (offset < LIMITS.MIN_OFFSET) {
throw new Error(ERROR_MESSAGES.INVALID_OFFSET);
}
return offset;
}
/**
* Utility function to validate alert identifier
*/
export function validateIdentifier(identifier) {
if (!identifier || identifier.trim().length === 0) {
throw new Error(ERROR_MESSAGES.INVALID_IDENTIFIER);
}
}
/**
* Utility function to build query parameters
*/
export function buildQueryParams(params) {
const result = {};
for (const [key, value] of Object.entries(params)) {
if (value !== undefined && value !== null) {
result[key] = value;
}
}
return result;
}
/**
* Build Opsgenie search query from filter options
* If a custom query is provided, it takes precedence over other filters
*/
export function buildSearchQuery(filter) {
// If a custom query is provided, use it as-is (AI has full control)
if (filter.query) {
return filter.query;
}
// Otherwise, build query from individual filters
const queryParts = [];
// Add status filter
if (filter.status && filter.status !== ALERT_STATUSES.ALL) {
queryParts.push(`status: ${filter.status}`);
}
// Add priority filter
if (filter.priority) {
queryParts.push(`priority: ${filter.priority}`);
}
// Add message filter
if (filter.message) {
queryParts.push(`message: ${filter.message}*`);
}
// Add source filter
if (filter.source) {
queryParts.push(`source: ${filter.source}`);
}
// Add owner filter
if (filter.owner) {
queryParts.push(`owner: ${filter.owner}`);
}
// Add tags filter (all tags must match)
if (filter.tags && filter.tags.length > 0) {
const tagQueries = filter.tags.map(tag => `tag: ${tag}`);
queryParts.push(...tagQueries);
}
// Add teams filter
if (filter.teams && filter.teams.length > 0) {
const teamQueries = filter.teams.map(team => `teams: ${team}`);
if (teamQueries.length === 1) {
queryParts.push(teamQueries[0]);
}
else {
queryParts.push(`(${teamQueries.join(' OR ')})`);
}
}
return queryParts.join(' AND ');
}