datadog-mcp 1.1.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/schema.ts","../src/config/index.ts","../src/server.ts","../src/config/datadog.ts","../src/tools/monitors.ts","../src/errors/datadog.ts","../src/utils/format.ts","../src/utils/urls.ts","../src/tools/dashboards.ts","../src/tools/logs.ts","../src/utils/time.ts","../src/tools/metrics.ts","../src/tools/traces.ts","../src/tools/events.ts","../src/tools/incidents.ts","../src/tools/slos.ts","../src/tools/synthetics.ts","../src/tools/hosts.ts","../src/tools/downtimes.ts","../src/tools/rum.ts","../src/tools/security.ts","../src/tools/notebooks.ts","../src/tools/users.ts","../src/tools/teams.ts","../src/tools/tags.ts","../src/tools/usage.ts","../src/tools/auth.ts","../src/tools/index.ts","../src/transport/stdio.ts","../src/transport/http.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod'\n\n// All available tool names\nexport const ALL_TOOLS = [\n 'monitors',\n 'dashboards',\n 'logs',\n 'metrics',\n 'traces',\n 'events',\n 'incidents',\n 'slos',\n 'synthetics',\n 'hosts',\n 'downtimes',\n 'rum',\n 'security',\n 'notebooks',\n 'users',\n 'teams',\n 'tags',\n 'usage',\n 'auth'\n] as const\n\nexport type ToolName = (typeof ALL_TOOLS)[number]\n\nexport const configSchema = z.object({\n datadog: z.object({\n apiKey: z.string().min(1, 'DD_API_KEY is required'),\n appKey: z.string().min(1, 'DD_APP_KEY is required'),\n site: z.string().default('datadoghq.com')\n }),\n server: z\n .object({\n name: z.string().default('datadog-mcp'),\n version: z.string().default('1.0.0'),\n transport: z.enum(['stdio', 'http']).default('stdio'),\n port: z.number().default(3000),\n host: z.string().default('localhost')\n })\n .default({}),\n limits: z\n .object({\n maxResults: z.number().default(100),\n maxLogLines: z.number().default(100), // Reduced from 500 for token efficiency\n defaultLimit: z.number().default(25), // Default limit for initial queries\n maxMetricDataPoints: z.number().default(1000),\n defaultTimeRangeHours: z.number().default(24)\n })\n .default({}),\n features: z\n .object({\n readOnly: z.boolean().default(false),\n disabledTools: z.array(z.string()).default([])\n })\n .default({})\n})\n\nexport type Config = z.infer<typeof configSchema>\nexport type DatadogConfig = Config['datadog']\nexport type ServerConfig = Config['server']\nexport type LimitsConfig = Config['limits']\nexport type FeaturesConfig = Config['features']\n","import { configSchema, ALL_TOOLS, type Config } from './schema.js'\n\ninterface ParsedArgs {\n strings: Record<string, string>\n booleans: Set<string>\n}\n\n/**\n * Parse --key=value format argument\n * Returns [key, value] or null if invalid\n */\nfunction parseEqualsFormat(arg: string): [string, string] | null {\n if (!arg.includes('=')) return null\n const parts = arg.slice(2).split('=')\n const key = parts[0]\n const value = parts.slice(1).join('=') // Handle values with = in them\n return key && value !== undefined ? [key, value] : null\n}\n\n/**\n * Parse --key value format argument\n * Returns [key, value] or null if next arg is missing/invalid\n */\nfunction parseSpacedFormat(arg: string, nextArg?: string): [string, string] | null {\n if (nextArg && !nextArg.startsWith('--')) {\n return [arg.slice(2), nextArg]\n }\n return null\n}\n\n/**\n * Parse boolean flag argument (--flag with no value)\n * Returns the flag name\n */\nfunction parseBooleanFlag(arg: string): string {\n return arg.slice(2)\n}\n\n/**\n * Parse CLI arguments\n * Supports: --transport, --port, --host, --site, --read-only, --disable-tools\n * Format: --key=value or --key value or --flag (boolean)\n */\nfunction parseArgs(): ParsedArgs {\n const strings: Record<string, string> = {}\n const booleans = new Set<string>()\n const argv = process.argv.slice(2)\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]\n if (!arg) continue\n\n if (arg.startsWith('--')) {\n // Try --key=value format\n const equalsResult = parseEqualsFormat(arg)\n if (equalsResult) {\n const [key, value] = equalsResult\n strings[key] = value\n continue\n }\n\n // Try --key value format\n const spacedResult = parseSpacedFormat(arg, argv[i + 1])\n if (spacedResult) {\n const [key, value] = spacedResult\n strings[key] = value\n i += 1 // Skip next arg since we consumed it\n continue\n }\n\n // Must be boolean flag\n booleans.add(parseBooleanFlag(arg))\n }\n }\n\n return { strings, booleans }\n}\n\n/**\n * Parse disabled tools from comma-separated string\n * Example: \"incidents,notebooks\" -> those tools disabled\n */\nfunction parseDisabledTools(value: string | undefined): string[] {\n if (!value) return []\n\n const requested = value.split(',').map((s) => s.trim().toLowerCase())\n return requested.filter((t) => (ALL_TOOLS as readonly string[]).includes(t))\n}\n\nexport function loadConfig(): Config {\n const args = parseArgs()\n\n const raw = {\n datadog: {\n apiKey: process.env.DD_API_KEY ?? '',\n appKey: process.env.DD_APP_KEY ?? '',\n site: args.strings.site ?? process.env.DD_SITE ?? 'datadoghq.com'\n },\n server: {\n name: 'datadog-mcp',\n version: '1.0.0',\n transport: args.strings.transport ?? process.env.MCP_TRANSPORT ?? 'stdio',\n port: Number.parseInt(args.strings.port ?? process.env.MCP_PORT ?? '3000', 10),\n host: args.strings.host ?? process.env.MCP_HOST ?? 'localhost'\n },\n limits: {\n maxResults: Number.parseInt(process.env.MCP_MAX_RESULTS ?? '100', 10),\n maxLogLines: Number.parseInt(process.env.MCP_MAX_LOG_LINES ?? '500', 10),\n maxMetricDataPoints: Number.parseInt(process.env.MCP_MAX_METRIC_POINTS ?? '1000', 10),\n defaultTimeRangeHours: Number.parseInt(process.env.MCP_DEFAULT_TIME_RANGE ?? '24', 10)\n },\n features: {\n readOnly: args.booleans.has('read-only') || process.env.MCP_READ_ONLY === 'true',\n disabledTools: parseDisabledTools(\n args.strings['disable-tools'] ?? process.env.MCP_DISABLE_TOOLS\n )\n }\n }\n\n return configSchema.parse(raw)\n}\n\nexport {\n type Config,\n type DatadogConfig,\n type ServerConfig,\n type LimitsConfig,\n type FeaturesConfig,\n type ToolName,\n ALL_TOOLS\n} from './schema.js'\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { createDatadogClients } from './config/datadog.js'\nimport { registerAllTools } from './tools/index.js'\nimport type { Config } from './config/index.js'\n\nexport function createServer(config: Config): McpServer {\n const server = new McpServer({\n name: config.server.name,\n version: config.server.version\n })\n\n const clients = createDatadogClients(config.datadog)\n\n registerAllTools(server, clients, config.limits, config.features, config.datadog.site)\n\n return server\n}\n","import { client, v1, v2 } from '@datadog/datadog-api-client'\nimport type { DatadogConfig } from './schema.js'\n\nexport interface DatadogClients {\n monitors: v1.MonitorsApi\n dashboards: v1.DashboardsApi\n dashboardLists: v1.DashboardListsApi\n logs: v2.LogsApi\n metricsV1: v1.MetricsApi\n metricsV2: v2.MetricsApi\n eventsV1: v1.EventsApi\n eventsV2: v2.EventsApi\n incidents: v2.IncidentsApi\n downtimes: v2.DowntimesApi\n hosts: v1.HostsApi\n slo: v1.ServiceLevelObjectivesApi\n synthetics: v1.SyntheticsApi\n rum: v2.RUMApi\n security: v2.SecurityMonitoringApi\n notebooks: v1.NotebooksApi\n users: v2.UsersApi\n teams: v2.TeamsApi\n tags: v1.TagsApi\n usage: v1.UsageMeteringApi\n spans: v2.SpansApi\n services: v2.ServiceDefinitionApi\n auth: v1.AuthenticationApi\n}\n\nexport function createDatadogClients(config: DatadogConfig): DatadogClients {\n const configuration = client.createConfiguration({\n authMethods: {\n apiKeyAuth: config.apiKey,\n appKeyAuth: config.appKey\n }\n })\n\n if (config.site && config.site !== 'datadoghq.com') {\n configuration.setServerVariables({ site: config.site })\n }\n\n // Enable unstable operations for v2 APIs\n configuration.unstableOperations = {\n 'v2.listIncidents': true,\n 'v2.getIncident': true,\n 'v2.searchIncidents': true,\n 'v2.createIncident': true,\n 'v2.updateIncident': true,\n 'v2.deleteIncident': true\n }\n\n return {\n monitors: new v1.MonitorsApi(configuration),\n dashboards: new v1.DashboardsApi(configuration),\n dashboardLists: new v1.DashboardListsApi(configuration),\n logs: new v2.LogsApi(configuration),\n metricsV1: new v1.MetricsApi(configuration),\n metricsV2: new v2.MetricsApi(configuration),\n eventsV1: new v1.EventsApi(configuration),\n eventsV2: new v2.EventsApi(configuration),\n incidents: new v2.IncidentsApi(configuration),\n downtimes: new v2.DowntimesApi(configuration),\n hosts: new v1.HostsApi(configuration),\n slo: new v1.ServiceLevelObjectivesApi(configuration),\n synthetics: new v1.SyntheticsApi(configuration),\n rum: new v2.RUMApi(configuration),\n security: new v2.SecurityMonitoringApi(configuration),\n notebooks: new v1.NotebooksApi(configuration),\n users: new v2.UsersApi(configuration),\n teams: new v2.TeamsApi(configuration),\n tags: new v1.TagsApi(configuration),\n usage: new v1.UsageMeteringApi(configuration),\n spans: new v2.SpansApi(configuration),\n services: new v2.ServiceDefinitionApi(configuration),\n auth: new v1.AuthenticationApi(configuration)\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { buildMonitorUrl, buildMonitorsListUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum([\n 'list',\n 'get',\n 'search',\n 'create',\n 'update',\n 'delete',\n 'mute',\n 'unmute'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Monitor ID (required for get/update/delete/mute/unmute)'),\n query: z.string().optional().describe('Search query (for search action)'),\n name: z.string().optional().describe('Filter by name (for list action)'),\n tags: z.array(z.string()).optional().describe('Filter by tags'),\n groupStates: z\n .array(z.string())\n .optional()\n .describe(\n 'Filter multi-alert monitors by group states (e.g., alert by host). Does NOT filter by overall monitor status. Values: alert, warn, no data, ok'\n ),\n limit: z.number().optional().describe('Maximum number of monitors to return'),\n config: z.record(z.unknown()).optional().describe('Monitor configuration (for create/update)'),\n message: z.string().optional().describe('Mute message (for mute action)'),\n end: z.number().optional().describe('Mute end timestamp (for mute action)')\n}\n\ninterface MonitorSummary {\n id: number\n name: string\n type: string\n status: string\n message: string\n tags: string[]\n query: string\n created: string\n modified: string\n}\n\nexport function formatMonitor(m: v1.Monitor): MonitorSummary {\n return {\n id: m.id ?? 0,\n name: m.name ?? '',\n type: String(m.type ?? 'unknown'),\n status: String(m.overallState ?? 'unknown'),\n message: m.message ?? '',\n tags: m.tags ?? [],\n query: m.query ?? '',\n created: m.created ? new Date(m.created).toISOString() : '',\n modified: m.modified ? new Date(m.modified).toISOString() : ''\n }\n}\n\nexport async function listMonitors(\n api: v1.MonitorsApi,\n params: { name?: string; tags?: string[]; groupStates?: string[]; limit?: number },\n limits: LimitsConfig,\n site: string\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listMonitors({\n name: params.name,\n tags: params.tags?.join(','),\n groupStates: params.groupStates?.join(',')\n })\n\n const monitors = response.slice(0, effectiveLimit).map(formatMonitor)\n\n const statusCounts = {\n total: response.length,\n alert: response.filter((m) => m.overallState === 'Alert').length,\n warn: response.filter((m) => m.overallState === 'Warn').length,\n ok: response.filter((m) => m.overallState === 'OK').length,\n noData: response.filter((m) => m.overallState === 'No Data').length\n }\n\n return {\n monitors,\n summary: statusCounts,\n datadog_url: buildMonitorsListUrl(params.name, site)\n }\n}\n\nexport async function getMonitor(api: v1.MonitorsApi, id: string, site: string) {\n const monitorId = Number.parseInt(id, 10)\n if (Number.isNaN(monitorId)) {\n throw new Error(`Invalid monitor ID: ${id}`)\n }\n\n const monitor = await api.getMonitor({ monitorId })\n return {\n monitor: formatMonitor(monitor),\n datadog_url: buildMonitorUrl(monitorId, site)\n }\n}\n\nexport async function searchMonitors(\n api: v1.MonitorsApi,\n query: string,\n limits: LimitsConfig,\n site: string\n) {\n const response = await api.searchMonitors({ query })\n const monitors = (response.monitors ?? []).slice(0, limits.maxResults).map((m) => ({\n id: m.id ?? 0,\n name: m.name ?? '',\n status: String(m.status ?? 'unknown'),\n type: m.type ?? '',\n tags: m.tags ?? []\n }))\n\n return {\n monitors,\n metadata: {\n totalCount: response.metadata?.totalCount ?? monitors.length,\n pageCount: response.metadata?.pageCount ?? 1,\n page: response.metadata?.page ?? 0\n },\n datadog_url: buildMonitorsListUrl(query, site)\n }\n}\n\n/**\n * Normalize monitor config to handle snake_case -> camelCase conversion\n * Common fields that users might pass in snake_case\n */\nexport function normalizeMonitorConfig(\n config: Record<string, unknown>,\n isUpdate: boolean = false\n): Record<string, unknown> {\n const normalized = { ...config }\n\n // Required field validation (only for create, not update)\n if (!isUpdate && !normalized.name && !normalized.type && !normalized.query) {\n throw new Error(\"Monitor config requires at least 'name', 'type', and 'query' fields\")\n }\n\n // Handle options object snake_case conversions\n if (normalized.options && typeof normalized.options === 'object') {\n const opts = { ...(normalized.options as Record<string, unknown>) }\n\n // Common snake_case -> camelCase conversions\n const optionMappings: [string, string][] = [\n ['notify_no_data', 'notifyNoData'],\n ['no_data_timeframe', 'noDataTimeframe'],\n ['new_host_delay', 'newHostDelay'],\n ['new_group_delay', 'newGroupDelay'],\n ['evaluation_delay', 'evaluationDelay'],\n ['renotify_interval', 'renotifyInterval'],\n ['renotify_occurrences', 'renotifyOccurrences'],\n ['renotify_statuses', 'renotifyStatuses'],\n ['timeout_h', 'timeoutH'],\n ['notify_audit', 'notifyAudit'],\n ['include_tags', 'includeTags'],\n ['require_full_window', 'requireFullWindow'],\n ['escalation_message', 'escalationMessage'],\n ['locked', 'locked'],\n ['silenced', 'silenced']\n ]\n\n for (const [snake, camel] of optionMappings) {\n if (snake in opts && !(camel in opts)) {\n opts[camel] = opts[snake]\n delete opts[snake]\n }\n }\n\n // Handle nested thresholds\n if (opts.thresholds && typeof opts.thresholds === 'object') {\n const thresholds = { ...(opts.thresholds as Record<string, unknown>) }\n const thresholdMappings: [string, string][] = [\n ['critical', 'critical'],\n ['warning', 'warning'],\n ['ok', 'ok'],\n ['critical_recovery', 'criticalRecovery'],\n ['warning_recovery', 'warningRecovery']\n ]\n for (const [snake, camel] of thresholdMappings) {\n if (snake in thresholds && !(camel in thresholds) && snake !== camel) {\n thresholds[camel] = thresholds[snake]\n delete thresholds[snake]\n }\n }\n opts.thresholds = thresholds\n }\n\n normalized.options = opts\n }\n\n return normalized\n}\n\nexport async function createMonitor(api: v1.MonitorsApi, config: Record<string, unknown>) {\n const body = normalizeMonitorConfig(config) as unknown as v1.Monitor\n const monitor = await api.createMonitor({ body })\n return {\n success: true,\n monitor: formatMonitor(monitor)\n }\n}\n\nexport async function updateMonitor(\n api: v1.MonitorsApi,\n id: string,\n config: Record<string, unknown>\n) {\n const monitorId = Number.parseInt(id, 10)\n const body = normalizeMonitorConfig(config, true) as unknown as v1.MonitorUpdateRequest\n const monitor = await api.updateMonitor({ monitorId, body })\n return {\n success: true,\n monitor: formatMonitor(monitor)\n }\n}\n\nexport async function deleteMonitor(api: v1.MonitorsApi, id: string) {\n const monitorId = Number.parseInt(id, 10)\n await api.deleteMonitor({ monitorId })\n return { success: true, message: `Monitor ${id} deleted` }\n}\n\nexport async function muteMonitor(api: v1.MonitorsApi, id: string, params: { end?: number }) {\n const monitorId = Number.parseInt(id, 10)\n // Use validate endpoint with mute options\n const monitor = await api.getMonitor({ monitorId })\n\n // Update the monitor with mute options\n await api.updateMonitor({\n monitorId,\n body: {\n options: {\n ...monitor.options,\n silenced: { '*': params.end ?? null }\n }\n } as unknown as v1.MonitorUpdateRequest\n })\n return { success: true, message: `Monitor ${id} muted` }\n}\n\nexport async function unmuteMonitor(api: v1.MonitorsApi, id: string) {\n const monitorId = Number.parseInt(id, 10)\n const monitor = await api.getMonitor({ monitorId })\n\n // Update the monitor to remove silenced option\n await api.updateMonitor({\n monitorId,\n body: {\n options: {\n ...monitor.options,\n silenced: {}\n }\n } as unknown as v1.MonitorUpdateRequest\n })\n return { success: true, message: `Monitor ${id} unmuted` }\n}\n\nexport function registerMonitorsTool(\n server: McpServer,\n api: v1.MonitorsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'monitors',\n `Manage Datadog monitors. Actions: list, get, search, create, update, delete, mute, unmute.\nFilters: name, tags, groupStates (alert/warn/ok/no data).\nTIP: For alert HISTORY (which monitors triggered), use the events tool with tags: [\"source:alert\"].`,\n InputSchema,\n async ({ action, id, query, name, tags, groupStates, limit, config, end }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listMonitors(api, { name, tags, groupStates, limit }, limits, site)\n )\n\n case 'get': {\n const monitorId = requireParam(id, 'id', 'get')\n return toolResult(await getMonitor(api, monitorId, site))\n }\n\n case 'search': {\n const searchQuery = requireParam(query, 'query', 'search')\n return toolResult(await searchMonitors(api, searchQuery, limits, site))\n }\n\n case 'create': {\n const monitorConfig = requireParam(config, 'config', 'create')\n return toolResult(await createMonitor(api, monitorConfig))\n }\n\n case 'update': {\n const monitorId = requireParam(id, 'id', 'update')\n const updateConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateMonitor(api, monitorId, updateConfig))\n }\n\n case 'delete': {\n const monitorId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteMonitor(api, monitorId))\n }\n\n case 'mute': {\n const monitorId = requireParam(id, 'id', 'mute')\n return toolResult(await muteMonitor(api, monitorId, { end }))\n }\n\n case 'unmute': {\n const monitorId = requireParam(id, 'id', 'unmute')\n return toolResult(await unmuteMonitor(api, monitorId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'\n\n/**\n * Custom error codes for Datadog-specific errors.\n * Uses JSON-RPC server error range (-32000 to -32099).\n * These allow LLMs to distinguish error types for retry logic.\n */\nexport const DatadogErrorCode = {\n /** 401 - Invalid or missing API/APP key */\n Unauthorized: -32050,\n /** 403 - Valid credentials but insufficient permissions */\n Forbidden: -32051,\n /** 404 - Requested resource does not exist */\n NotFound: -32052,\n /** 429 - Rate limit exceeded, should retry after delay */\n RateLimited: -32053,\n /** 5xx - Datadog service temporarily unavailable */\n ServiceUnavailable: -32054\n} as const\n\n/**\n * Maps Datadog API errors to MCP errors with appropriate error codes.\n * Uses custom error codes to allow LLMs to distinguish between:\n * - Authentication failures (retry won't help without new credentials)\n * - Authorization failures (need different permissions)\n * - Not found (check if resource exists)\n * - Rate limiting (wait and retry)\n * - Service unavailable (temporary, retry later)\n */\nexport function handleDatadogError(error: unknown): never {\n console.error('[Datadog Error]', error)\n\n // Pass through McpError unchanged (check first since McpError also has numeric code)\n if (error instanceof McpError) {\n throw error\n }\n\n // Check for Datadog API errors by duck typing\n const apiError = error as { code?: number; body?: { errors?: string[] }; message?: string }\n if (typeof apiError.code === 'number') {\n const message = apiError.body?.errors?.[0] ?? apiError.message ?? 'Unknown error'\n\n switch (apiError.code) {\n case 400:\n throw new McpError(ErrorCode.InvalidRequest, `Invalid request: ${message}`)\n case 401:\n throw new McpError(\n DatadogErrorCode.Unauthorized,\n `Authentication failed: Invalid Datadog API key or APP key`\n )\n case 403:\n throw new McpError(DatadogErrorCode.Forbidden, `Authorization denied: ${message}`)\n case 404:\n throw new McpError(DatadogErrorCode.NotFound, `Resource not found: ${message}`)\n case 429:\n throw new McpError(\n DatadogErrorCode.RateLimited,\n 'Rate limit exceeded. Retry after a short delay.'\n )\n case 500:\n case 502:\n case 503:\n throw new McpError(\n DatadogErrorCode.ServiceUnavailable,\n 'Datadog service temporarily unavailable. Retry later.'\n )\n default:\n throw new McpError(\n ErrorCode.InternalError,\n `Datadog API error (${apiError.code}): ${message}`\n )\n }\n }\n\n throw new McpError(\n ErrorCode.InternalError,\n error instanceof Error ? error.message : String(error)\n )\n}\n\n/**\n * Validates required parameters for an action\n */\nexport function requireParam<T>(value: T | undefined, name: string, action: string): T {\n if (value === undefined || value === null || value === '') {\n throw new McpError(\n ErrorCode.InvalidParams,\n `Parameter '${name}' is required for action '${action}'`\n )\n }\n return value\n}\n\n/**\n * Write actions that should be blocked in read-only mode\n */\nconst WRITE_ACTIONS = new Set([\n 'create',\n 'update',\n 'delete',\n 'mute',\n 'unmute',\n 'cancel',\n 'add',\n 'trigger'\n])\n\n/**\n * Checks if action is allowed given read-only mode setting.\n * Throws an error for write actions when in read-only mode.\n */\nexport function checkReadOnly(action: string, readOnly: boolean): void {\n if (readOnly && WRITE_ACTIONS.has(action)) {\n throw new McpError(\n ErrorCode.InvalidRequest,\n `Action '${action}' is not allowed in read-only mode. Server started with --read-only flag.`\n )\n }\n}\n","/**\n * Format tool response as MCP content\n */\nexport function formatResponse(data: unknown): { type: 'text'; text: string }[] {\n return [\n {\n type: 'text' as const,\n text: JSON.stringify(data, null, 2) ?? 'null'\n }\n ]\n}\n\n/**\n * Create a structured tool result\n */\nexport function toolResult<T>(data: T): { content: { type: 'text'; text: string }[] } {\n return {\n content: formatResponse(data)\n }\n}\n","/**\n * Datadog URL builders for deep linking to the Datadog UI\n *\n * These functions generate URLs that link directly to Datadog's web interface,\n * allowing AI tools to provide evidence links back to the source data.\n */\n\n/**\n * Map Datadog API sites to their corresponding app URLs\n */\nconst SITE_TO_APP_URL: Record<string, string> = {\n 'datadoghq.com': 'https://app.datadoghq.com',\n 'us3.datadoghq.com': 'https://us3.datadoghq.com',\n 'us5.datadoghq.com': 'https://us5.datadoghq.com',\n 'datadoghq.eu': 'https://app.datadoghq.eu',\n 'ap1.datadoghq.com': 'https://ap1.datadoghq.com',\n 'ddog-gov.com': 'https://app.ddog-gov.com'\n}\n\n/**\n * Get the app base URL for a given Datadog site\n */\nfunction getAppBaseUrl(site: string = 'datadoghq.com'): string {\n return SITE_TO_APP_URL[site] ?? SITE_TO_APP_URL['datadoghq.com']!\n}\n\n/**\n * Convert Unix seconds to milliseconds for URL params\n */\nfunction toMs(seconds: number): number {\n return seconds * 1000\n}\n\n/**\n * Build a Datadog Logs Explorer URL\n *\n * @param query - Log search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildLogsUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/logs?${params.toString()}`\n}\n\n/**\n * Extract metric name from a PromQL-style query\n * e.g., \"avg:system.cpu.user{host:foo}\" -> \"system.cpu.user\"\n */\nfunction extractMetricName(query: string): string {\n // Pattern: aggregation:metric_name{tags} or just metric_name{tags}\n const match = query.match(/^(?:\\w+:)?([a-zA-Z0-9_.]+)/)\n return match?.[1] ?? query\n}\n\n/**\n * Build a Datadog Metrics Explorer URL\n *\n * @param query - PromQL-style metric query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildMetricsUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const metricName = extractMetricName(query)\n const params = new URLSearchParams({\n exp_metric: metricName,\n exp_query: query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/metric/explorer?${params.toString()}`\n}\n\n/**\n * Build a Datadog APM Traces URL\n * Note: APM uses start/end instead of from_ts/to_ts\n *\n * @param query - APM trace search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildTracesUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n start: toMs(fromSec).toString(),\n end: toMs(toSec).toString()\n })\n return `${base}/apm/traces?${params.toString()}`\n}\n\n/**\n * Build a Datadog Events Explorer URL\n *\n * @param query - Event search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildEventsUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/event/explorer?${params.toString()}`\n}\n\n/**\n * Build a Datadog Monitor URL\n *\n * @param monitorId - Monitor ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildMonitorUrl(\n monitorId: string | number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n return `${base}/monitors/${monitorId}`\n}\n\n/**\n * Build a Datadog Monitors List URL with optional query filters\n *\n * @param query - Optional search query\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildMonitorsListUrl(query?: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n if (query) {\n const params = new URLSearchParams({ query })\n return `${base}/monitors/manage?${params.toString()}`\n }\n return `${base}/monitors/manage`\n}\n\n/**\n * Build a Datadog RUM Explorer URL\n *\n * @param query - RUM search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildRumUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/rum/explorer?${params.toString()}`\n}\n\n/**\n * Build a Datadog RUM Session Replay URL\n *\n * @param applicationId - RUM Application ID\n * @param sessionId - Session ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildRumSessionUrl(\n applicationId: string,\n sessionId: string,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n return `${base}/rum/replay/sessions/${sessionId}?applicationId=${encodeURIComponent(applicationId)}`\n}\n\n/**\n * Build a Datadog Dashboard URL\n *\n * @param dashboardId - Dashboard ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildDashboardUrl(dashboardId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/dashboard/${dashboardId}`\n}\n\n/**\n * Build a Datadog SLO URL\n *\n * @param sloId - SLO ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildSloUrl(sloId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/slo/${sloId}`\n}\n\n/**\n * Build a Datadog Incident URL\n *\n * @param incidentId - Incident ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildIncidentUrl(incidentId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/incidents/${incidentId}`\n}\n\n/**\n * Build a Datadog Synthetic Test URL\n *\n * @param publicId - Synthetic test public ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildSyntheticUrl(publicId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/synthetics/details/${publicId}`\n}\n\n/**\n * Build a Datadog Notebook URL\n *\n * @param notebookId - Notebook ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildNotebookUrl(notebookId: number, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/notebook/${notebookId}`\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Dashboard ID (required for get/update/delete)'),\n name: z.string().optional().describe('Filter by name'),\n tags: z.array(z.string()).optional().describe('Filter by tags'),\n limit: z.number().optional().describe('Maximum number of dashboards to return'),\n config: z.record(z.unknown()).optional().describe('Dashboard configuration (for create/update)')\n}\n\ninterface DashboardSummary {\n id: string\n title: string\n description: string\n url: string\n layoutType: string\n created: string\n modified: string\n authorHandle: string\n}\n\nexport function formatDashboardSummary(d: v1.DashboardSummaryDefinition): DashboardSummary {\n return {\n id: d.id ?? '',\n title: d.title ?? '',\n description: d.description ?? '',\n url: d.url ?? '',\n layoutType: String(d.layoutType ?? 'unknown'),\n created: d.createdAt ? new Date(d.createdAt).toISOString() : '',\n modified: d.modifiedAt ? new Date(d.modifiedAt).toISOString() : '',\n authorHandle: d.authorHandle ?? ''\n }\n}\n\nexport async function listDashboards(\n api: v1.DashboardsApi,\n params: { name?: string; tags?: string[]; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listDashboards({\n filterShared: false\n })\n\n let dashboards = response.dashboards ?? []\n\n // Client-side filtering by name\n if (params.name) {\n const lowerName = params.name.toLowerCase()\n dashboards = dashboards.filter((d) => d.title?.toLowerCase().includes(lowerName))\n }\n\n const result = dashboards.slice(0, effectiveLimit).map(formatDashboardSummary)\n\n return {\n dashboards: result,\n total: response.dashboards?.length ?? 0\n }\n}\n\nexport async function getDashboard(api: v1.DashboardsApi, id: string) {\n const dashboard = await api.getDashboard({ dashboardId: id })\n return {\n dashboard: {\n id: dashboard.id ?? '',\n title: dashboard.title ?? '',\n description: dashboard.description ?? '',\n layoutType: String(dashboard.layoutType ?? 'unknown'),\n widgets: dashboard.widgets?.length ?? 0,\n url: dashboard.url ?? '',\n created: dashboard.createdAt ? new Date(dashboard.createdAt).toISOString() : '',\n modified: dashboard.modifiedAt ? new Date(dashboard.modifiedAt).toISOString() : '',\n authorHandle: dashboard.authorHandle ?? ''\n }\n }\n}\n\nexport function normalizeDashboardConfig(config: Record<string, unknown>): Record<string, unknown> {\n const normalized = { ...config }\n\n // Handle layout_type -> layoutType\n if ('layout_type' in normalized && !('layoutType' in normalized)) {\n normalized.layoutType = normalized.layout_type\n delete normalized.layout_type\n }\n\n // Validate required field\n if (!normalized.layoutType) {\n throw new Error(\"Dashboard config requires 'layoutType' (e.g., 'ordered', 'free')\")\n }\n\n // Validate tags if present - Datadog only allows 'team' as the tag key\n if (normalized.tags && Array.isArray(normalized.tags)) {\n const invalidTags = normalized.tags.filter((tag: unknown) => {\n if (typeof tag !== 'string') return true\n return !tag.startsWith('team:')\n })\n if (invalidTags.length > 0) {\n throw new Error(\n `Dashboard tags must use 'team:' prefix. Invalid tags: ${invalidTags.join(', ')}. Example: [\"team:operations\", \"team:frontend\"]`\n )\n }\n }\n\n return normalized\n}\n\nexport async function createDashboard(api: v1.DashboardsApi, config: Record<string, unknown>) {\n const body = normalizeDashboardConfig(config) as unknown as v1.Dashboard\n const dashboard = await api.createDashboard({ body })\n return {\n success: true,\n dashboard: {\n id: dashboard.id ?? '',\n title: dashboard.title ?? '',\n url: dashboard.url ?? ''\n }\n }\n}\n\nexport async function updateDashboard(\n api: v1.DashboardsApi,\n id: string,\n config: Record<string, unknown>\n) {\n const body = normalizeDashboardConfig(config) as unknown as v1.Dashboard\n const dashboard = await api.updateDashboard({ dashboardId: id, body })\n return {\n success: true,\n dashboard: {\n id: dashboard.id ?? '',\n title: dashboard.title ?? '',\n url: dashboard.url ?? ''\n }\n }\n}\n\nexport async function deleteDashboard(api: v1.DashboardsApi, id: string) {\n await api.deleteDashboard({ dashboardId: id })\n return { success: true, message: `Dashboard ${id} deleted` }\n}\n\nexport function registerDashboardsTool(\n server: McpServer,\n api: v1.DashboardsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'dashboards',\n 'Access Datadog dashboards and visualizations. Actions: list (filter by name/tags), get, create, update, delete. Use for: finding existing views, team dashboards, understanding what is monitored. NOTE: Dashboard tags must use \"team:\" prefix (e.g., [\"team:operations\"]).',\n InputSchema,\n async ({ action, id, name, tags, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listDashboards(api, { name, tags, limit }, limits))\n\n case 'get': {\n const dashboardId = requireParam(id, 'id', 'get')\n return toolResult(await getDashboard(api, dashboardId))\n }\n\n case 'create': {\n const dashboardConfig = requireParam(config, 'config', 'create')\n return toolResult(await createDashboard(api, dashboardConfig))\n }\n\n case 'update': {\n const dashboardId = requireParam(id, 'id', 'update')\n const updateConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateDashboard(api, dashboardId, updateConfig))\n }\n\n case 'delete': {\n const dashboardId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteDashboard(api, dashboardId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { hoursAgo, now, parseTime, ensureValidTimeRange } from '../utils/time.js'\nimport { buildLogsUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['search', 'aggregate'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe(\n 'Log search query (Datadog syntax). Examples: \"error\", \"service:my-service status:error\", \"error AND timeout\"'\n ),\n keyword: z\n .string()\n .optional()\n .describe(\n 'Simple text search - finds logs containing this text (grep-like). Merged with query using AND'\n ),\n pattern: z\n .string()\n .optional()\n .describe(\n 'Regex pattern to match in log message (grep -E style). Example: \"ERROR.*timeout|connection refused\"'\n ),\n from: z\n .string()\n .optional()\n .describe(\n 'Start time. Formats: ISO 8601, relative (30s, 15m, 2h, 7d), precise (3d@11:45:23, yesterday@14:00)'\n ),\n to: z\n .string()\n .optional()\n .describe('End time. Same formats as \"from\". Example: from=\"3d@11:45:23\" to=\"3d@12:55:34\"'),\n service: z.string().optional().describe('Filter by service name'),\n host: z.string().optional().describe('Filter by host'),\n status: z\n .enum(['error', 'warn', 'info', 'debug'])\n .optional()\n .describe('Filter by log status/level'),\n indexes: z.array(z.string()).optional().describe('Log indexes to search'),\n limit: z.number().optional().describe('Maximum number of logs to return'),\n sort: z.enum(['timestamp', '-timestamp']).optional().describe('Sort order'),\n sample: z\n .enum(['first', 'spread', 'diverse'])\n .optional()\n .describe(\n 'Sampling mode: first (chronological, default), spread (evenly across time range), diverse (distinct message patterns)'\n ),\n compact: z\n .boolean()\n .optional()\n .describe(\n 'Strip custom attributes for token efficiency. Keeps: id, timestamp, service, host, status, message (truncated), dd.trace_id, dd.span_id, pod_name, kube_namespace, kube_container_name, error info'\n ),\n groupBy: z.array(z.string()).optional().describe('Fields to group by (for aggregate)'),\n compute: z.record(z.unknown()).optional().describe('Compute operations (for aggregate)')\n}\n\ninterface LogEntry {\n id: string\n timestamp: string\n service: string\n host: string\n status: string\n message: string\n tags: string[]\n attributes: Record<string, unknown>\n}\n\nexport function formatLog(log: v2.Log): LogEntry {\n const attrs = log.attributes ?? {}\n // Handle timestamp which can be Date or string\n let timestamp = ''\n if (attrs.timestamp) {\n const ts = attrs.timestamp\n timestamp = ts instanceof Date ? ts.toISOString() : new Date(String(ts)).toISOString()\n }\n return {\n id: log.id ?? '',\n timestamp,\n service: (attrs.service as string) ?? '',\n host: (attrs.host as string) ?? '',\n status: (attrs.status as string) ?? '',\n message: (attrs.message as string) ?? '',\n tags: (attrs.tags as string[]) ?? [],\n attributes: (attrs.attributes as Record<string, unknown>) ?? {}\n }\n}\n\n/**\n * Compact log format for token efficiency\n * Strips custom attributes object, keeps only essential fields for investigation\n */\ninterface CompactLogEntry {\n id: string\n timestamp: string\n service: string\n host: string\n status: string\n message: string // truncated to 500 chars\n traceId: string // extracted from dd.trace_id for correlation\n spanId: string\n podName?: string // extracted from pod_name tag\n namespace?: string // extracted from kube_namespace tag\n container?: string // extracted from kube_container_name tag\n error?: {\n type: string\n message: string\n }\n}\n\ntype FormattedLog = LogEntry | CompactLogEntry\n\nexport function formatLogCompact(log: v2.Log): CompactLogEntry {\n const attrs = log.attributes ?? {}\n const nestedAttrs = (attrs.attributes as Record<string, unknown>) ?? {}\n const tags = (attrs.tags as string[]) ?? []\n\n // Parse Kubernetes fields from tags (format: \"key:value\")\n const findTagValue = (tagPrefix: string): string => {\n const tag = tags.find((t) => t.startsWith(tagPrefix + ':'))\n return tag ? tag.substring(tagPrefix.length + 1) : ''\n }\n\n const podName = findTagValue('pod_name')\n const namespace = findTagValue('kube_namespace')\n const container = findTagValue('kube_container_name')\n\n // Handle timestamp\n let timestamp = ''\n if (attrs.timestamp) {\n const ts = attrs.timestamp\n timestamp = ts instanceof Date ? ts.toISOString() : new Date(String(ts)).toISOString()\n }\n\n // Extract trace correlation IDs from various possible locations\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const attrsAny = attrs as any\n const traceId =\n (nestedAttrs['dd.trace_id'] as string) ??\n (nestedAttrs['trace_id'] as string) ??\n (attrsAny['dd.trace_id'] as string) ??\n ''\n const spanId =\n (nestedAttrs['dd.span_id'] as string) ??\n (nestedAttrs['span_id'] as string) ??\n (attrsAny['dd.span_id'] as string) ??\n ''\n\n // Extract error info\n const errorType =\n (nestedAttrs['error.type'] as string) ?? (nestedAttrs['error.kind'] as string) ?? ''\n const errorMessage =\n (nestedAttrs['error.message'] as string) ?? (nestedAttrs['error.msg'] as string) ?? ''\n\n // Truncate message for token efficiency\n const fullMessage = (attrs.message as string) ?? ''\n const message = fullMessage.length > 500 ? fullMessage.slice(0, 500) + '...' : fullMessage\n\n const entry: CompactLogEntry = {\n id: log.id ?? '',\n timestamp,\n service: (attrs.service as string) ?? '',\n host: (attrs.host as string) ?? '',\n status: (attrs.status as string) ?? '',\n message,\n traceId,\n spanId\n }\n\n // Add Kubernetes fields if present\n if (podName) entry.podName = podName\n if (namespace) entry.namespace = namespace\n if (container) entry.container = container\n\n // Only include error if present\n if (errorType || errorMessage) {\n entry.error = {\n type: errorType,\n message: errorMessage.length > 200 ? errorMessage.slice(0, 200) + '...' : errorMessage\n }\n }\n\n return entry\n}\n\n/**\n * Normalize a log message to a pattern by replacing variable parts\n * Used for diverse sampling to identify distinct error patterns\n */\nexport function normalizeToPattern(message: string): string {\n return (\n message\n // UUIDs (universal format)\n .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '{UUID}')\n // Long hex strings (16+ chars - trace IDs, hashes, object IDs)\n .replace(/\\b[0-9a-f]{16,}\\b/gi, '{HEX}')\n // Shorter hex IDs (8-15 chars)\n .replace(/\\b[0-9a-f]{8,15}\\b/gi, '{ID}')\n // ISO timestamps\n .replace(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[.\\dZ]*/g, '{TS}')\n // IP addresses\n .replace(/\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/g, '{IP}')\n // Large numbers (4+ digits) - after other patterns to avoid breaking them\n .replace(/\\b\\d{4,}\\b/g, '{N}')\n // Truncate for efficient hashing\n .slice(0, 200)\n )\n}\n\n/**\n * Spread sample: evenly distributed across the array\n */\nexport function spreadSample<T>(items: T[], limit: number): T[] {\n if (items.length <= limit) return items\n const step = items.length / limit\n return Array.from({ length: limit }, (_, i) => items[Math.floor(i * step)] as T)\n}\n\n/**\n * Diverse sample: deduplicate by message pattern to get distinct error types\n */\nexport function diverseSample<T extends { message: string }>(\n items: T[],\n limit: number\n): { samples: T[]; patterns: number } {\n const seen = new Map<string, T>()\n\n for (const item of items) {\n const pattern = normalizeToPattern(item.message)\n if (!seen.has(pattern)) {\n seen.set(pattern, item)\n if (seen.size >= limit) break\n }\n }\n\n return {\n samples: Array.from(seen.values()),\n patterns: seen.size\n }\n}\n\n/**\n * Build a Datadog log query from various filter parameters\n */\nexport function buildLogQuery(params: {\n query?: string\n keyword?: string\n pattern?: string\n service?: string\n host?: string\n status?: string\n}): string {\n const parts: string[] = []\n\n // Base query or wildcard\n if (params.query) {\n parts.push(params.query)\n }\n\n // Simple keyword search (grep-like)\n if (params.keyword) {\n // Escape special characters and wrap in quotes for exact phrase\n const escaped = params.keyword.replace(/\"/g, '\\\\\"')\n parts.push(`\"${escaped}\"`)\n }\n\n // Regex pattern search on message field\n if (params.pattern) {\n // Datadog regex syntax: @field:~\"pattern\"\n const escaped = params.pattern.replace(/\"/g, '\\\\\"')\n parts.push(`@message:~\"${escaped}\"`)\n }\n\n // Service filter\n if (params.service) {\n parts.push(`service:${params.service}`)\n }\n\n // Host filter\n if (params.host) {\n parts.push(`host:${params.host}`)\n }\n\n // Status filter\n if (params.status) {\n parts.push(`status:${params.status}`)\n }\n\n // If no parts, search everything\n return parts.length > 0 ? parts.join(' ') : '*'\n}\n\nexport async function searchLogs(\n api: v2.LogsApi,\n params: {\n query?: string\n keyword?: string\n pattern?: string\n service?: string\n host?: string\n status?: string\n from?: string\n to?: string\n indexes?: string[]\n limit?: number\n sort?: 'timestamp' | '-timestamp'\n sample?: 'first' | 'spread' | 'diverse'\n compact?: boolean\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n // Build the full query from all filter params\n const fullQuery = buildLogQuery({\n query: params.query,\n keyword: params.keyword,\n pattern: params.pattern,\n service: params.service,\n host: params.host,\n status: params.status\n })\n\n const requestedLimit = params.limit ?? limits.defaultLimit\n const sampleMode = params.sample ?? 'first'\n\n // For spread/diverse sampling, fetch more logs to sample from\n const fetchMultiplier = sampleMode === 'first' ? 1 : 4\n const fetchLimit = Math.min(requestedLimit * fetchMultiplier, limits.maxLogLines)\n\n const body: v2.LogsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n indexes: params.indexes\n },\n sort: params.sort === 'timestamp' ? 'timestamp' : '-timestamp',\n page: {\n limit: fetchLimit\n }\n }\n\n const response = await api.listLogs({ body })\n\n // Format logs (compact or full)\n const formattedLogs = params.compact\n ? (response.data ?? []).map(formatLogCompact)\n : (response.data ?? []).map(formatLog)\n\n // Apply sampling based on mode\n // Type assertion needed because ternary produces CompactLogEntry[] | LogEntry[]\n // but generic functions need (CompactLogEntry | LogEntry)[]\n let logs: FormattedLog[]\n let distinctPatterns: number | undefined\n\n switch (sampleMode) {\n case 'spread':\n logs = spreadSample(formattedLogs as FormattedLog[], requestedLimit)\n break\n case 'diverse': {\n const result = diverseSample(formattedLogs as FormattedLog[], requestedLimit)\n logs = result.samples\n distinctPatterns = result.patterns\n break\n }\n case 'first':\n default:\n logs = formattedLogs.slice(0, requestedLimit)\n }\n\n return {\n logs,\n meta: {\n count: logs.length,\n query: fullQuery,\n from: fromTime,\n to: toTime,\n compact: params.compact ?? false,\n sample: sampleMode,\n ...(sampleMode !== 'first' && { fetched: formattedLogs.length }),\n ...(distinctPatterns !== undefined && { distinctPatterns }),\n datadog_url: buildLogsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\nexport async function aggregateLogs(\n api: v2.LogsApi,\n params: {\n query: string\n from?: string\n to?: string\n groupBy?: string[]\n compute?: Record<string, unknown>\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const computeOps: v2.LogsCompute[] = params.compute\n ? [params.compute as unknown as v2.LogsCompute]\n : [{ aggregation: 'count' as const, type: 'total' as const }]\n\n const body: v2.LogsAggregateRequest = {\n filter: {\n query: params.query,\n from: fromTime,\n to: toTime\n },\n compute: computeOps,\n groupBy: params.groupBy?.map((field) => ({\n facet: field,\n limit: 10\n }))\n }\n\n const response = await api.aggregateLogs({ body })\n\n return {\n buckets: response.data?.buckets ?? [],\n meta: {\n query: params.query,\n from: fromTime,\n to: toTime,\n groupBy: params.groupBy,\n datadog_url: buildLogsUrl(params.query, validFrom, validTo, site)\n }\n }\n}\n\nexport function registerLogsTool(\n server: McpServer,\n api: v2.LogsApi,\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'logs',\n `Search Datadog logs with grep-like text filtering. Actions: search (find logs), aggregate (count/group). Key filters: keyword (text grep), pattern (regex), service, host, status (error/warn/info). Time ranges: \"1h\", \"3d@11:45:23\".\nCORRELATION: Logs contain dd.trace_id in attributes for linking to traces and APM metrics.\nSAMPLING: Use sample:\"diverse\" for error investigation (dedupes by message pattern), sample:\"spread\" for time distribution.\nTOKEN TIP: Use compact:true to reduce payload size (strips heavy fields) when querying large volumes.`,\n InputSchema,\n async ({\n action,\n query,\n keyword,\n pattern,\n service,\n host,\n status,\n from,\n to,\n indexes,\n limit,\n sort,\n sample,\n compact,\n groupBy,\n compute\n }) => {\n try {\n switch (action) {\n case 'search': {\n // Query is now optional - can use keyword, pattern, or filters instead\n return toolResult(\n await searchLogs(\n api,\n {\n query,\n keyword,\n pattern,\n service,\n host,\n status,\n from,\n to,\n indexes,\n limit,\n sort,\n sample,\n compact\n },\n limits,\n site\n )\n )\n }\n\n case 'aggregate': {\n const aggregateQuery = query ?? '*'\n return toolResult(\n await aggregateLogs(\n api,\n {\n query: aggregateQuery,\n from,\n to,\n groupBy,\n compute\n },\n limits,\n site\n )\n )\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","/**\n * Get Unix timestamp from hours ago\n */\nexport function hoursAgo(hours: number): number {\n return Math.floor(Date.now() / 1000) - hours * 3600\n}\n\n/**\n * Get Unix timestamp from days ago\n */\nexport function daysAgo(days: number): number {\n return Math.floor(Date.now() / 1000) - days * 86400\n}\n\n/**\n * Get current Unix timestamp\n */\nexport function now(): number {\n return Math.floor(Date.now() / 1000)\n}\n\n/**\n * Get start of a day (midnight) N days ago\n */\nfunction startOfDayAgo(days: number): Date {\n const date = new Date()\n date.setDate(date.getDate() - days)\n date.setHours(0, 0, 0, 0)\n return date\n}\n\n/**\n * Parse time string to Unix timestamp\n *\n * Supported formats:\n * - ISO 8601: \"2024-01-15T11:45:23Z\"\n * - Relative simple: \"30s\", \"15m\", \"2h\", \"7d\"\n * - Relative with time: \"3d@11:45:23\", \"3d@11:45\", \"1d@14:30:00\"\n * - Keywords with time: \"today@09:30\", \"yesterday@14:00:00\"\n * - Unix timestamp: 1702656000 or \"1702656000\"\n *\n * Examples for LLMs:\n * - \"3d@11:45:23\" = 3 days ago at 11:45:23\n * - \"1d@14:30\" = yesterday at 14:30:00\n * - \"today@09:00\" = today at 09:00:00\n * - \"2h\" = 2 hours ago from now\n */\nexport function parseTime(input: string | number | undefined, defaultValue: number): number {\n if (input === undefined) {\n return defaultValue\n }\n\n if (typeof input === 'number') {\n return input\n }\n\n const trimmed = input.trim()\n\n // Simple relative time: 30s, 15m, 2h, 7d\n const simpleRelativeMatch = trimmed.match(/^(\\d+)([smhd])$/)\n if (simpleRelativeMatch) {\n const value = Number.parseInt(simpleRelativeMatch[1] ?? '0', 10)\n const unit = simpleRelativeMatch[2]\n const nowTs = now()\n switch (unit) {\n case 's':\n return nowTs - value\n case 'm':\n return nowTs - value * 60\n case 'h':\n return nowTs - value * 3600\n case 'd':\n return nowTs - value * 86400\n default:\n return defaultValue\n }\n }\n\n // Relative time with specific time: 3d@11:45:23 or 3d@11:45\n const relativeWithTimeMatch = trimmed.match(/^(\\d+)([dh])[@\\s](\\d{1,2}):(\\d{2})(?::(\\d{2}))?$/)\n if (relativeWithTimeMatch) {\n const value = Number.parseInt(relativeWithTimeMatch[1] ?? '0', 10)\n const unit = relativeWithTimeMatch[2]\n const hours = Number.parseInt(relativeWithTimeMatch[3] ?? '0', 10)\n const minutes = Number.parseInt(relativeWithTimeMatch[4] ?? '0', 10)\n const seconds = Number.parseInt(relativeWithTimeMatch[5] ?? '0', 10)\n\n if (unit === 'd') {\n const date = startOfDayAgo(value)\n date.setHours(hours, minutes, seconds, 0)\n return Math.floor(date.getTime() / 1000)\n }\n // For hours, we go back N hours then set to specific minute/second\n // This is less common but supported\n const date = new Date()\n date.setHours(date.getHours() - value)\n date.setMinutes(minutes, seconds, 0)\n return Math.floor(date.getTime() / 1000)\n }\n\n // Keywords: today@09:30, yesterday@14:00:00\n const keywordMatch = trimmed.match(/^(today|yesterday)[@\\s](\\d{1,2}):(\\d{2})(?::(\\d{2}))?$/i)\n if (keywordMatch) {\n const keyword = keywordMatch[1]?.toLowerCase()\n const hours = Number.parseInt(keywordMatch[2] ?? '0', 10)\n const minutes = Number.parseInt(keywordMatch[3] ?? '0', 10)\n const seconds = Number.parseInt(keywordMatch[4] ?? '0', 10)\n\n const daysAgo = keyword === 'yesterday' ? 1 : 0\n const date = startOfDayAgo(daysAgo)\n date.setHours(hours, minutes, seconds, 0)\n return Math.floor(date.getTime() / 1000)\n }\n\n // ISO 8601 date\n const date = new Date(trimmed)\n if (!Number.isNaN(date.getTime())) {\n return Math.floor(date.getTime() / 1000)\n }\n\n // Unix timestamp as string\n const ts = Number.parseInt(trimmed, 10)\n if (!Number.isNaN(ts)) {\n return ts\n }\n\n return defaultValue\n}\n\n/**\n * Ensure from < to for time range queries\n * If from >= to, adjusts to to be from + minRangeSeconds\n *\n * @param from - Start timestamp (Unix seconds)\n * @param to - End timestamp (Unix seconds)\n * @param minRangeSeconds - Minimum range in seconds (default: 60 = 1 minute)\n * @returns Tuple of [adjustedFrom, adjustedTo] where from < to\n */\nexport function ensureValidTimeRange(\n from: number,\n to: number,\n minRangeSeconds: number = 60\n): [number, number] {\n // If from > to, swap them (user probably made a mistake)\n if (from > to) {\n ;[from, to] = [to, from]\n }\n\n // If from == to (or very close), add minimum buffer to 'to'\n if (to - from < minRangeSeconds) {\n to = from + minRangeSeconds\n }\n\n return [from, to]\n}\n\n/**\n * Parse duration string to nanoseconds (for Datadog APM queries)\n *\n * Supported formats:\n * - \"100ns\" = 100 nanoseconds\n * - \"50us\" or \"50µs\" = 50 microseconds\n * - \"500ms\" = 500 milliseconds\n * - \"2s\" = 2 seconds\n * - \"1.5s\" = 1.5 seconds\n * - \"5m\" = 5 minutes\n * - \"1h\" = 1 hour\n * - Raw number = nanoseconds\n *\n * Examples for LLMs:\n * - \"1s\" = 1,000,000,000 ns (find spans >1 second)\n * - \"500ms\" = 500,000,000 ns (find spans >500ms)\n * - \"5s\" = 5,000,000,000 ns (find slow database calls)\n */\nexport function parseDurationToNs(input: string | number | undefined): number | undefined {\n if (input === undefined) {\n return undefined\n }\n\n if (typeof input === 'number') {\n return input\n }\n\n const trimmed = input.trim().toLowerCase()\n\n // Match: number + optional decimal + unit\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)(ns|µs|us|ms|s|m|h|d|w)?$/)\n if (!match) {\n // Try parsing as raw number (assume nanoseconds)\n const raw = Number.parseInt(trimmed, 10)\n return Number.isNaN(raw) ? undefined : raw\n }\n\n const value = Number.parseFloat(match[1] ?? '0')\n const unit = match[2] ?? 'ns'\n\n const multipliers: Record<string, number> = {\n ns: 1,\n µs: 1000,\n us: 1000,\n ms: 1000000,\n s: 1000000000,\n m: 60000000000,\n h: 3600000000000,\n d: 86400000000000,\n w: 604800000000000\n }\n\n return Math.floor(value * (multipliers[unit] ?? 1))\n}\n\n/**\n * Format nanoseconds to human-readable duration\n */\nexport function formatDurationNs(ns: number): string {\n if (ns < 1000) return `${ns}ns`\n if (ns < 1000000) return `${(ns / 1000).toFixed(1)}µs`\n if (ns < 1000000000) return `${(ns / 1000000).toFixed(1)}ms`\n if (ns < 60000000000) return `${(ns / 1000000000).toFixed(2)}s`\n return `${(ns / 60000000000).toFixed(2)}m`\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1, v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { hoursAgo, now, parseTime, ensureValidTimeRange } from '../utils/time.js'\nimport { buildMetricsUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['query', 'search', 'list', 'metadata'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe(\n 'For query: PromQL expression (e.g., \"avg:system.cpu.user{*}\"). For search: grep-like filter on metric names. For list: tag filter.'\n ),\n from: z\n .string()\n .optional()\n .describe(\n 'Start time (ONLY for query action). Formats: ISO 8601, relative (30s, 15m, 2h, 7d), precise (3d@11:45:23)'\n ),\n to: z.string().optional().describe('End time (ONLY for query action). Same formats as \"from\".'),\n metric: z.string().optional().describe('Metric name (for metadata action)'),\n tag: z.string().optional().describe('Filter by tag'),\n limit: z.number().optional().describe('Maximum number of results (for search/list)')\n}\n\ninterface MetricSeriesData {\n metric: string\n points: Array<{ timestamp: number; value: number }>\n scope: string\n tags: string[]\n}\n\nexport async function queryMetrics(\n api: v1.MetricsApi,\n params: {\n query: string\n from?: string\n to?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Parse and validate time range (ensures from < to)\n const [fromTs, toTs] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n\n const response = await api.queryMetrics({\n from: fromTs,\n to: toTs,\n query: params.query\n })\n\n const series: MetricSeriesData[] = (response.series ?? []).map((s) => ({\n metric: s.metric ?? '',\n points: (s.pointlist ?? []).slice(0, limits.maxMetricDataPoints).map((p) => ({\n timestamp: p[0] ?? 0,\n value: p[1] ?? 0\n })),\n scope: s.scope ?? '',\n tags: s.tagSet ?? []\n }))\n\n return {\n series,\n meta: {\n query: params.query,\n from: new Date(fromTs * 1000).toISOString(),\n to: new Date(toTs * 1000).toISOString(),\n seriesCount: series.length,\n datadog_url: buildMetricsUrl(params.query, fromTs, toTs, site)\n }\n }\n}\n\nexport async function searchMetrics(\n api: v1.MetricsApi,\n params: { query: string; limit?: number },\n limits: LimitsConfig\n) {\n // Use listActiveMetrics with 24h window (same as list), then filter by name\n const response = await api.listActiveMetrics({\n from: hoursAgo(24),\n host: undefined,\n tagFilter: undefined // Must match listMetrics exactly\n })\n\n const allMetrics = response.metrics ?? []\n const lowerQuery = params.query.toLowerCase()\n\n // Filter by query (grep-like on metric name)\n const filtered = allMetrics\n .filter((name) => name.toLowerCase().includes(lowerQuery))\n .slice(0, params.limit ?? limits.maxResults)\n\n return {\n metrics: filtered,\n total: filtered.length,\n searchedFrom: allMetrics.length\n }\n}\n\nexport async function listMetrics(\n api: v1.MetricsApi,\n params: { query?: string },\n limits: LimitsConfig\n) {\n const response = await api.listActiveMetrics({\n from: hoursAgo(24),\n host: undefined,\n tagFilter: params.query\n })\n\n const metrics = (response.metrics ?? []).slice(0, limits.maxResults)\n\n return {\n metrics,\n total: response.metrics?.length ?? 0\n }\n}\n\nexport async function getMetricMetadata(api: v1.MetricsApi, metricName: string) {\n const metadata = await api.getMetricMetadata({ metricName })\n\n return {\n metric: metricName,\n description: metadata.description ?? '',\n unit: metadata.unit ?? '',\n perUnit: metadata.perUnit ?? '',\n type: metadata.type ?? '',\n shortName: metadata.shortName ?? '',\n integration: metadata.integration ?? ''\n }\n}\n\nexport function registerMetricsTool(\n server: McpServer,\n metricsV1Api: v1.MetricsApi,\n metricsV2Api: v2.MetricsApi,\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'metrics',\n `Query Datadog metrics. Actions:\n- query: Get timeseries data (requires from/to time range, PromQL query)\n- search: Find metrics by name (grep-like, NO time param needed)\n- list: Get recently active metrics (last 24h, optionally filter by tag)\n- metadata: Get metric details (unit, type, description)\n\nAPM METRICS (auto-generated from traces):\n- trace.{service}.hits - Request count\n- trace.{service}.errors - Error count\n- trace.{service}.duration - Latency (use avg:, p95:, max:)\nExample: max:trace.{service}.request.duration{*}`,\n InputSchema,\n async ({ action, query, from, to, metric, limit }) => {\n try {\n switch (action) {\n case 'query': {\n const metricsQuery = requireParam(query, 'query', 'query')\n return toolResult(\n await queryMetrics(\n metricsV1Api,\n {\n query: metricsQuery,\n from,\n to\n },\n limits,\n site\n )\n )\n }\n\n case 'search': {\n const searchQuery = requireParam(query, 'query', 'search')\n return toolResult(\n await searchMetrics(\n metricsV1Api,\n {\n query: searchQuery,\n limit\n },\n limits\n )\n )\n }\n\n case 'list':\n return toolResult(await listMetrics(metricsV1Api, { query }, limits))\n\n case 'metadata': {\n const metricName = requireParam(metric, 'metric', 'metadata')\n return toolResult(await getMetricMetadata(metricsV1Api, metricName))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport {\n hoursAgo,\n now,\n parseTime,\n ensureValidTimeRange,\n parseDurationToNs,\n formatDurationNs\n} from '../utils/time.js'\nimport { buildTracesUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['search', 'aggregate', 'services'])\n\n// Reserved span facets that should NOT be prefixed with @\nconst RESERVED_SPAN_FACETS = new Set([\n 'service',\n 'resource_name',\n 'operation_name',\n 'span_name',\n 'status',\n 'env',\n 'host',\n 'type',\n 'duration',\n 'trace_id',\n 'span_id'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe(\n 'APM trace search query (Datadog syntax). Example: \"@http.status_code:500\", \"service:my-service status:error\"'\n ),\n from: z\n .string()\n .optional()\n .describe(\n 'Start time. Formats: ISO 8601, relative (30s, 15m, 2h, 7d), precise (3d@11:45:23, yesterday@14:00)'\n ),\n to: z\n .string()\n .optional()\n .describe('End time. Same formats as \"from\". Example: from=\"3d@11:45\" to=\"3d@12:55\"'),\n service: z\n .string()\n .optional()\n .describe('Filter by service name. Example: \"my-service\", \"postgres\"'),\n operation: z\n .string()\n .optional()\n .describe('Filter by operation name. Example: \"express.request\", \"mongodb.query\"'),\n resource: z\n .string()\n .optional()\n .describe(\n 'Filter by resource name (endpoint/query). Supports wildcards. Example: \"GET /api/*\", \"*orders*\"'\n ),\n status: z\n .enum(['ok', 'error'])\n .optional()\n .describe('Filter by span status - \"ok\" for successful, \"error\" for failed spans'),\n env: z.string().optional().describe('Filter by environment. Example: \"production\", \"staging\"'),\n minDuration: z\n .string()\n .optional()\n .describe('Minimum span duration (find slow spans). Examples: \"1s\", \"500ms\", \"100ms\"'),\n maxDuration: z.string().optional().describe('Maximum span duration. Examples: \"5s\", \"1000ms\"'),\n httpStatus: z\n .string()\n .optional()\n .describe(\n 'HTTP status code filter. Examples: \"500\", \"5xx\" (500-599), \"4xx\" (400-499), \">=400\"'\n ),\n errorType: z\n .string()\n .optional()\n .describe('Filter by error type (grep-like). Example: \"TimeoutError\", \"ConnectionRefused\"'),\n errorMessage: z\n .string()\n .optional()\n .describe('Filter by error message (grep-like). Example: \"timeout\", \"connection refused\"'),\n limit: z.number().optional().describe('Maximum number of results'),\n sort: z.enum(['timestamp', '-timestamp']).optional().describe('Sort order'),\n groupBy: z\n .array(z.string())\n .optional()\n .describe('Fields to group by (for aggregate). Example: [\"resource_name\", \"status\"]')\n}\n\ninterface SpanSummary {\n traceId: string\n spanId: string\n service: string\n resource: string\n operation: string\n type: string\n status: string\n duration: string\n durationNs: number\n http: {\n statusCode: string\n method: string\n url: string\n }\n error: {\n type: string\n message: string\n }\n env: string\n tags: string[]\n}\n\n// SDK types are incomplete - extend with actual API response fields\ninterface SpanAttributesExtended {\n tags?: string[]\n attributes?: Record<string, unknown>\n custom?: {\n error?: Record<string, unknown>\n [key: string]: unknown\n }\n error?: Record<string, unknown>\n status?: string\n operationName?: string\n startTimestamp?: Date\n endTimestamp?: Date\n traceId?: string\n spanId?: string\n service?: string\n resourceName?: string\n type?: string\n env?: string\n [key: string]: unknown\n}\n\nexport function formatSpan(span: v2.Span): SpanSummary {\n // SDK types are incomplete - actual API returns more fields than typed\n // Using SpanAttributesExtended to access real API fields: error, status, operationName\n const attrs = (span.attributes ?? {}) as SpanAttributesExtended\n const tags = (attrs.tags as string[]) ?? []\n const nestedAttrs = (attrs.attributes ?? {}) as Record<string, unknown>\n const custom = (attrs.custom ?? {}) as Record<string, unknown>\n const attrsError = (attrs.error ?? {}) as Record<string, unknown>\n const customError = (custom.error ?? {}) as Record<string, unknown>\n\n // Extract common tags into a map\n const tagMap: Record<string, string> = {}\n for (const tag of tags) {\n const [key, value] = tag.split(':')\n if (key && value) tagMap[key] = value\n }\n\n // Calculate duration from timestamps or get from nested attributes\n let durationNs = 0\n if (attrs.startTimestamp && attrs.endTimestamp) {\n const startMs = attrs.startTimestamp.getTime()\n const endMs = attrs.endTimestamp.getTime()\n durationNs = (endMs - startMs) * 1_000_000 // ms to ns\n } else if (typeof nestedAttrs['duration'] === 'number') {\n durationNs = nestedAttrs['duration']\n } else if (typeof custom['duration'] === 'number') {\n durationNs = custom['duration']\n }\n\n // Get status - prioritize direct attrs field, then custom, then tags\n const status = (attrs.status as string) ?? (custom['status'] as string) ?? tagMap['status'] ?? ''\n\n return {\n traceId: attrs.traceId ?? '',\n spanId: attrs.spanId ?? '',\n service: attrs.service ?? '',\n resource: attrs.resourceName ?? '',\n operation: (attrs.operationName as string) ?? (custom['operation_name'] as string) ?? '',\n type: attrs.type ?? '',\n status,\n duration: formatDurationNs(durationNs),\n durationNs,\n http: {\n statusCode: tagMap['http.status_code'] ?? '',\n method: tagMap['http.method'] ?? '',\n url: tagMap['http.url'] ?? ''\n },\n error: {\n type:\n (attrsError['type'] as string) ??\n (customError['type'] as string) ??\n tagMap['error.type'] ??\n '',\n message:\n (customError['message'] as string) ?? tagMap['error.message'] ?? tagMap['error.msg'] ?? ''\n },\n env: attrs.env ?? tagMap['env'] ?? '',\n tags\n }\n}\n\n/**\n * Build HTTP status code filter string for trace query\n * Handles ranges (5xx), comparisons (>=500), and exact values (404)\n */\nfunction buildHttpStatusFilter(httpStatus: string): string {\n const status = httpStatus.toLowerCase()\n\n if (status.endsWith('xx')) {\n const base = Number.parseInt(status[0] ?? '0', 10) * 100\n return `@http.status_code:[${base} TO ${base + 99}]`\n }\n if (status.startsWith('>=')) return `@http.status_code:>=${status.slice(2)}`\n if (status.startsWith('>')) return `@http.status_code:>${status.slice(1)}`\n if (status.startsWith('<=')) return `@http.status_code:<=${status.slice(2)}`\n if (status.startsWith('<')) return `@http.status_code:<${status.slice(1)}`\n\n return `@http.status_code:${httpStatus}`\n}\n\n/**\n * Build a Datadog APM trace query from filter parameters\n */\nexport function buildTraceQuery(params: {\n query?: string\n service?: string\n operation?: string\n resource?: string\n status?: 'ok' | 'error'\n env?: string\n minDuration?: string\n maxDuration?: string\n httpStatus?: string\n errorType?: string\n errorMessage?: string\n}): string {\n const parts: string[] = []\n\n // Base query\n if (params.query) {\n parts.push(params.query)\n }\n\n // Service filter\n if (params.service) {\n parts.push(`service:${params.service}`)\n }\n\n // Operation name filter\n if (params.operation) {\n parts.push(`operation_name:${params.operation}`)\n }\n\n // Resource name filter (endpoint/query name)\n if (params.resource) {\n parts.push(`resource_name:${params.resource}`)\n }\n\n // Span status filter (ok/error)\n if (params.status) {\n parts.push(`status:${params.status}`)\n }\n\n // Environment filter\n if (params.env) {\n parts.push(`env:${params.env}`)\n }\n\n // Duration filters (convert to nanoseconds)\n if (params.minDuration) {\n const ns = parseDurationToNs(params.minDuration)\n if (ns !== undefined) {\n parts.push(`@duration:>=${ns}`)\n }\n }\n if (params.maxDuration) {\n const ns = parseDurationToNs(params.maxDuration)\n if (ns !== undefined) {\n parts.push(`@duration:<=${ns}`)\n }\n }\n\n // HTTP status code filter\n if (params.httpStatus) {\n parts.push(buildHttpStatusFilter(params.httpStatus))\n }\n\n // Error type grep (wildcard search)\n if (params.errorType) {\n const escaped = params.errorType.replace(/\"/g, '\\\\\"')\n parts.push(`error.type:*${escaped}*`)\n }\n\n // Error message grep (wildcard search)\n if (params.errorMessage) {\n const escaped = params.errorMessage.replace(/\"/g, '\\\\\"')\n parts.push(`error.message:*${escaped}*`)\n }\n\n return parts.length > 0 ? parts.join(' ') : '*'\n}\n\nexport async function searchTraces(\n api: v2.SpansApi,\n params: {\n query?: string\n from?: string\n to?: string\n service?: string\n operation?: string\n resource?: string\n status?: 'ok' | 'error'\n env?: string\n minDuration?: string\n maxDuration?: string\n httpStatus?: string\n errorType?: string\n errorMessage?: string\n limit?: number\n sort?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Build query from all filter params\n const fullQuery = buildTraceQuery({\n query: params.query,\n service: params.service,\n operation: params.operation,\n resource: params.resource,\n status: params.status,\n env: params.env,\n minDuration: params.minDuration,\n maxDuration: params.maxDuration,\n httpStatus: params.httpStatus,\n errorType: params.errorType,\n errorMessage: params.errorMessage\n })\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const body: v2.SpansListRequest = {\n data: {\n type: 'search_request',\n attributes: {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: params.sort === 'timestamp' ? 'timestamp' : '-timestamp',\n page: {\n limit: Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n }\n }\n }\n }\n\n const response = await api.listSpans({ body })\n const spans = (response.data ?? []).map(formatSpan)\n\n return {\n spans,\n meta: {\n count: spans.length,\n query: fullQuery,\n from: fromTime,\n to: toTime,\n datadog_url: buildTracesUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\nexport async function aggregateTraces(\n api: v2.SpansApi,\n params: {\n query?: string\n from?: string\n to?: string\n service?: string\n operation?: string\n resource?: string\n status?: 'ok' | 'error'\n env?: string\n minDuration?: string\n maxDuration?: string\n httpStatus?: string\n errorType?: string\n errorMessage?: string\n groupBy?: string[]\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Build query from all filter params\n const fullQuery = buildTraceQuery({\n query: params.query,\n service: params.service,\n operation: params.operation,\n resource: params.resource,\n status: params.status,\n env: params.env,\n minDuration: params.minDuration,\n maxDuration: params.maxDuration,\n httpStatus: params.httpStatus,\n errorType: params.errorType,\n errorMessage: params.errorMessage\n })\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n // Use raw object structure to avoid TypeScript SDK type issues\n // Note: sort is omitted from group_by as it causes API validation errors\n const body = {\n data: {\n type: 'aggregate_request',\n attributes: {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n compute: [{ aggregation: 'count', type: 'total' }],\n groupBy: params.groupBy?.map((field) => ({\n facet: RESERVED_SPAN_FACETS.has(field) || field.startsWith('@') ? field : `@${field}`,\n limit: 10\n }))\n }\n }\n } as v2.SpansAggregateRequest\n\n const response = await api.aggregateSpans({ body })\n\n return {\n data: response.data ?? [],\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n groupBy: params.groupBy,\n datadog_url: buildTracesUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\nexport async function listApmServices(\n api: v2.SpansApi,\n params: { env?: string; from?: string; to?: string },\n limits: LimitsConfig\n) {\n const defaultFrom = hoursAgo(24) // Look back 24 hours for services\n const defaultTo = now()\n\n // Parse and validate time range\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n // Build query - env filter is optional\n const query = params.env ? `env:${params.env}` : '*'\n\n // Aggregate spans by service name to discover APM services\n // Use raw object structure to avoid TypeScript SDK type issues\n // Note: sort is omitted as it causes API validation errors\n const body = {\n data: {\n type: 'aggregate_request',\n attributes: {\n filter: {\n query,\n from: fromTime,\n to: toTime\n },\n compute: [{ aggregation: 'count', type: 'total' }],\n groupBy: [\n {\n facet: 'service',\n limit: limits.maxResults\n }\n ]\n }\n }\n } as v2.SpansAggregateRequest\n\n const response = await api.aggregateSpans({ body })\n\n // Extract service names from aggregation buckets\n // SDK types define 'computes' but API returns 'compute' (singular)\n const buckets = (response.data ?? []) as Array<{\n attributes?: {\n by?: Record<string, string>\n compute?: Record<string, number>\n }\n }>\n\n const services = buckets\n .map((bucket) => ({\n name: bucket.attributes?.by?.['service'] ?? '',\n spanCount: bucket.attributes?.compute?.['c0'] ?? 0\n }))\n .filter((s) => s.name !== '')\n\n return {\n services,\n total: services.length,\n meta: {\n query,\n env: params.env ?? 'all',\n from: fromTime,\n to: toTime\n }\n }\n}\n\nexport function registerTracesTool(\n server: McpServer,\n spansApi: v2.SpansApi,\n _servicesApi: v2.ServiceDefinitionApi, // Keep for backward compatibility, not used\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'traces',\n `Analyze APM traces for request flow and latency debugging. Actions: search (find spans), aggregate (group stats), services (list APM services). Key filters: minDuration/maxDuration (\"500ms\", \"2s\"), httpStatus (\"5xx\", \">=400\"), status (ok/error), errorMessage (grep).\nAPM METRICS: Traces auto-generate metrics in trace.{service}.* namespace. Use metrics tool to query: avg:trace.{service}.request.duration{*}`,\n InputSchema,\n async ({\n action,\n query,\n from,\n to,\n service,\n operation,\n resource,\n status,\n env,\n minDuration,\n maxDuration,\n httpStatus,\n errorType,\n errorMessage,\n limit,\n sort,\n groupBy\n }) => {\n try {\n switch (action) {\n case 'search': {\n return toolResult(\n await searchTraces(\n spansApi,\n {\n query,\n from,\n to,\n service,\n operation,\n resource,\n status,\n env,\n minDuration,\n maxDuration,\n httpStatus,\n errorType,\n errorMessage,\n limit,\n sort\n },\n limits,\n site\n )\n )\n }\n\n case 'aggregate': {\n return toolResult(\n await aggregateTraces(\n spansApi,\n {\n query,\n from,\n to,\n service,\n operation,\n resource,\n status,\n env,\n minDuration,\n maxDuration,\n httpStatus,\n errorType,\n errorMessage,\n groupBy\n },\n limits,\n site\n )\n )\n }\n\n case 'services':\n return toolResult(await listApmServices(spansApi, { env, from, to }, limits))\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1, v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { hoursAgo, now, parseTime, ensureValidTimeRange, parseDurationToNs } from '../utils/time.js'\nimport { buildEventsUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum([\n 'list',\n 'get',\n 'create',\n 'search',\n 'aggregate',\n 'top',\n 'timeseries',\n 'incidents'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Event ID (for get action)'),\n query: z.string().optional().describe('Search query'),\n from: z\n .string()\n .optional()\n .describe('Start time (ISO 8601, relative like \"1h\", or Unix timestamp)'),\n to: z.string().optional().describe('End time (ISO 8601, relative like \"1h\", or Unix timestamp)'),\n priority: z.enum(['normal', 'low']).optional().describe('Event priority'),\n sources: z.array(z.string()).optional().describe('Filter by sources'),\n tags: z.array(z.string()).optional().describe('Filter by tags'),\n limit: z.number().optional().describe('Maximum number of events to return'),\n title: z.string().optional().describe('Event title (for create)'),\n text: z.string().optional().describe('Event text (for create)'),\n alertType: z\n .enum(['error', 'warning', 'info', 'success'])\n .optional()\n .describe('Alert type (for create)'),\n groupBy: z\n .array(z.string())\n .optional()\n .describe('Fields to group by: monitor_name, priority, alert_type, source'),\n cursor: z.string().optional().describe('Pagination cursor from previous response'),\n // Phase 2: Timeseries\n interval: z\n .string()\n .optional()\n .describe('Time bucket interval for timeseries: 1h, 4h, 1d (default: 1h)'),\n // Phase 2: Incidents deduplication\n dedupeWindow: z\n .string()\n .optional()\n .describe('Deduplication window for incidents: 5m, 15m, 1h (default: 5m)'),\n // Phase 3: Monitor enrichment\n enrich: z\n .boolean()\n .optional()\n .describe('Enrich events with monitor metadata (slower, adds monitor details)')\n}\n\n// v1 Event summary format\ninterface EventSummaryV1 {\n id: number\n title: string\n text: string\n dateHappened: string\n priority: string\n source: string\n tags: string[]\n alertType: string\n host: string\n}\n\n// v2 Event summary format\ninterface EventSummaryV2 {\n id: string\n title: string\n message: string\n timestamp: string\n priority: string\n source: string\n tags: string[]\n alertType: string\n host: string\n monitorId?: number\n monitorInfo?: {\n name: string\n status: string\n scope: string\n priority?: string\n }\n}\n\n// Aggregation bucket format\ninterface AggregationBucket {\n key: string\n count: number\n sample: EventSummaryV2\n}\n\n// Timeseries bucket format (Phase 2)\ninterface TimeseriesBucket {\n timestamp: string\n timestampMs: number\n counts: Record<string, number>\n total: number\n}\n\n// Incident format (Phase 2 - deduplicated events)\ninterface IncidentEvent {\n monitorName: string\n firstTrigger: string\n lastTrigger: string\n triggerCount: number\n recovered: boolean\n recoveredAt?: string\n duration?: string\n sample: EventSummaryV2\n}\n\n// Enriched event with monitor metadata (Phase 3)\ninterface EnrichedEvent extends EventSummaryV2 {\n monitorMetadata?: {\n id: number\n type: string\n message: string\n tags: string[]\n options?: {\n thresholds?: Record<string, number>\n notifyNoData?: boolean\n escalationMessage?: string\n }\n }\n}\n\n/**\n * Extract monitor information from alert event title\n * Handles patterns like:\n * - [Triggered on {scope}] Monitor Name\n * - [P1] [Triggered on {scope}] Monitor Name\n * - [Warn on {scope}] Monitor Name\n * - [Recovered on {scope}] Monitor Name\n */\nexport function extractMonitorInfo(title: string): {\n status: string\n scope: string\n name: string\n priority?: string\n} {\n // Extract priority prefix if present\n const priorityMatch = title.match(/^\\[P(\\d+)\\]\\s*/)\n const priority = priorityMatch ? `P${priorityMatch[1]}` : undefined\n const withoutPriority = title.replace(/^\\[P\\d+\\]\\s*/, '')\n\n // Extract status, scope, and name\n // NOSONAR S5852: Anchored pattern with no nested quantifiers, input is bounded Datadog event titles\n const match = withoutPriority.match(\n /^\\[(Triggered|Recovered|Warn|Alert|OK|No Data|Re-Triggered|Renotify)(?:\\s+on\\s+\\{([^}]+)\\})?\\]\\s*(.+)$/i\n )\n\n if (match) {\n return {\n status: match[1] ?? '',\n scope: match[2] ?? '',\n name: match[3]?.trim() ?? title,\n priority\n }\n }\n\n return { status: '', scope: '', name: title, priority }\n}\n\n/**\n * Extract title/monitor name from v2 event message body\n * v2 API returns empty title, but message contains the alert text\n * Format: \"%%%\\nMonitor title here\\n\\n...\"\n */\nexport function extractTitleFromMessage(message: string): string {\n if (!message) return ''\n\n // Remove %%% markdown delimiter if present\n const content = message.replace(/^%%%\\s*\\n?/, '').trim()\n\n // Get first line (up to first newline)\n const firstLine = content.split('\\n')[0]?.trim() ?? ''\n\n // Clean up common trailing patterns like \" !\" or extra whitespace\n // NOSONAR S5852: Simplified pattern, .trim() handles whitespace\n return firstLine.replace(/\\s*!?\\s*$/, '').trim()\n}\n\n/**\n * Extract monitor ID from v2 event message body\n * Messages contain links like: [[Monitor Status](/monitors/67860480?...)]\n */\nexport function extractMonitorIdFromMessage(message: string): number | undefined {\n if (!message) return undefined\n\n // Match /monitors/{id} pattern in the message\n const match = message.match(/\\/monitors\\/(\\d+)/)\n if (match?.[1]) {\n const id = Number.parseInt(match[1], 10)\n return Number.isNaN(id) ? undefined : id\n }\n\n return undefined\n}\n\n/**\n * Build a group key for aggregation based on the event and groupBy fields\n */\nexport function buildGroupKey(event: EventSummaryV2, groupBy: string[]): string {\n const parts: string[] = []\n\n for (const field of groupBy) {\n switch (field) {\n case 'monitor_name':\n parts.push(event.monitorInfo?.name ?? event.title)\n break\n case 'monitor_id':\n parts.push(event.monitorId?.toString() ?? '')\n break\n case 'priority':\n parts.push(event.monitorInfo?.priority ?? event.priority)\n break\n case 'source':\n parts.push(event.source)\n break\n case 'alert_type':\n parts.push(event.alertType)\n break\n case 'status':\n parts.push(event.monitorInfo?.status ?? '')\n break\n case 'host':\n parts.push(event.host)\n break\n default: {\n // For unknown fields, try to find in tags\n const tagValue = event.tags.find((t) => t.startsWith(`${field}:`))?.split(':')[1] ?? ''\n parts.push(tagValue)\n }\n }\n }\n\n return parts.join('|')\n}\n\nexport function formatEventV1(e: v1.Event): EventSummaryV1 {\n const event = e as v1.Event & { sourceTypeName?: string }\n return {\n id: e.id ?? 0,\n title: e.title ?? '',\n text: e.text ?? '',\n dateHappened: e.dateHappened ? new Date(e.dateHappened * 1000).toISOString() : '',\n priority: String(e.priority ?? 'normal'),\n source: event.sourceTypeName ?? '',\n tags: e.tags ?? [],\n alertType: String(e.alertType ?? 'info'),\n host: e.host ?? ''\n }\n}\n\nexport function formatEventV2(e: v2.EventResponse): EventSummaryV2 {\n const attrs = e.attributes ?? {}\n\n // Parse timestamp\n let timestamp = ''\n if (attrs.timestamp) {\n const ts = attrs.timestamp\n timestamp = ts instanceof Date ? ts.toISOString() : new Date(String(ts)).toISOString()\n }\n\n const message = (attrs.message as string) ?? ''\n\n // v2 API often returns empty title - extract from message body instead\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let title = ((attrs as any).title as string) ?? ''\n if (!title && message) {\n title = extractTitleFromMessage(message)\n }\n\n const monitorInfo = extractMonitorInfo(title)\n const monitorId = extractMonitorIdFromMessage(message)\n\n // Extract source from tags or attributes\n const tags = (attrs.tags as string[]) ?? []\n const sourceTag = tags.find((t) => t.startsWith('source:'))\n const source = sourceTag?.split(':')[1] ?? ''\n\n // Extract alert_type from tags\n const alertTypeTag = tags.find((t) => t.startsWith('alert_type:'))\n const alertType = alertTypeTag?.split(':')[1] ?? ''\n\n // Extract host from tags\n const hostTag = tags.find((t) => t.startsWith('host:'))\n const host = hostTag?.split(':')[1] ?? ''\n\n // Extract priority from tags\n const priorityTag = tags.find((t) => t.startsWith('priority:'))\n const priority = priorityTag?.split(':')[1] ?? 'normal'\n\n return {\n id: String(e.id ?? ''),\n title,\n message,\n timestamp,\n priority,\n source,\n tags,\n alertType,\n host,\n monitorId,\n monitorInfo:\n monitorInfo.name !== title\n ? {\n name: monitorInfo.name,\n status: monitorInfo.status,\n scope: monitorInfo.scope,\n priority: monitorInfo.priority\n }\n : undefined\n }\n}\n\n// ============ V1 API Functions (backward compatible) ============\n\nexport async function listEventsV1(\n api: v1.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n priority?: 'normal' | 'low'\n sources?: string[]\n tags?: string[]\n limit?: number\n },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.defaultLimit, limits.maxResults)\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const response = await api.listEvents({\n start: parseTime(params.from, defaultFrom),\n end: parseTime(params.to, defaultTo),\n priority: params.priority === 'low' ? 'low' : 'normal',\n sources: params.sources?.join(','),\n tags: params.tags?.join(','),\n unaggregated: true\n })\n\n let events = response.events ?? []\n\n // Client-side query filter\n if (params.query) {\n const lowerQuery = params.query.toLowerCase()\n events = events.filter(\n (e) =>\n e.title?.toLowerCase().includes(lowerQuery) || e.text?.toLowerCase().includes(lowerQuery)\n )\n }\n\n const result = events.slice(0, effectiveLimit).map(formatEventV1)\n\n return {\n events: result,\n total: events.length\n }\n}\n\nexport async function getEventV1(api: v1.EventsApi, id: string) {\n const eventId = Number.parseInt(id, 10)\n if (Number.isNaN(eventId)) {\n throw new Error(`Invalid event ID: ${id}`)\n }\n\n const response = await api.getEvent({ eventId })\n return { event: formatEventV1(response.event ?? {}) }\n}\n\nexport async function createEventV1(\n api: v1.EventsApi,\n params: {\n title: string\n text: string\n priority?: 'normal' | 'low'\n tags?: string[]\n alertType?: 'error' | 'warning' | 'info' | 'success'\n }\n) {\n const body: v1.EventCreateRequest = {\n title: params.title,\n text: params.text,\n priority: params.priority === 'low' ? 'low' : 'normal',\n tags: params.tags,\n alertType: params.alertType ?? 'info'\n }\n\n const response = await api.createEvent({ body })\n\n return {\n success: true,\n event: {\n id: response.event?.id ?? 0,\n title: response.event?.title ?? '',\n status: response.status ?? ''\n }\n }\n}\n\n// ============ V2 API Functions (new capabilities) ============\n\n/**\n * Build a Datadog event search query from filter parameters\n */\nexport function buildEventQuery(params: {\n query?: string\n sources?: string[]\n tags?: string[]\n priority?: string\n}): string {\n const parts: string[] = []\n\n if (params.query) {\n parts.push(params.query)\n }\n\n if (params.sources && params.sources.length > 0) {\n const sourceFilter = params.sources.map((s) => `source:${s}`).join(' OR ')\n parts.push(`(${sourceFilter})`)\n }\n\n if (params.tags && params.tags.length > 0) {\n for (const tag of params.tags) {\n parts.push(tag)\n }\n }\n\n if (params.priority) {\n parts.push(`priority:${params.priority}`)\n }\n\n return parts.length > 0 ? parts.join(' ') : '*'\n}\n\nexport async function searchEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n priority?: string\n limit?: number\n cursor?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query,\n sources: params.sources,\n tags: params.tags,\n priority: params.priority\n })\n\n const effectiveLimit = Math.min(params.limit ?? limits.defaultLimit, limits.maxResults)\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: {\n limit: effectiveLimit,\n cursor: params.cursor\n }\n }\n\n const response = await api.searchEvents({ body })\n\n const events = (response.data ?? []).map(formatEventV2)\n const nextCursor = response.meta?.page?.after\n\n return {\n events,\n meta: {\n count: events.length,\n query: fullQuery,\n from: fromTime,\n to: toTime,\n nextCursor,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n/**\n * Client-side aggregation for events\n * Streams through all matching events and counts by group key\n */\nexport async function aggregateEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n groupBy?: string[]\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n const counts = new Map<string, { count: number; sample: EventSummaryV2 }>()\n\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query,\n sources: params.sources,\n tags: params.tags\n })\n\n const groupByFields = params.groupBy ?? ['monitor_name']\n\n // Use pagination to stream through all events\n // Limit to maxEventsToAggregate to prevent runaway queries\n const maxEventsToAggregate = 10000\n let eventCount = 0\n let pageCount = 0\n const maxPages = 100\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: {\n limit: 1000 // Max per page\n }\n }\n\n // Manual pagination since searchEventsWithPagination may not be available\n let cursor: string | undefined\n\n while (pageCount < maxPages && eventCount < maxEventsToAggregate) {\n const pageBody = { ...body, page: { ...body.page, cursor } }\n const response = await api.searchEvents({ body: pageBody })\n\n const events = response.data ?? []\n if (events.length === 0) break\n\n for (const event of events) {\n const formatted = formatEventV2(event)\n const groupKey = buildGroupKey(formatted, groupByFields)\n\n const existing = counts.get(groupKey)\n if (existing) {\n existing.count++\n } else {\n counts.set(groupKey, { count: 1, sample: formatted })\n }\n\n eventCount++\n if (eventCount >= maxEventsToAggregate) break\n }\n\n cursor = response.meta?.page?.after\n if (!cursor) break\n pageCount++\n }\n\n // Sort by count descending, apply limit\n const effectiveLimit = Math.min(params.limit ?? 100, 1000)\n const sorted = [...counts.entries()]\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, effectiveLimit)\n\n const buckets: AggregationBucket[] = sorted.map(([key, data]) => ({\n key,\n count: data.count,\n sample: data.sample\n }))\n\n return {\n buckets,\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n groupBy: groupByFields,\n totalGroups: counts.size,\n totalEvents: eventCount,\n truncated: eventCount >= maxEventsToAggregate,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n/**\n * Top N events by count - convenience wrapper for aggregate\n * Direct answer to \"which monitors triggered the most alerts\"\n */\nexport async function topEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n groupBy?: string[]\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n // Default to source:alert for alert-related queries\n const effectiveQuery = params.query ?? 'source:alert'\n const effectiveTags = params.tags ?? ['source:alert']\n\n const result = await aggregateEventsV2(\n api,\n {\n ...params,\n query: effectiveQuery,\n tags: effectiveTags,\n groupBy: params.groupBy ?? ['monitor_name'],\n limit: params.limit ?? 10\n },\n limits,\n site\n )\n\n // Format for easier consumption\n return {\n top: result.buckets.map((bucket, index) => ({\n rank: index + 1,\n name: bucket.key,\n monitorId: bucket.sample.monitorId,\n alertCount: bucket.count,\n lastAlert: bucket.sample.timestamp,\n sample: {\n title: bucket.sample.title,\n source: bucket.sample.source,\n alertType: bucket.sample.alertType\n }\n })),\n meta: result.meta\n }\n}\n\n// ============ Phase 2: Timeseries Action ============\n\n/**\n * Parse interval string to milliseconds\n * Supports: 1h, 4h, 1d, 15m, etc.\n */\nexport function parseIntervalToMs(interval: string | undefined): number {\n const ns = parseDurationToNs(interval ?? '1h')\n return ns ? Math.floor(ns / 1000000) : 3600000 // default 1h\n}\n\n/**\n * Time-bucketed alert trends\n * Buckets events by time interval and groups by specified fields\n */\nexport async function timeseriesEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n groupBy?: string[]\n interval?: string\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query ?? 'source:alert',\n sources: params.sources,\n tags: params.tags\n })\n\n const intervalMs = parseIntervalToMs(params.interval)\n const groupByFields = params.groupBy ?? ['monitor_name']\n\n // Map: bucketTs -> groupKey -> count\n const timeBuckets = new Map<number, Map<string, number>>()\n\n const maxEventsToProcess = 10000\n let eventCount = 0\n let pageCount = 0\n const maxPages = 100\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: { limit: 1000 }\n }\n\n let cursor: string | undefined\n\n while (pageCount < maxPages && eventCount < maxEventsToProcess) {\n const pageBody = { ...body, page: { ...body.page, cursor } }\n const response = await api.searchEvents({ body: pageBody })\n\n const events = response.data ?? []\n if (events.length === 0) break\n\n for (const event of events) {\n const formatted = formatEventV2(event)\n const groupKey = buildGroupKey(formatted, groupByFields)\n\n // Parse timestamp and bucket it\n const eventTs = new Date(formatted.timestamp).getTime()\n const bucketTs = Math.floor(eventTs / intervalMs) * intervalMs\n\n if (!timeBuckets.has(bucketTs)) {\n timeBuckets.set(bucketTs, new Map())\n }\n const groupCounts = timeBuckets.get(bucketTs)!\n groupCounts.set(groupKey, (groupCounts.get(groupKey) ?? 0) + 1)\n\n eventCount++\n if (eventCount >= maxEventsToProcess) break\n }\n\n cursor = response.meta?.page?.after\n if (!cursor) break\n pageCount++\n }\n\n // Convert to sorted array of buckets\n const sortedBuckets = [...timeBuckets.entries()]\n .sort((a, b) => a[0] - b[0])\n .map(([bucketTs, groupCounts]) => {\n const counts: Record<string, number> = {}\n let total = 0\n for (const [key, count] of groupCounts) {\n counts[key] = count\n total += count\n }\n return {\n timestamp: new Date(bucketTs).toISOString(),\n timestampMs: bucketTs,\n counts,\n total\n } satisfies TimeseriesBucket\n })\n\n // Apply limit to buckets if specified\n const effectiveLimit = params.limit ?? 100\n const limitedBuckets = sortedBuckets.slice(0, effectiveLimit)\n\n return {\n timeseries: limitedBuckets,\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n interval: params.interval ?? '1h',\n intervalMs,\n groupBy: groupByFields,\n totalBuckets: sortedBuckets.length,\n totalEvents: eventCount,\n truncated: eventCount >= maxEventsToProcess,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n// ============ Phase 2: Incidents Action (Deduplication) ============\n\n/**\n * Deduplicate alert events into incidents\n * Groups Triggered events within a time window, pairs with Recovered events\n */\nexport async function incidentsEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n dedupeWindow?: string\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query ?? 'source:alert',\n sources: params.sources,\n tags: params.tags\n })\n\n // Parse dedupe window (default 5 minutes)\n const dedupeWindowNs = parseDurationToNs(params.dedupeWindow ?? '5m')\n const dedupeWindowMs = dedupeWindowNs ? Math.floor(dedupeWindowNs / 1000000) : 300000\n\n // Track incidents per monitor\n interface IncidentTracker {\n monitorName: string\n firstTrigger: Date\n lastTrigger: Date\n triggerCount: number\n recovered: boolean\n recoveredAt?: Date\n sample: EventSummaryV2\n }\n const incidents = new Map<string, IncidentTracker>()\n\n const maxEventsToProcess = 10000\n let eventCount = 0\n let pageCount = 0\n const maxPages = 100\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: { limit: 1000 }\n }\n\n let cursor: string | undefined\n\n while (pageCount < maxPages && eventCount < maxEventsToProcess) {\n const pageBody = { ...body, page: { ...body.page, cursor } }\n const response = await api.searchEvents({ body: pageBody })\n\n const events = response.data ?? []\n if (events.length === 0) break\n\n for (const event of events) {\n const formatted = formatEventV2(event)\n\n // Use monitorInfo.name if available, otherwise fall back to title\n const monitorName = formatted.monitorInfo?.name ?? formatted.title\n if (!monitorName) {\n eventCount++\n continue\n }\n\n const eventTs = new Date(formatted.timestamp)\n\n // Derive status from monitorInfo, alertType, or message content for v2 events\n let status = formatted.monitorInfo?.status?.toLowerCase() ?? ''\n if (!status && formatted.alertType) {\n // Map alertType to status for v2 events without structured monitorInfo\n const alertType = formatted.alertType.toLowerCase()\n if (alertType === 'error' || alertType === 'warning') {\n status = 'triggered'\n } else if (alertType === 'success') {\n status = 'recovered'\n }\n }\n // For source:alert events without explicit status, check message for recovery indicators\n // or default to 'triggered' since alert events are triggers by nature\n if (!status && formatted.source === 'alert') {\n const msgLower = formatted.message.toLowerCase()\n if (\n msgLower.includes('recovered') ||\n msgLower.includes('[ok]') ||\n msgLower.includes('resolved')\n ) {\n status = 'recovered'\n } else {\n status = 'triggered'\n }\n }\n\n const existing = incidents.get(monitorName)\n\n if (\n status === 'triggered' ||\n status === 'alert' ||\n status === 're-triggered' ||\n status === 'renotify'\n ) {\n if (existing) {\n // Check if within dedupe window\n const timeSinceLastTrigger = eventTs.getTime() - existing.lastTrigger.getTime()\n if (timeSinceLastTrigger <= dedupeWindowMs) {\n // Same incident, update\n existing.lastTrigger = eventTs\n existing.triggerCount++\n existing.sample = formatted // Keep latest sample\n } else {\n // New incident for this monitor, close old one\n // Store the old one with a unique key\n const oldKey = `${monitorName}::${existing.firstTrigger.toISOString()}`\n incidents.set(oldKey, existing)\n\n // Start new incident\n incidents.set(monitorName, {\n monitorName,\n firstTrigger: eventTs,\n lastTrigger: eventTs,\n triggerCount: 1,\n recovered: false,\n sample: formatted\n })\n }\n } else {\n // First trigger for this monitor\n incidents.set(monitorName, {\n monitorName,\n firstTrigger: eventTs,\n lastTrigger: eventTs,\n triggerCount: 1,\n recovered: false,\n sample: formatted\n })\n }\n } else if (status === 'recovered' || status === 'ok') {\n if (existing && !existing.recovered) {\n existing.recovered = true\n existing.recoveredAt = eventTs\n }\n }\n\n eventCount++\n if (eventCount >= maxEventsToProcess) break\n }\n\n cursor = response.meta?.page?.after\n if (!cursor) break\n pageCount++\n }\n\n // Convert to array and calculate durations\n const incidentList: IncidentEvent[] = [...incidents.values()].map((inc) => {\n let duration: string | undefined\n if (inc.recoveredAt) {\n const durationMs = inc.recoveredAt.getTime() - inc.firstTrigger.getTime()\n if (durationMs < 60000) {\n duration = `${Math.round(durationMs / 1000)}s`\n } else if (durationMs < 3600000) {\n duration = `${Math.round(durationMs / 60000)}m`\n } else {\n duration = `${(durationMs / 3600000).toFixed(1)}h`\n }\n }\n\n return {\n monitorName: inc.monitorName,\n firstTrigger: inc.firstTrigger.toISOString(),\n lastTrigger: inc.lastTrigger.toISOString(),\n triggerCount: inc.triggerCount,\n recovered: inc.recovered,\n recoveredAt: inc.recoveredAt?.toISOString(),\n duration,\n sample: inc.sample\n }\n })\n\n // Sort by first trigger descending, apply limit\n incidentList.sort(\n (a, b) => new Date(b.firstTrigger).getTime() - new Date(a.firstTrigger).getTime()\n )\n const effectiveLimit = Math.min(params.limit ?? 100, 500)\n\n return {\n incidents: incidentList.slice(0, effectiveLimit),\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n dedupeWindow: params.dedupeWindow ?? '5m',\n dedupeWindowMs,\n totalIncidents: incidentList.length,\n totalEvents: eventCount,\n recoveredCount: incidentList.filter((i) => i.recovered).length,\n activeCount: incidentList.filter((i) => !i.recovered).length,\n truncated: eventCount >= maxEventsToProcess,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n// ============ Phase 3: Monitor Metadata Enrichment ============\n\n/**\n * Enrich events with monitor metadata from the Monitors API\n */\nexport async function enrichWithMonitorMetadata(\n events: EventSummaryV2[],\n monitorsApi: v1.MonitorsApi\n): Promise<EnrichedEvent[]> {\n // Extract unique monitor names\n const monitorNames = new Set<string>()\n for (const event of events) {\n if (event.monitorInfo?.name) {\n monitorNames.add(event.monitorInfo.name)\n }\n }\n\n if (monitorNames.size === 0) {\n return events as EnrichedEvent[]\n }\n\n // Fetch monitors - search by name\n const monitorCache = new Map<string, v1.Monitor>()\n\n try {\n // Fetch all monitors and filter locally\n // The API doesn't support searching by exact name, so we need to filter\n const response = await monitorsApi.listMonitors({\n pageSize: 1000\n })\n\n const monitors = response ?? []\n for (const monitor of monitors) {\n if (monitor.name) {\n monitorCache.set(monitor.name, monitor)\n }\n }\n } catch {\n // If monitor fetch fails, return events without enrichment\n return events as EnrichedEvent[]\n }\n\n // Enrich events\n return events.map((event) => {\n const enriched: EnrichedEvent = { ...event }\n\n if (event.monitorInfo?.name) {\n const monitor = monitorCache.get(event.monitorInfo.name)\n if (monitor) {\n enriched.monitorMetadata = {\n id: monitor.id ?? 0,\n type: String(monitor.type ?? ''),\n message: monitor.message ?? '',\n tags: monitor.tags ?? [],\n options: {\n thresholds: monitor.options?.thresholds as Record<string, number> | undefined,\n notifyNoData: monitor.options?.notifyNoData,\n escalationMessage: monitor.options?.escalationMessage\n }\n }\n }\n }\n\n return enriched\n })\n}\n\nexport function registerEventsTool(\n server: McpServer,\n apiV1: v1.EventsApi,\n apiV2: v2.EventsApi,\n monitorsApi: v1.MonitorsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'events',\n `Track Datadog events. Actions: list, get, create, search, aggregate, top, timeseries, incidents.\nIMPORTANT: For monitor alert history, use tags: [\"source:alert\"] to find all triggered monitors.\nFilters: query (text search), sources, tags, priority, time range.\nUse for: monitor alerts, deployments, incidents, change tracking.\n\nUse action:\"top\" with from:\"7d\" to find the noisiest monitors.\nUse action:\"aggregate\" with groupBy:[\"monitor_name\"] for alert counts per monitor.\nUse action:\"timeseries\" with interval:\"1h\" to see alert trends over time.\nUse action:\"incidents\" with dedupeWindow:\"5m\" to deduplicate alerts into incidents.\nUse enrich:true with search to get monitor metadata (slower).`,\n InputSchema,\n async ({\n action,\n id,\n query,\n from,\n to,\n priority,\n sources,\n tags,\n limit,\n title,\n text,\n alertType,\n groupBy,\n cursor,\n interval,\n dedupeWindow,\n enrich\n }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listEventsV1(\n apiV1,\n {\n query,\n from,\n to,\n priority,\n sources,\n tags,\n limit\n },\n limits\n )\n )\n\n case 'get': {\n const eventId = requireParam(id, 'id', 'get')\n return toolResult(await getEventV1(apiV1, eventId))\n }\n\n case 'create': {\n const eventTitle = requireParam(title, 'title', 'create')\n const eventText = requireParam(text, 'text', 'create')\n return toolResult(\n await createEventV1(apiV1, {\n title: eventTitle,\n text: eventText,\n priority,\n tags,\n alertType\n })\n )\n }\n\n case 'search': {\n const result = await searchEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n priority,\n limit,\n cursor\n },\n limits,\n site\n )\n\n // Phase 3: Optional enrichment\n if (enrich && result.events.length > 0) {\n const enrichedEvents = await enrichWithMonitorMetadata(result.events, monitorsApi)\n return toolResult({ ...result, events: enrichedEvents })\n }\n\n return toolResult(result)\n }\n\n case 'aggregate':\n return toolResult(\n await aggregateEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n groupBy,\n limit\n },\n limits,\n site\n )\n )\n\n case 'top':\n return toolResult(\n await topEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n groupBy,\n limit\n },\n limits,\n site\n )\n )\n\n case 'timeseries':\n return toolResult(\n await timeseriesEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n groupBy,\n interval,\n limit\n },\n limits,\n site\n )\n )\n\n case 'incidents':\n return toolResult(\n await incidentsEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n dedupeWindow,\n limit\n },\n limits,\n site\n )\n )\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'search', 'create', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Incident ID (required for get/update/delete)'),\n query: z.string().optional().describe('Search query (for search action)'),\n status: z\n .enum(['active', 'stable', 'resolved'])\n .optional()\n .describe('Filter by status (for list)'),\n limit: z.number().optional().describe('Maximum number of incidents to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe(\n 'Incident configuration (for create/update). Create requires: title. Update can modify: title, status, severity, fields.'\n )\n}\n\ninterface IncidentSummary {\n id: string\n title: string\n status: string\n severity: string | null\n state: string | null\n customerImpactScope: string | null\n customerImpacted: boolean\n commander: {\n name: string | null\n email: string | null\n handle: string | null\n }\n createdAt: string\n modifiedAt: string\n resolvedAt: string | null\n timeToDetect: number | null\n timeToRepair: number | null\n}\n\nexport function formatIncident(i: v2.IncidentResponseData): IncidentSummary {\n const attrs = i.attributes\n const commander = i.relationships?.commanderUser?.data\n return {\n id: i.id ?? '',\n title: attrs?.title ?? '',\n status: String(attrs?.state ?? 'unknown'),\n severity: attrs?.severity ? String(attrs.severity) : null,\n state: attrs?.state ? String(attrs.state) : null,\n customerImpactScope: attrs?.customerImpactScope ?? null,\n customerImpacted: attrs?.customerImpacted ?? false,\n commander: {\n name: null, // Would need to resolve from relationships\n email: null,\n handle: commander?.id ?? null\n },\n createdAt: attrs?.created ? new Date(attrs.created).toISOString() : '',\n modifiedAt: attrs?.modified ? new Date(attrs.modified).toISOString() : '',\n resolvedAt: attrs?.resolved ? new Date(attrs.resolved).toISOString() : null,\n timeToDetect: attrs?.timeToDetect ?? null,\n timeToRepair: attrs?.timeToRepair ?? null\n }\n}\n\nexport async function listIncidents(\n api: v2.IncidentsApi,\n params: { status?: 'active' | 'stable' | 'resolved'; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n // Note: listIncidents is an unstable operation that requires enablement\n const response = await api.listIncidents({\n pageSize: effectiveLimit\n })\n\n let incidents = (response.data ?? []).map(formatIncident)\n\n // Filter by status client-side if specified\n if (params.status) {\n incidents = incidents.filter((i) => i.state?.toLowerCase() === params.status)\n }\n\n // Apply limit after filtering (in case status filter reduced count)\n incidents = incidents.slice(0, effectiveLimit)\n\n return {\n incidents,\n total: incidents.length\n }\n}\n\nexport async function getIncident(api: v2.IncidentsApi, id: string) {\n const response = await api.getIncident({ incidentId: id })\n return {\n incident: response.data ? formatIncident(response.data) : null\n }\n}\n\nexport async function searchIncidents(api: v2.IncidentsApi, query: string, limits: LimitsConfig) {\n const response = await api.searchIncidents({\n query,\n pageSize: limits.maxResults\n })\n\n const incidents = (response.data?.attributes?.incidents ?? []).map(\n (i: v2.IncidentSearchResponseIncidentsData) => ({\n id: i.data?.id ?? '',\n title: i.data?.attributes?.title ?? '',\n state: i.data?.attributes?.state ?? 'unknown'\n })\n )\n\n return {\n incidents,\n total: response.data?.attributes?.total ?? incidents.length\n }\n}\n\nexport async function createIncident(api: v2.IncidentsApi, config: Record<string, unknown>) {\n const body = {\n data: {\n type: 'incidents' as const,\n attributes: config\n }\n } as unknown as v2.IncidentCreateRequest\n\n const response = await api.createIncident({ body })\n return {\n success: true,\n incident: response.data ? formatIncident(response.data) : null\n }\n}\n\nexport async function updateIncident(\n api: v2.IncidentsApi,\n id: string,\n config: Record<string, unknown>\n) {\n const body = {\n data: {\n type: 'incidents' as const,\n id,\n attributes: config\n }\n } as unknown as v2.IncidentUpdateRequest\n\n const response = await api.updateIncident({ incidentId: id, body })\n return {\n success: true,\n incident: response.data ? formatIncident(response.data) : null\n }\n}\n\nexport async function deleteIncident(api: v2.IncidentsApi, id: string) {\n await api.deleteIncident({ incidentId: id })\n return {\n success: true,\n message: `Incident ${id} deleted`\n }\n}\n\nexport function registerIncidentsTool(\n server: McpServer,\n api: v2.IncidentsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'incidents',\n 'Manage Datadog incidents for incident response. Actions: list, get, search, create, update, delete. Use for: incident management, on-call response, postmortems, tracking MTTR/MTTD.',\n InputSchema,\n async ({ action, id, query, status, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listIncidents(api, { status, limit }, limits))\n\n case 'get': {\n const incidentId = requireParam(id, 'id', 'get')\n return toolResult(await getIncident(api, incidentId))\n }\n\n case 'search': {\n const searchQuery = requireParam(query, 'query', 'search')\n return toolResult(await searchIncidents(api, searchQuery, limits))\n }\n\n case 'create': {\n const incidentConfig = requireParam(config, 'config', 'create')\n return toolResult(await createIncident(api, incidentConfig))\n }\n\n case 'update': {\n const incidentId = requireParam(id, 'id', 'update')\n const incidentConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateIncident(api, incidentId, incidentConfig))\n }\n\n case 'delete': {\n const incidentId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteIncident(api, incidentId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime, ensureValidTimeRange } from '../utils/time.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete', 'history'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('SLO ID (required for get/update/delete/history)'),\n ids: z.array(z.string()).optional().describe('Multiple SLO IDs (for list with specific IDs)'),\n query: z.string().optional().describe('Search query (for list)'),\n tags: z.array(z.string()).optional().describe('Filter by tags (for list)'),\n limit: z.number().optional().describe('Maximum number of SLOs to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe('SLO configuration (for create/update). Must include type, name, thresholds.'),\n from: z\n .string()\n .optional()\n .describe('Start time for history (ISO 8601 or relative like \"7d\", \"1w\")'),\n to: z.string().optional().describe('End time for history (ISO 8601 or relative, default: now)')\n}\n\ninterface SloSummary {\n id: string\n name: string\n description: string | null\n type: string\n targetThreshold: number\n warningThreshold: number | null\n timeframe: string\n tags: string[]\n status: {\n sli: number | null\n errorBudgetRemaining: number | null\n state: string\n }\n createdAt: string\n modifiedAt: string\n}\n\nexport function formatSlo(s: v1.ServiceLevelObjective | v1.SLOResponseData): SloSummary {\n const primaryThreshold = s.thresholds?.[0]\n return {\n id: s.id ?? '',\n name: s.name ?? '',\n description: s.description ?? null,\n type: String(s.type ?? 'unknown'),\n targetThreshold: primaryThreshold?.target ?? 0,\n warningThreshold: primaryThreshold?.warning ?? null,\n timeframe: String(primaryThreshold?.timeframe ?? ''),\n tags: s.tags ?? [],\n status: {\n // Note: SLI status requires a separate API call to getSLOHistory\n sli: null,\n errorBudgetRemaining: null,\n state: 'unknown'\n },\n createdAt: s.createdAt ? new Date(s.createdAt * 1000).toISOString() : '',\n modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1000).toISOString() : ''\n }\n}\n\nexport async function listSlos(\n api: v1.ServiceLevelObjectivesApi,\n params: { ids?: string[]; query?: string; tags?: string[]; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listSLOs({\n ids: params.ids?.join(','),\n query: params.query,\n tagsQuery: params.tags?.join(','),\n limit: effectiveLimit\n })\n\n const slos = (response.data ?? []).map(formatSlo)\n\n return {\n slos,\n total: response.data?.length ?? 0\n }\n}\n\nexport async function getSlo(api: v1.ServiceLevelObjectivesApi, id: string) {\n const response = await api.getSLO({ sloId: id })\n return {\n slo: response.data ? formatSlo(response.data) : null\n }\n}\n\n/**\n * Recursively convert snake_case keys to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())\n}\n\nexport function normalizeConfigKeys(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj\n if (Array.isArray(obj)) return obj.map(normalizeConfigKeys)\n if (typeof obj !== 'object') return obj\n\n const normalized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const camelKey = snakeToCamel(key)\n normalized[camelKey] = normalizeConfigKeys(value)\n }\n return normalized\n}\n\n/**\n * Normalize SLO config to handle snake_case -> camelCase\n */\nexport function normalizeSloConfig(config: Record<string, unknown>): Record<string, unknown> {\n const normalized = normalizeConfigKeys(config) as Record<string, unknown>\n\n // Validate required fields\n if (!normalized.name) {\n throw new Error(\"SLO config requires 'name' field\")\n }\n if (!normalized.type) {\n throw new Error(\"SLO config requires 'type' field (e.g., 'metric', 'monitor')\")\n }\n if (!normalized.thresholds || !Array.isArray(normalized.thresholds)) {\n throw new Error(\"SLO config requires 'thresholds' array with at least one threshold\")\n }\n\n return normalized\n}\n\nexport async function createSlo(\n api: v1.ServiceLevelObjectivesApi,\n config: Record<string, unknown>\n) {\n const body = normalizeSloConfig(config) as unknown as v1.ServiceLevelObjectiveRequest\n const response = await api.createSLO({ body })\n return {\n success: true,\n slo: response.data?.[0] ? formatSlo(response.data[0]) : null\n }\n}\n\nexport async function updateSlo(\n api: v1.ServiceLevelObjectivesApi,\n id: string,\n config: Record<string, unknown>\n) {\n const body = normalizeConfigKeys(config) as unknown as v1.ServiceLevelObjective\n const response = await api.updateSLO({ sloId: id, body })\n return {\n success: true,\n slo: response.data?.[0] ? formatSlo(response.data[0]) : null\n }\n}\n\nexport async function deleteSlo(api: v1.ServiceLevelObjectivesApi, id: string) {\n await api.deleteSLO({ sloId: id })\n return {\n success: true,\n message: `SLO ${id} deleted`\n }\n}\n\nexport async function getSloHistory(\n api: v1.ServiceLevelObjectivesApi,\n id: string,\n params: { from?: string; to?: string }\n) {\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 7 * 24 * 60 * 60 * 1000 // Default 7 days\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000)) * 1000\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000)) * 1000\n\n const [validFrom, validTo] = ensureValidTimeRange(fromTime, toTime)\n\n const response = await api.getSLOHistory({\n sloId: id,\n fromTs: Math.floor(validFrom / 1000),\n toTs: Math.floor(validTo / 1000)\n })\n\n const data = response.data\n return {\n history: {\n overall: {\n sliValue: data?.overall?.sliValue ?? null,\n spanPrecision: data?.overall?.spanPrecision ?? null,\n uptime: data?.overall?.uptime ?? null\n },\n series: {\n numerator: data?.series?.numerator?.values ?? [],\n denominator: data?.series?.denominator?.values ?? [],\n times: data?.series?.times ?? []\n },\n thresholds: data?.thresholds ?? {},\n fromTs: new Date(validFrom).toISOString(),\n toTs: new Date(validTo).toISOString()\n }\n }\n}\n\nexport function registerSlosTool(\n server: McpServer,\n api: v1.ServiceLevelObjectivesApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'slos',\n 'Manage Datadog Service Level Objectives. Actions: list, get, create, update, delete, history. SLO types: metric-based, monitor-based. Use for: reliability tracking, error budgets, SLA compliance, performance targets.',\n InputSchema,\n async ({ action, id, ids, query, tags, limit, config, from, to }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listSlos(api, { ids, query, tags, limit }, limits))\n\n case 'get': {\n const sloId = requireParam(id, 'id', 'get')\n return toolResult(await getSlo(api, sloId))\n }\n\n case 'create': {\n const sloConfig = requireParam(config, 'config', 'create')\n return toolResult(await createSlo(api, sloConfig))\n }\n\n case 'update': {\n const sloId = requireParam(id, 'id', 'update')\n const sloConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateSlo(api, sloId, sloConfig))\n }\n\n case 'delete': {\n const sloId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteSlo(api, sloId))\n }\n\n case 'history': {\n const sloId = requireParam(id, 'id', 'history')\n return toolResult(await getSloHistory(api, sloId, { from, to }))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete', 'trigger', 'results'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z\n .string()\n .optional()\n .describe('Test public ID (required for get/update/delete/trigger/results)'),\n ids: z.array(z.string()).optional().describe('Multiple test IDs (for bulk trigger)'),\n testType: z\n .enum(['api', 'browser'])\n .optional()\n .describe('Test type filter (for list) or type for create'),\n locations: z.array(z.string()).optional().describe('Filter by locations (for list)'),\n tags: z.array(z.string()).optional().describe('Filter by tags (for list)'),\n limit: z.number().optional().describe('Maximum number of tests to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe(\n 'Test configuration (for create/update). Includes: name, type, config, options, locations, message.'\n )\n}\n\ninterface SyntheticTestSummary {\n publicId: string\n name: string\n type: string\n subtype: string | null\n status: string\n message: string\n tags: string[]\n locations: string[]\n monitorId: number | null\n}\n\nexport function formatTest(t: v1.SyntheticsTestDetails): SyntheticTestSummary {\n return {\n publicId: t.publicId ?? '',\n name: t.name ?? '',\n type: String(t.type ?? 'unknown'),\n subtype: t.subtype ? String(t.subtype) : null,\n status: String(t.status ?? 'unknown'),\n message: t.message ?? '',\n tags: t.tags ?? [],\n locations: t.locations ?? [],\n monitorId: t.monitorId ?? null\n }\n}\n\nexport async function listTests(\n api: v1.SyntheticsApi,\n params: { locations?: string[]; tags?: string[]; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n // Note: listTests API only accepts pageSize/pageNumber, filtering done client-side\n const response = await api.listTests({\n pageSize: effectiveLimit\n })\n\n let tests = (response.tests ?? []).map(formatTest)\n\n // Client-side filtering by tags\n if (params.tags && params.tags.length > 0) {\n tests = tests.filter((t) => params.tags!.some((tag) => t.tags.includes(tag)))\n }\n\n // Client-side filtering by locations\n if (params.locations && params.locations.length > 0) {\n tests = tests.filter((t) => params.locations!.some((loc) => t.locations.includes(loc)))\n }\n\n tests = tests.slice(0, effectiveLimit)\n\n const summary = {\n total: response.tests?.length ?? 0,\n api: tests.filter((t) => t.type === 'api').length,\n browser: tests.filter((t) => t.type === 'browser').length,\n passing: tests.filter((t) => t.status === 'OK' || t.status === 'live').length,\n failing: tests.filter((t) => t.status === 'Alert').length\n }\n\n return { tests, summary }\n}\n\nexport async function getTest(api: v1.SyntheticsApi, id: string) {\n // Try API test first, then browser\n try {\n const response = await api.getAPITest({ publicId: id })\n return { test: formatTest(response) }\n } catch {\n const response = await api.getBrowserTest({ publicId: id })\n return { test: formatTest(response) }\n }\n}\n\n/**\n * Recursively convert snake_case keys to camelCase in an object\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())\n}\n\nexport function normalizeConfigKeys(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj\n if (Array.isArray(obj)) return obj.map(normalizeConfigKeys)\n if (typeof obj !== 'object') return obj\n\n const normalized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const camelKey = snakeToCamel(key)\n normalized[camelKey] = normalizeConfigKeys(value)\n }\n return normalized\n}\n\n/**\n * Normalize synthetics test config to handle snake_case -> camelCase\n */\nexport function normalizeSyntheticsConfig(\n config: Record<string, unknown>\n): Record<string, unknown> {\n // Recursively convert all snake_case keys to camelCase\n const normalized = normalizeConfigKeys(config) as Record<string, unknown>\n\n // Validate required fields\n if (!normalized.name) {\n throw new Error(\"Synthetics test config requires 'name' field\")\n }\n if (\n !normalized.locations ||\n !Array.isArray(normalized.locations) ||\n normalized.locations.length === 0\n ) {\n throw new Error(\"Synthetics test config requires 'locations' array (e.g., ['aws:us-east-1'])\")\n }\n\n return normalized\n}\n\nexport async function createTest(\n api: v1.SyntheticsApi,\n config: Record<string, unknown>,\n testType?: 'api' | 'browser'\n) {\n const normalizedConfig = normalizeSyntheticsConfig(config)\n const type = testType ?? (normalizedConfig.type === 'browser' ? 'browser' : 'api')\n\n if (type === 'browser') {\n const body = normalizedConfig as unknown as v1.SyntheticsBrowserTest\n const response = await api.createSyntheticsBrowserTest({ body })\n return {\n success: true,\n test: formatTest(response)\n }\n } else {\n const body = normalizedConfig as unknown as v1.SyntheticsAPITest\n const response = await api.createSyntheticsAPITest({ body })\n return {\n success: true,\n test: formatTest(response)\n }\n }\n}\n\nexport async function updateTest(\n api: v1.SyntheticsApi,\n id: string,\n config: Record<string, unknown>\n) {\n // Normalize config first\n const normalizedConfig = normalizeConfigKeys(config) as Record<string, unknown>\n\n // Determine test type by fetching it first\n let testType: 'api' | 'browser'\n try {\n await api.getAPITest({ publicId: id })\n testType = 'api'\n } catch {\n testType = 'browser'\n }\n\n if (testType === 'browser') {\n const body = normalizedConfig as unknown as v1.SyntheticsBrowserTest\n const response = await api.updateBrowserTest({ publicId: id, body })\n return {\n success: true,\n test: formatTest(response)\n }\n } else {\n const body = normalizedConfig as unknown as v1.SyntheticsAPITest\n const response = await api.updateAPITest({ publicId: id, body })\n return {\n success: true,\n test: formatTest(response)\n }\n }\n}\n\nexport async function deleteTests(api: v1.SyntheticsApi, ids: string[]) {\n await api.deleteTests({\n body: { publicIds: ids }\n })\n return {\n success: true,\n message: `Deleted ${ids.length} test(s): ${ids.join(', ')}`\n }\n}\n\nexport async function triggerTests(api: v1.SyntheticsApi, ids: string[]) {\n const response = await api.triggerTests({\n body: {\n tests: ids.map((id) => ({ publicId: id }))\n }\n })\n\n const results =\n response.results?.map((r) => ({\n publicId: r.publicId ?? '',\n resultId: r.resultId ?? '',\n triggered: true\n })) ?? []\n\n return {\n triggered: results,\n total: results.length\n }\n}\n\nexport async function getTestResults(api: v1.SyntheticsApi, id: string) {\n // Try API test results first, then browser\n try {\n const response = await api.getAPITestLatestResults({ publicId: id })\n const results = (response.results ?? []).map((r) => ({\n resultId: r.resultId ?? '',\n status: r.result?.passed ? 'passed' : 'failed',\n checkTime: r.checkTime ? new Date(r.checkTime * 1000).toISOString() : '',\n responseTime: r.result?.timings?.total ?? null\n }))\n return { results, testType: 'api' }\n } catch {\n const response = await api.getBrowserTestLatestResults({ publicId: id })\n const results = (response.results ?? []).map((r) => ({\n resultId: r.resultId ?? '',\n // Browser tests don't have 'passed' - determine from errorCount\n status: (r.result?.errorCount ?? 0) === 0 ? 'passed' : 'failed',\n checkTime: r.checkTime ? new Date(r.checkTime * 1000).toISOString() : '',\n duration: r.result?.duration ?? null\n }))\n return { results, testType: 'browser' }\n }\n}\n\nexport function registerSyntheticsTool(\n server: McpServer,\n api: v1.SyntheticsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'synthetics',\n 'Manage Datadog Synthetic tests (API and Browser). Actions: list, get, create, update, delete, trigger, results. Use for: uptime monitoring, API testing, user journey testing, performance testing, canary deployments.',\n InputSchema,\n async ({ action, id, ids, testType, locations, tags, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listTests(api, { locations, tags, limit }, limits))\n\n case 'get': {\n const testId = requireParam(id, 'id', 'get')\n return toolResult(await getTest(api, testId))\n }\n\n case 'create': {\n const testConfig = requireParam(config, 'config', 'create')\n return toolResult(await createTest(api, testConfig, testType))\n }\n\n case 'update': {\n const testId = requireParam(id, 'id', 'update')\n const testConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateTest(api, testId, testConfig))\n }\n\n case 'delete': {\n const testIds = ids ?? (id ? [id] : undefined)\n const deleteIds = requireParam(testIds, 'id or ids', 'delete')\n return toolResult(await deleteTests(api, deleteIds))\n }\n\n case 'trigger': {\n const testIds = ids ?? (id ? [id] : undefined)\n const triggerIds = requireParam(testIds, 'id or ids', 'trigger')\n return toolResult(await triggerTests(api, triggerIds))\n }\n\n case 'results': {\n const testId = requireParam(id, 'id', 'results')\n return toolResult(await getTestResults(api, testId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'totals', 'mute', 'unmute'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n filter: z.string().optional().describe('Filter hosts by name, alias, or tag (e.g., \"env:prod\")'),\n from: z.number().optional().describe('Starting offset for pagination'),\n count: z.number().optional().describe('Number of hosts to return'),\n sortField: z.string().optional().describe('Field to sort by (e.g., \"apps\", \"cpu\", \"name\")'),\n sortDir: z.enum(['asc', 'desc']).optional().describe('Sort direction'),\n hostName: z.string().optional().describe('Host name (required for mute/unmute)'),\n message: z.string().optional().describe('Mute reason message'),\n end: z.number().optional().describe('Mute end timestamp (POSIX). Omit for indefinite mute'),\n override: z.boolean().optional().describe('If true, replaces existing mute instead of failing')\n}\n\ninterface HostSummary {\n hostName: string\n aliases: string[]\n apps: string[]\n sources: string[]\n up: boolean\n isMuted: boolean\n muteTimeout: number | null\n lastReportedTime: string\n meta: {\n cpuCores: number | null\n platform: string | null\n gohai: string | null\n }\n}\n\nexport function formatHost(h: v1.Host): HostSummary {\n return {\n hostName: h.hostName ?? '',\n aliases: h.aliases ?? [],\n apps: h.apps ?? [],\n sources: h.sources ?? [],\n up: h.up ?? false,\n isMuted: h.isMuted ?? false,\n muteTimeout: h.muteTimeout ?? null,\n lastReportedTime: h.lastReportedTime ? new Date(h.lastReportedTime * 1000).toISOString() : '',\n meta: {\n cpuCores: h.meta?.cpuCores ?? null,\n platform: h.meta?.platform ?? null,\n gohai: h.meta?.gohai ?? null\n }\n }\n}\n\nexport async function listHosts(\n api: v1.HostsApi,\n params: {\n filter?: string\n from?: number\n count?: number\n sortField?: string\n sortDir?: 'asc' | 'desc'\n },\n limits: LimitsConfig\n) {\n const response = await api.listHosts({\n filter: params.filter,\n from: params.from,\n count: Math.min(params.count ?? limits.maxResults, limits.maxResults),\n sortField: params.sortField,\n sortDir: params.sortDir\n })\n\n const hosts = (response.hostList ?? []).map(formatHost)\n\n return {\n hosts,\n totalReturned: response.totalReturned ?? hosts.length,\n totalMatching: response.totalMatching ?? hosts.length\n }\n}\n\nexport async function getHostTotals(api: v1.HostsApi) {\n const response = await api.getHostTotals({})\n return {\n totals: {\n totalUp: response.totalUp ?? 0,\n totalActive: response.totalActive ?? 0\n }\n }\n}\n\nexport async function muteHost(\n api: v1.HostsApi,\n hostName: string,\n params: { message?: string; end?: number; override?: boolean }\n) {\n await api.muteHost({\n hostName,\n body: {\n message: params.message,\n end: params.end,\n override: params.override\n }\n })\n const muteEndMessage = params.end\n ? ` until ${new Date(params.end * 1000).toISOString()}`\n : ' indefinitely'\n return {\n success: true,\n message: `Host ${hostName} muted${muteEndMessage}`\n }\n}\n\nexport async function unmuteHost(api: v1.HostsApi, hostName: string) {\n await api.unmuteHost({ hostName })\n return {\n success: true,\n message: `Host ${hostName} unmuted`\n }\n}\n\nexport function registerHostsTool(\n server: McpServer,\n api: v1.HostsApi,\n limits: LimitsConfig,\n readOnly: boolean = false\n): void {\n server.tool(\n 'hosts',\n 'Manage Datadog infrastructure hosts. Actions: list (with filters), totals (counts), mute (silence alerts), unmute. Use for: infrastructure inventory, host health, silencing noisy hosts during maintenance.',\n InputSchema,\n async ({\n action,\n filter,\n from,\n count,\n sortField,\n sortDir,\n hostName,\n message,\n end,\n override\n }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listHosts(api, { filter, from, count, sortField, sortDir }, limits)\n )\n\n case 'totals':\n return toolResult(await getHostTotals(api))\n\n case 'mute': {\n const host = requireParam(hostName, 'hostName', 'mute')\n return toolResult(await muteHost(api, host, { message, end, override }))\n }\n\n case 'unmute': {\n const host = requireParam(hostName, 'hostName', 'unmute')\n return toolResult(await unmuteHost(api, host))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'cancel', 'listByMonitor'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Downtime ID (required for get/update/cancel)'),\n monitorId: z.number().optional().describe('Monitor ID (required for listByMonitor)'),\n currentOnly: z.boolean().optional().describe('Only return active downtimes (for list)'),\n limit: z.number().optional().describe('Maximum number of downtimes to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe('Downtime configuration (for create/update). Must include scope and schedule.')\n}\n\ninterface DowntimeSummary {\n id: string\n displayTimezone: string\n message: string | null\n monitorIdentifier: {\n monitorId: number | null\n monitorTags: string[]\n }\n scope: string\n status: string\n schedule: unknown\n createdAt: string\n modifiedAt: string\n}\n\nexport function extractMonitorIdentifier(mi?: v2.DowntimeMonitorIdentifier): {\n monitorId: number | null\n monitorTags: string[]\n} {\n if (!mi) return { monitorId: null, monitorTags: [] }\n\n // Check if it's a DowntimeMonitorIdentifierId (has monitorId property)\n if ('monitorId' in mi && typeof mi.monitorId === 'number') {\n return { monitorId: mi.monitorId, monitorTags: [] }\n }\n\n // Check if it's a DowntimeMonitorIdentifierTags (has monitorTags property)\n if ('monitorTags' in mi && Array.isArray(mi.monitorTags)) {\n return { monitorId: null, monitorTags: mi.monitorTags }\n }\n\n return { monitorId: null, monitorTags: [] }\n}\n\nexport function formatDowntime(d: v2.DowntimeResponseData): DowntimeSummary {\n const attrs = d.attributes\n const status = attrs?.status\n return {\n id: d.id ?? '',\n displayTimezone: attrs?.displayTimezone ?? 'UTC',\n message: attrs?.message ?? null,\n monitorIdentifier: extractMonitorIdentifier(attrs?.monitorIdentifier),\n scope: attrs?.scope ?? '',\n status: typeof status === 'string' ? status : 'unknown',\n schedule: attrs?.schedule ?? null,\n createdAt: attrs?.created ? new Date(attrs.created).toISOString() : '',\n modifiedAt: attrs?.modified ? new Date(attrs.modified).toISOString() : ''\n }\n}\n\nexport async function listDowntimes(\n api: v2.DowntimesApi,\n params: { currentOnly?: boolean; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listDowntimes({\n currentOnly: params.currentOnly\n })\n\n const downtimes = (response.data ?? []).slice(0, effectiveLimit).map(formatDowntime)\n\n return {\n downtimes,\n total: response.data?.length ?? 0\n }\n}\n\nexport async function getDowntime(api: v2.DowntimesApi, id: string) {\n const response = await api.getDowntime({ downtimeId: id })\n return {\n downtime: response.data ? formatDowntime(response.data) : null\n }\n}\n\n/**\n * Normalize downtime config to handle property name conversion and date formatting\n * - Converts snake_case user input to camelCase for SDK compatibility\n * - One-time schedules: convert ISO strings to Date objects\n * - Recurring schedules: keep dates as strings\n */\nexport function normalizeDowntimeConfig(config: Record<string, unknown>): Record<string, unknown> {\n // Step 1: Convert top-level snake_case keys to camelCase\n // SDK expects camelCase internally and converts to snake_case for HTTP API\n const keyMapping: Record<string, string> = {\n monitor_identifier: 'monitorIdentifier',\n display_timezone: 'displayTimezone',\n mute_first_recovery_notification: 'muteFirstRecoveryNotification',\n notify_end_states: 'notifyEndStates',\n notify_end_types: 'notifyEndTypes'\n }\n\n const normalized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(config)) {\n const newKey = keyMapping[key] || key\n normalized[newKey] = value\n }\n\n // Step 2: Handle nested monitorIdentifier conversion (monitor_id → monitorId, monitor_tags → monitorTags)\n if (normalized.monitorIdentifier && typeof normalized.monitorIdentifier === 'object') {\n const mi = { ...(normalized.monitorIdentifier as Record<string, unknown>) }\n if ('monitor_id' in mi) {\n mi.monitorId = mi.monitor_id\n delete mi.monitor_id\n }\n if ('monitor_tags' in mi) {\n mi.monitorTags = mi.monitor_tags\n delete mi.monitor_tags\n }\n normalized.monitorIdentifier = mi\n }\n\n // Step 3: Handle schedule date conversions and timezone\n if (normalized.schedule && typeof normalized.schedule === 'object') {\n const schedule = { ...(normalized.schedule as Record<string, unknown>) }\n\n // Detect schedule type:\n // - Recurring if it has 'duration' and 'rrule' fields\n // - One-time otherwise\n const isRecurring = 'duration' in schedule && 'rrule' in schedule\n\n if (!isRecurring) {\n // One-time schedule: convert ISO string dates to Date objects\n if (schedule.start && typeof schedule.start === 'string') {\n schedule.start = new Date(schedule.start)\n }\n if (schedule.end && typeof schedule.end === 'string') {\n schedule.end = new Date(schedule.end)\n }\n\n // Move timezone to displayTimezone at top level if present in schedule\n if (schedule.timezone && !normalized.displayTimezone) {\n normalized.displayTimezone = schedule.timezone\n }\n // Remove timezone from one-time schedule (not a valid field)\n delete schedule.timezone\n }\n // For recurring schedules, keep dates as strings (no conversion needed)\n\n normalized.schedule = schedule\n }\n\n return normalized\n}\n\nexport async function createDowntime(api: v2.DowntimesApi, config: Record<string, unknown>) {\n const normalizedConfig = normalizeDowntimeConfig(config)\n const body = {\n data: {\n type: 'downtime' as const,\n attributes: normalizedConfig\n }\n } as unknown as v2.DowntimeCreateRequest\n\n const response = await api.createDowntime({ body })\n return {\n success: true,\n downtime: response.data ? formatDowntime(response.data) : null\n }\n}\n\nexport async function updateDowntime(\n api: v2.DowntimesApi,\n id: string,\n config: Record<string, unknown>\n) {\n const normalizedConfig = normalizeDowntimeConfig(config)\n const body = {\n data: {\n type: 'downtime' as const,\n id,\n attributes: normalizedConfig\n }\n } as unknown as v2.DowntimeUpdateRequest\n\n const response = await api.updateDowntime({ downtimeId: id, body })\n return {\n success: true,\n downtime: response.data ? formatDowntime(response.data) : null\n }\n}\n\nexport async function cancelDowntime(api: v2.DowntimesApi, id: string) {\n await api.cancelDowntime({ downtimeId: id })\n return {\n success: true,\n message: `Downtime ${id} cancelled`\n }\n}\n\ninterface MonitorDowntimeSummary {\n id: string\n scope: string | null\n start: string | null\n end: string | null\n}\n\nexport function formatMonitorDowntime(\n d: v2.MonitorDowntimeMatchResponseData\n): MonitorDowntimeSummary {\n const attrs = d.attributes\n return {\n id: d.id ?? '',\n scope: attrs?.scope ?? null,\n start: attrs?.start ? new Date(attrs.start).toISOString() : null,\n end: attrs?.end ? new Date(attrs.end).toISOString() : null\n }\n}\n\nexport async function listMonitorDowntimes(\n api: v2.DowntimesApi,\n monitorId: number,\n limits: LimitsConfig\n) {\n const response = await api.listMonitorDowntimes({ monitorId })\n const downtimes = (response.data ?? []).slice(0, limits.maxResults).map(formatMonitorDowntime)\n\n return {\n downtimes,\n monitorId,\n total: response.data?.length ?? 0\n }\n}\n\nexport function registerDowntimesTool(\n server: McpServer,\n api: v2.DowntimesApi,\n limits: LimitsConfig,\n readOnly: boolean = false\n): void {\n server.tool(\n 'downtimes',\n 'Manage Datadog scheduled downtimes for maintenance windows. Actions: list, get, create, update, cancel, listByMonitor. Use for: scheduling maintenance, preventing false alerts during deployments, managing recurring maintenance windows.',\n InputSchema,\n async ({ action, id, monitorId, currentOnly, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listDowntimes(api, { currentOnly, limit }, limits))\n\n case 'get': {\n const downtimeId = requireParam(id, 'id', 'get')\n return toolResult(await getDowntime(api, downtimeId))\n }\n\n case 'create': {\n const downtimeConfig = requireParam(config, 'config', 'create')\n return toolResult(await createDowntime(api, downtimeConfig))\n }\n\n case 'update': {\n const downtimeId = requireParam(id, 'id', 'update')\n const downtimeConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateDowntime(api, downtimeId, downtimeConfig))\n }\n\n case 'cancel': {\n const downtimeId = requireParam(id, 'id', 'cancel')\n return toolResult(await cancelDowntime(api, downtimeId))\n }\n\n case 'listByMonitor': {\n const monitor = requireParam(monitorId, 'monitorId', 'listByMonitor')\n return toolResult(await listMonitorDowntimes(api, monitor, limits))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime } from '../utils/time.js'\nimport { buildRumUrl, buildRumSessionUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['applications', 'events', 'aggregate', 'performance', 'waterfall'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe('RUM query string (e.g., \"@type:view @application.id:abc\")'),\n from: z\n .string()\n .optional()\n .describe('Start time (ISO 8601, relative like \"1h\", \"7d\", or precise like \"1d@10:00\")'),\n to: z\n .string()\n .optional()\n .describe('End time (ISO 8601, relative like \"now\", or precise timestamp)'),\n type: z\n .enum(['all', 'view', 'action', 'error', 'long_task', 'resource'])\n .optional()\n .describe('RUM event type filter'),\n sort: z.enum(['timestamp', '-timestamp']).optional().describe('Sort order for events'),\n limit: z.number().optional().describe('Maximum number of events to return'),\n groupBy: z\n .array(z.string())\n .optional()\n .describe('Fields to group by for aggregation (e.g., [\"@view.url_path\", \"@session.type\"])'),\n compute: z\n .object({\n aggregation: z\n .enum(['count', 'cardinality', 'avg', 'sum', 'min', 'max', 'percentile'])\n .optional(),\n metric: z.string().optional(),\n interval: z.string().optional()\n })\n .optional()\n .describe('Compute configuration for aggregation'),\n // Performance action parameters\n metrics: z\n .array(z.enum(['lcp', 'fcp', 'cls', 'fid', 'inp', 'loading_time']))\n .optional()\n .describe(\n 'Core Web Vitals metrics to retrieve (default: all). lcp=Largest Contentful Paint, fcp=First Contentful Paint, cls=Cumulative Layout Shift, fid=First Input Delay, inp=Interaction to Next Paint, loading_time=View loading time'\n ),\n // Waterfall action parameters\n applicationId: z.string().optional().describe('Application ID for waterfall action'),\n sessionId: z.string().optional().describe('Session ID for waterfall action'),\n viewId: z\n .string()\n .optional()\n .describe('View ID for waterfall action (optional, filters to specific view)')\n}\n\ninterface RumApplicationSummary {\n id: string\n name: string\n type: string\n orgId: number\n hash: string | null\n createdAt: string\n updatedAt: string\n}\n\ninterface RumEventSummary {\n id: string\n type: string\n timestamp: string\n attributes: {\n application: {\n id: string | null\n name: string | null\n }\n session: {\n id: string | null\n type: string | null\n }\n view: {\n id: string | null\n url: string | null\n urlPath: string | null\n name: string | null\n }\n user: {\n id: string | null\n email: string | null\n name: string | null\n }\n action?: {\n id: string | null\n type: string | null\n name: string | null\n }\n error?: {\n message: string | null\n source: string | null\n stack: string | null\n }\n resource?: {\n url: string | null\n type: string | null\n duration: number | null\n }\n }\n}\n\nexport function formatApplication(app: v2.RUMApplicationList): RumApplicationSummary {\n const attrs = app.attributes ?? {}\n\n return {\n id: app.id ?? '',\n name: attrs.name ?? '',\n type: String(attrs.type ?? ''),\n orgId: attrs.orgId ?? 0,\n hash: attrs.hash ?? null,\n createdAt: attrs.createdAt ? new Date(attrs.createdAt).toISOString() : '',\n updatedAt: attrs.updatedAt ? new Date(attrs.updatedAt).toISOString() : ''\n }\n}\n\nexport function formatEvent(event: v2.RUMEvent): RumEventSummary {\n const attrs = event.attributes ?? {}\n const appAttrs = (attrs.attributes ?? {}) as Record<string, unknown>\n\n // Extract nested attributes safely\n const application = (appAttrs['application'] ?? {}) as Record<string, unknown>\n const session = (appAttrs['session'] ?? {}) as Record<string, unknown>\n const view = (appAttrs['view'] ?? {}) as Record<string, unknown>\n const usr = (appAttrs['usr'] ?? {}) as Record<string, unknown>\n const action = (appAttrs['action'] ?? {}) as Record<string, unknown>\n const error = (appAttrs['error'] ?? {}) as Record<string, unknown>\n const resource = (appAttrs['resource'] ?? {}) as Record<string, unknown>\n\n return {\n id: event.id ?? '',\n type: String(event.type ?? ''),\n timestamp: attrs.timestamp?.toISOString() ?? '',\n attributes: {\n application: {\n id: (application['id'] as string) ?? null,\n name: (application['name'] as string) ?? null\n },\n session: {\n id: (session['id'] as string) ?? null,\n type: (session['type'] as string) ?? null\n },\n view: {\n id: (view['id'] as string) ?? null,\n url: (view['url'] as string) ?? null,\n urlPath: (view['url_path'] as string) ?? null,\n name: (view['name'] as string) ?? null\n },\n user: {\n id: (usr['id'] as string) ?? null,\n email: (usr['email'] as string) ?? null,\n name: (usr['name'] as string) ?? null\n },\n action: action['id']\n ? {\n id: (action['id'] as string) ?? null,\n type: (action['type'] as string) ?? null,\n name: (action['name'] as string) ?? null\n }\n : undefined,\n error: error['message']\n ? {\n message: (error['message'] as string) ?? null,\n source: (error['source'] as string) ?? null,\n stack: (error['stack'] as string) ?? null\n }\n : undefined,\n resource: resource['url']\n ? {\n url: (resource['url'] as string) ?? null,\n type: (resource['type'] as string) ?? null,\n duration: (resource['duration'] as number) ?? null\n }\n : undefined\n }\n }\n}\n\nexport async function listApplications(api: v2.RUMApi) {\n const response = await api.getRUMApplications()\n const applications = (response.data ?? []).map(formatApplication)\n\n return {\n applications,\n totalCount: applications.length\n }\n}\n\nexport async function searchEvents(\n api: v2.RUMApi,\n params: {\n query?: string\n from?: string\n to?: string\n type?: string\n sort?: 'timestamp' | '-timestamp'\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n // Build query with type filter\n let queryString = params.query ?? '*'\n if (params.type && params.type !== 'all') {\n queryString = `@type:${params.type} ${queryString}`.trim()\n }\n\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 15 * 60 * 1000 // Default 15 minutes\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n const response = await api.listRUMEvents({\n filterQuery: queryString,\n filterFrom: new Date(fromTime * 1000),\n filterTo: new Date(toTime * 1000),\n sort: params.sort === 'timestamp' ? 'timestamp' : '-timestamp',\n pageLimit: Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n })\n\n const events = (response.data ?? []).map(formatEvent)\n\n return {\n events,\n meta: {\n totalCount: events.length,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n datadog_url: buildRumUrl(queryString, fromTime, toTime, site)\n }\n }\n}\n\nexport async function aggregateEvents(\n api: v2.RUMApi,\n params: {\n query?: string\n from?: string\n to?: string\n groupBy?: string[]\n compute?: {\n aggregation?: string\n metric?: string\n interval?: string\n }\n },\n _limits: LimitsConfig,\n site: string\n) {\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 60 * 60 * 1000 // Default 1 hour\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n // Build group by configurations\n const groupByConfigs: v2.RUMGroupBy[] = (params.groupBy ?? []).map((field) => ({\n facet: field,\n limit: 10,\n sort: {\n type: 'measure' as const,\n aggregation: 'count' as v2.RUMAggregationFunction,\n order: 'desc' as const\n }\n }))\n\n // Build compute configuration - only include defined properties\n // Note: 'type' should only be set when metric is present, otherwise API rejects it\n const computeConfig: v2.RUMCompute = {\n aggregation: (params.compute?.aggregation ?? 'count') as v2.RUMAggregationFunction\n }\n if (params.compute?.metric) {\n computeConfig.metric = params.compute.metric\n computeConfig.type = 'total'\n }\n if (params.compute?.interval) {\n computeConfig.interval = params.compute.interval\n computeConfig.type = 'timeseries'\n }\n const computeConfigs: v2.RUMCompute[] = [computeConfig]\n\n const queryString = params.query ?? '*'\n const response = await api.aggregateRUMEvents({\n body: {\n filter: {\n query: queryString,\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n groupBy: groupByConfigs.length > 0 ? groupByConfigs : undefined,\n compute: computeConfigs\n }\n })\n\n // Format buckets from response\n const buckets = (response.data?.buckets ?? []).map((bucket) => ({\n by: bucket.by ?? {},\n computes: bucket.computes ?? {}\n }))\n\n return {\n buckets,\n meta: {\n elapsed: response.meta?.elapsed ?? 0,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n datadog_url: buildRumUrl(queryString, fromTime, toTime, site)\n }\n }\n}\n\n// Core Web Vitals metric configurations\nconst METRIC_CONFIGS: Record<string, { field: string; aggregations: v2.RUMAggregationFunction[] }> =\n {\n lcp: {\n field: '@view.largest_contentful_paint',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n fcp: {\n field: '@view.first_contentful_paint',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n cls: {\n field: '@view.cumulative_layout_shift',\n aggregations: ['avg', 'pc75']\n },\n fid: {\n field: '@view.first_input_delay',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n inp: {\n field: '@view.interaction_to_next_paint',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n loading_time: {\n field: '@view.loading_time',\n aggregations: ['avg', 'pc75', 'pc90']\n }\n }\n\nexport async function getPerformanceMetrics(\n api: v2.RUMApi,\n params: {\n query?: string\n from?: string\n to?: string\n groupBy?: string[]\n metrics?: string[]\n },\n _limits: LimitsConfig,\n site: string\n) {\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 60 * 60 * 1000 // Default 1 hour\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n // Determine which metrics to query (default to 3 most important to stay under 10 computes limit)\n const requestedMetrics = params.metrics ?? ['lcp', 'fcp', 'cls']\n\n // Build compute configurations for all requested metrics\n const computeConfigs: v2.RUMCompute[] = []\n for (const metricName of requestedMetrics) {\n const config = METRIC_CONFIGS[metricName]\n if (!config) continue\n\n for (const aggregation of config.aggregations) {\n computeConfigs.push({\n aggregation,\n metric: config.field,\n type: 'total'\n })\n }\n }\n\n // Build group by configurations\n const groupByConfigs: v2.RUMGroupBy[] = (params.groupBy ?? []).map((field) => ({\n facet: field,\n limit: 10,\n sort: {\n type: 'measure' as const,\n aggregation: 'count' as v2.RUMAggregationFunction,\n order: 'desc' as const\n }\n }))\n\n // Query must filter to view events only\n const viewQuery = params.query ? `@type:view ${params.query}` : '@type:view'\n\n const response = await api.aggregateRUMEvents({\n body: {\n filter: {\n query: viewQuery,\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n groupBy: groupByConfigs.length > 0 ? groupByConfigs : undefined,\n compute: computeConfigs\n }\n })\n\n // Format response into structured metrics\n const buckets = (response.data?.buckets ?? []).map((bucket) => {\n const computes = (bucket.computes as Record<string, { value?: number }>) ?? {}\n const metrics: Record<string, Record<string, number | null>> = {}\n\n // Organize computes by metric name\n for (const metricName of requestedMetrics) {\n const config = METRIC_CONFIGS[metricName]\n if (!config) continue\n\n metrics[metricName] = {}\n for (const aggregation of config.aggregations) {\n // The key format in response is like \"c0\", \"c1\", etc. based on order\n // We need to find the matching compute by index\n const computeIndex = computeConfigs.findIndex(\n (c) => c.metric === config.field && c.aggregation === aggregation\n )\n const key = `c${computeIndex}`\n const value = computes[key]?.value\n metrics[metricName][String(aggregation)] = value ?? null\n }\n }\n\n return {\n by: bucket.by ?? {},\n metrics\n }\n })\n\n return {\n buckets,\n meta: {\n metrics: requestedMetrics,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n datadog_url: buildRumUrl(viewQuery, fromTime, toTime, site)\n }\n }\n}\n\ninterface WaterfallEvent {\n id: string\n type: string\n timestamp: string\n duration: number | null\n view: {\n id: string | null\n url: string | null\n name: string | null\n }\n resource?: {\n url: string | null\n type: string | null\n duration: number | null\n size: number | null\n statusCode: number | null\n }\n action?: {\n id: string | null\n type: string | null\n name: string | null\n target: string | null\n }\n error?: {\n message: string | null\n source: string | null\n type: string | null\n }\n longTask?: {\n duration: number | null\n }\n}\n\nexport function formatWaterfallEvent(event: v2.RUMEvent): WaterfallEvent {\n const attrs = event.attributes ?? {}\n const appAttrs = (attrs.attributes ?? {}) as Record<string, unknown>\n\n const view = (appAttrs['view'] ?? {}) as Record<string, unknown>\n const resource = (appAttrs['resource'] ?? {}) as Record<string, unknown>\n const action = (appAttrs['action'] ?? {}) as Record<string, unknown>\n const error = (appAttrs['error'] ?? {}) as Record<string, unknown>\n const longTask = (appAttrs['long_task'] ?? {}) as Record<string, unknown>\n\n // Event type is in nested attributes, not at top level\n const eventType = (appAttrs['type'] as string) ?? 'unknown'\n\n return {\n id: event.id ?? '',\n type: eventType,\n timestamp: attrs.timestamp?.toISOString() ?? '',\n duration: (view['loading_time'] as number) ?? (resource['duration'] as number) ?? null,\n view: {\n id: (view['id'] as string) ?? null,\n url: (view['url'] as string) ?? null,\n name: (view['name'] as string) ?? null\n },\n resource: resource['url']\n ? {\n url: (resource['url'] as string) ?? null,\n type: (resource['type'] as string) ?? null,\n duration: (resource['duration'] as number) ?? null,\n size: (resource['size'] as number) ?? null,\n statusCode: (resource['status_code'] as number) ?? null\n }\n : undefined,\n action: action['id']\n ? {\n id: (action['id'] as string) ?? null,\n type: (action['type'] as string) ?? null,\n name: (action['name'] as string) ?? null,\n target: (action['target'] as string) ?? null\n }\n : undefined,\n error: error['message']\n ? {\n message: (error['message'] as string) ?? null,\n source: (error['source'] as string) ?? null,\n type: (error['type'] as string) ?? null\n }\n : undefined,\n longTask: longTask['duration']\n ? {\n duration: (longTask['duration'] as number) ?? null\n }\n : undefined\n }\n}\n\nexport async function getSessionWaterfall(\n api: v2.RUMApi,\n params: {\n applicationId: string\n sessionId: string\n viewId?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n // Build query for specific session\n const queryParts = [`@application.id:${params.applicationId}`, `@session.id:${params.sessionId}`]\n if (params.viewId) {\n queryParts.push(`@view.id:${params.viewId}`)\n }\n\n const response = await api.listRUMEvents({\n filterQuery: queryParts.join(' '),\n sort: 'timestamp',\n pageLimit: Math.min(limits.maxResults, 1000)\n })\n\n const events = (response.data ?? []).map(formatWaterfallEvent)\n\n // Group events by type for summary\n const summary = {\n views: events.filter((e) => e.type === 'view').length,\n resources: events.filter((e) => e.type === 'resource').length,\n actions: events.filter((e) => e.type === 'action').length,\n errors: events.filter((e) => e.type === 'error').length,\n longTasks: events.filter((e) => e.type === 'long_task').length\n }\n\n return {\n events,\n summary,\n meta: {\n totalCount: events.length,\n applicationId: params.applicationId,\n sessionId: params.sessionId,\n viewId: params.viewId ?? null,\n datadog_url: buildRumSessionUrl(params.applicationId, params.sessionId, site)\n }\n }\n}\n\nexport function registerRumTool(\n server: McpServer,\n api: v2.RUMApi,\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'rum',\n 'Query Datadog Real User Monitoring (RUM) data. Actions: applications (list RUM apps), events (search RUM events), aggregate (group and count events), performance (Core Web Vitals: LCP, FCP, CLS, FID, INP), waterfall (session timeline with resources/actions/errors). Use for: frontend performance, user sessions, page views, errors, resource loading.',\n InputSchema,\n async ({\n action,\n query,\n from,\n to,\n type,\n sort,\n limit,\n groupBy,\n compute,\n metrics,\n applicationId,\n sessionId,\n viewId\n }) => {\n try {\n switch (action) {\n case 'applications':\n return toolResult(await listApplications(api))\n\n case 'events':\n return toolResult(\n await searchEvents(api, { query, from, to, type, sort, limit }, limits, site)\n )\n\n case 'aggregate':\n return toolResult(\n await aggregateEvents(api, { query, from, to, groupBy, compute }, limits, site)\n )\n\n case 'performance':\n return toolResult(\n await getPerformanceMetrics(api, { query, from, to, groupBy, metrics }, limits, site)\n )\n\n case 'waterfall':\n if (!applicationId || !sessionId) {\n throw new Error('waterfall action requires applicationId and sessionId parameters')\n }\n return toolResult(\n await getSessionWaterfall(api, { applicationId, sessionId, viewId }, limits, site)\n )\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime } from '../utils/time.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['rules', 'signals', 'findings'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Rule or signal ID (for specific lookups)'),\n query: z.string().optional().describe('Search query for signals or findings'),\n from: z.string().optional().describe('Start time (ISO 8601, relative like \"1h\", \"7d\")'),\n to: z.string().optional().describe('End time (ISO 8601, relative like \"now\")'),\n severity: z\n .enum(['info', 'low', 'medium', 'high', 'critical'])\n .optional()\n .describe('Filter by severity'),\n status: z\n .enum(['open', 'under_review', 'archived'])\n .optional()\n .describe('Filter signals by status'),\n pageSize: z.number().optional().describe('Number of results to return'),\n pageCursor: z.string().optional().describe('Cursor for pagination')\n}\n\ninterface SecurityRuleSummary {\n id: string\n name: string\n type: string\n isEnabled: boolean\n hasExtendedTitle: boolean\n message: string | null\n tags: string[]\n createdAt: string\n updatedAt: string\n creationAuthorId: number | null\n isDefault: boolean\n isDeleted: boolean\n filters: Array<{\n action: string\n query: string\n }>\n}\n\ninterface SecuritySignalSummary {\n id: string\n type: string\n timestamp: string\n attributes: {\n message: string | null\n status: string | null\n severity: string | null\n tags: string[]\n custom: Record<string, unknown>\n }\n}\n\nexport function formatRule(rule: v2.SecurityMonitoringRuleResponse): SecurityRuleSummary {\n // Handle union type - SecurityMonitoringRuleResponse can be various rule types\n const ruleData = rule as Record<string, unknown>\n\n return {\n id: (ruleData['id'] as string) ?? '',\n name: (ruleData['name'] as string) ?? '',\n type: (ruleData['type'] as string) ?? '',\n isEnabled: (ruleData['isEnabled'] as boolean) ?? false,\n hasExtendedTitle: (ruleData['hasExtendedTitle'] as boolean) ?? false,\n message: (ruleData['message'] as string) ?? null,\n tags: (ruleData['tags'] as string[]) ?? [],\n createdAt: ruleData['createdAt'] ? new Date(ruleData['createdAt'] as number).toISOString() : '',\n updatedAt: ruleData['updatedAt'] ? new Date(ruleData['updatedAt'] as number).toISOString() : '',\n creationAuthorId: (ruleData['creationAuthorId'] as number) ?? null,\n isDefault: (ruleData['isDefault'] as boolean) ?? false,\n isDeleted: (ruleData['isDeleted'] as boolean) ?? false,\n filters: ((ruleData['filters'] as Array<{ action: string; query: string }>) ?? []).map((f) => ({\n action: f.action ?? '',\n query: f.query ?? ''\n }))\n }\n}\n\nexport function formatSignal(signal: v2.SecurityMonitoringSignal): SecuritySignalSummary {\n const attrs = signal.attributes ?? {}\n // Custom attributes are in the additionalProperties\n const customAttrs = attrs as Record<string, unknown>\n\n return {\n id: signal.id ?? '',\n type: String(signal.type ?? ''),\n timestamp: attrs.timestamp?.toISOString() ?? '',\n attributes: {\n message: attrs.message ?? null,\n status: (customAttrs['status'] as string) ?? null,\n severity: (customAttrs['severity'] as string) ?? null,\n tags: attrs.tags ?? [],\n custom: attrs.custom ?? {}\n }\n }\n}\n\nexport async function listRules(\n api: v2.SecurityMonitoringApi,\n params: {\n pageSize?: number\n pageCursor?: string\n },\n limits: LimitsConfig\n) {\n const response = await api.listSecurityMonitoringRules({\n pageSize: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n pageNumber: 0\n })\n\n const rules = (response.data ?? []).map(formatRule)\n\n return {\n rules,\n meta: {\n totalCount: rules.length\n }\n }\n}\n\nexport async function getRule(api: v2.SecurityMonitoringApi, ruleId: string) {\n const response = await api.getSecurityMonitoringRule({ ruleId })\n\n return {\n rule: formatRule(response)\n }\n}\n\nexport async function searchSignals(\n api: v2.SecurityMonitoringApi,\n params: {\n query?: string\n from?: string\n to?: string\n severity?: string\n status?: string\n pageSize?: number\n pageCursor?: string\n },\n limits: LimitsConfig\n) {\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 24 * 60 * 60 * 1000 // Default 24 hours\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n // Build query with filters\n let queryString = params.query ?? '*'\n if (params.severity) {\n queryString = `severity:${params.severity} ${queryString}`.trim()\n }\n if (params.status) {\n queryString = `status:${params.status} ${queryString}`.trim()\n }\n\n const response = await api.searchSecurityMonitoringSignals({\n body: {\n filter: {\n query: queryString,\n from: new Date(fromTime * 1000),\n to: new Date(toTime * 1000)\n },\n page: {\n limit: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n cursor: params.pageCursor\n },\n sort: 'timestamp' as v2.SecurityMonitoringSignalsSort\n }\n })\n\n const signals = (response.data ?? []).map(formatSignal)\n\n return {\n signals,\n meta: {\n nextCursor: response.meta?.page?.after ?? null,\n totalCount: signals.length,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n }\n }\n }\n}\n\nexport async function listFindings(\n api: v2.SecurityMonitoringApi,\n params: {\n query?: string\n pageSize?: number\n pageCursor?: string\n },\n limits: LimitsConfig\n) {\n // Note: Findings API may require specific permissions\n // Using the signals search as a fallback for security findings\n const response = await api.searchSecurityMonitoringSignals({\n body: {\n filter: {\n query:\n params.query ??\n '@workflow.rule.type:workload_security OR @workflow.rule.type:cloud_configuration',\n from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last 7 days\n to: new Date()\n },\n page: {\n limit: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n cursor: params.pageCursor\n }\n }\n })\n\n const findings = (response.data ?? []).map(formatSignal)\n\n return {\n findings,\n meta: {\n nextCursor: response.meta?.page?.after ?? null,\n totalCount: findings.length\n }\n }\n}\n\nexport function registerSecurityTool(\n server: McpServer,\n api: v2.SecurityMonitoringApi,\n limits: LimitsConfig\n): void {\n server.tool(\n 'security',\n 'Query Datadog Security Monitoring. Actions: rules (list detection rules), signals (search security signals), findings (list security findings). Use for: threat detection, compliance, security posture, incident investigation.',\n InputSchema,\n async ({ action, id, query, from, to, severity, status, pageSize, pageCursor }) => {\n try {\n switch (action) {\n case 'rules':\n if (id) {\n return toolResult(await getRule(api, id))\n }\n return toolResult(await listRules(api, { pageSize, pageCursor }, limits))\n\n case 'signals':\n return toolResult(\n await searchSignals(\n api,\n { query, from, to, severity, status, pageSize, pageCursor },\n limits\n )\n )\n\n case 'findings':\n return toolResult(await listFindings(api, { query, pageSize, pageCursor }, limits))\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.number().optional().describe('Notebook ID (required for get/update/delete actions)'),\n query: z.string().optional().describe('Search query for notebooks'),\n authorHandle: z.string().optional().describe('Filter by author handle (email)'),\n excludeAuthorHandle: z.string().optional().describe('Exclude notebooks by author handle'),\n includeCells: z\n .boolean()\n .optional()\n .describe('Include cell content in response (default: true for get)'),\n name: z.string().optional().describe('Notebook name (for create/update)'),\n cells: z\n .array(\n z.object({\n type: z.enum([\n 'markdown',\n 'timeseries',\n 'toplist',\n 'heatmap',\n 'distribution',\n 'log_stream'\n ]),\n content: z.unknown()\n })\n )\n .optional()\n .describe('Notebook cells (for create/update)'),\n time: z\n .object({\n liveSpan: z.string().optional(),\n start: z.number().optional(),\n end: z.number().optional()\n })\n .optional()\n .describe('Time configuration for notebook'),\n status: z.enum(['published']).optional().describe('Notebook status'),\n pageSize: z.number().optional().describe('Number of notebooks to return'),\n pageNumber: z.number().optional().describe('Page number for pagination')\n}\n\ninterface NotebookSummary {\n id: number\n name: string\n author: {\n handle: string | null\n name: string | null\n }\n status: string\n cellCount: number\n created: string\n modified: string\n metadata: {\n isTemplate: boolean | null\n takeSnapshots: boolean | null\n }\n}\n\ninterface NotebookDetail extends NotebookSummary {\n cells: Array<{\n id: string\n type: string\n attributes: unknown\n }>\n time: {\n liveSpan: string | null\n }\n}\n\nexport function formatNotebookSummary(nb: v1.NotebooksResponseData): NotebookSummary {\n const attrs = nb.attributes ?? {}\n\n return {\n id: nb.id ?? 0,\n name: attrs.name ?? '',\n author: {\n handle: attrs.author?.handle ?? null,\n name: attrs.author?.name ?? null\n },\n status: String(attrs.status ?? ''),\n cellCount: attrs.cells?.length ?? 0,\n created: attrs.created?.toISOString() ?? '',\n modified: attrs.modified?.toISOString() ?? '',\n metadata: {\n isTemplate: attrs.metadata?.isTemplate ?? null,\n takeSnapshots: attrs.metadata?.takeSnapshots ?? null\n }\n }\n}\n\nexport function formatNotebookDetail(nb: v1.NotebookResponseData): NotebookDetail {\n const attrs = nb.attributes ?? {}\n\n return {\n id: nb.id ?? 0,\n name: attrs.name ?? '',\n author: {\n handle: attrs.author?.handle ?? null,\n name: attrs.author?.name ?? null\n },\n status: String(attrs.status ?? ''),\n cellCount: attrs.cells?.length ?? 0,\n created: attrs.created?.toISOString() ?? '',\n modified: attrs.modified?.toISOString() ?? '',\n metadata: {\n isTemplate: attrs.metadata?.isTemplate ?? null,\n takeSnapshots: attrs.metadata?.takeSnapshots ?? null\n },\n cells: (attrs.cells ?? []).map((cell) => ({\n id: String(cell.id ?? ''),\n type: String(cell.type ?? ''),\n attributes: cell.attributes ?? {}\n })),\n time: {\n liveSpan: attrs.time\n ? String((attrs.time as unknown as Record<string, unknown>)['liveSpan'] ?? '')\n : null\n }\n }\n}\n\nexport async function listNotebooks(\n api: v1.NotebooksApi,\n params: {\n query?: string\n authorHandle?: string\n excludeAuthorHandle?: string\n includeCells?: boolean\n pageSize?: number\n pageNumber?: number\n },\n limits: LimitsConfig\n) {\n const response = await api.listNotebooks({\n query: params.query,\n authorHandle: params.authorHandle,\n excludeAuthorHandle: params.excludeAuthorHandle,\n includeCells: params.includeCells ?? false,\n count: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n start: (params.pageNumber ?? 0) * (params.pageSize ?? limits.maxResults)\n })\n\n const notebooks = (response.data ?? []).map(formatNotebookSummary)\n\n return {\n notebooks,\n meta: {\n totalCount: response.meta?.page?.totalCount ?? notebooks.length,\n totalFilteredCount: response.meta?.page?.totalFilteredCount ?? notebooks.length\n }\n }\n}\n\nexport async function getNotebook(api: v1.NotebooksApi, notebookId: number) {\n const response = await api.getNotebook({ notebookId })\n\n if (!response.data) {\n throw new Error(`Notebook ${notebookId} not found`)\n }\n\n return {\n notebook: formatNotebookDetail(response.data)\n }\n}\n\nexport async function createNotebook(\n api: v1.NotebooksApi,\n params: {\n name: string\n cells?: Array<{ type: string; content: unknown }>\n time?: { liveSpan?: string; start?: number; end?: number }\n status?: string\n }\n) {\n // Build cells for the notebook\n const cells: v1.NotebookCellCreateRequest[] = (params.cells ?? []).map((cell) => {\n // Default to markdown cell if no specific type handling\n if (cell.type === 'markdown') {\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: {\n type: 'markdown' as const,\n text: String(cell.content ?? '')\n }\n } as v1.NotebookCellCreateRequestAttributes\n }\n }\n // For other cell types, pass through the content as definition\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: cell.content\n } as v1.NotebookCellCreateRequestAttributes\n }\n })\n\n // If no cells provided, create a default markdown cell\n if (cells.length === 0) {\n cells.push({\n type: 'notebook_cells' as const,\n attributes: {\n definition: {\n type: 'markdown' as const,\n text: '# New Notebook\\n\\nStart adding content here.'\n }\n } as v1.NotebookCellCreateRequestAttributes\n })\n }\n\n // Build time configuration - use type assertion for union type\n const timeConfig = (\n params.time?.liveSpan\n ? { liveSpan: params.time.liveSpan as v1.NotebookRelativeTime['liveSpan'] }\n : { liveSpan: '1h' as v1.NotebookRelativeTime['liveSpan'] }\n ) as v1.NotebookGlobalTime\n\n const response = await api.createNotebook({\n body: {\n data: {\n type: 'notebooks',\n attributes: {\n name: params.name,\n cells,\n time: timeConfig,\n status: (params.status as v1.NotebookStatus) ?? 'published'\n }\n }\n }\n })\n\n if (!response.data) {\n throw new Error('Failed to create notebook')\n }\n\n return {\n success: true,\n notebook: formatNotebookDetail(response.data),\n message: `Notebook \"${params.name}\" created successfully`\n }\n}\n\nexport async function updateNotebook(\n api: v1.NotebooksApi,\n notebookId: number,\n params: {\n name?: string\n cells?: Array<{ type: string; content: unknown }>\n time?: { liveSpan?: string; start?: number; end?: number }\n status?: string\n }\n) {\n // First get the existing notebook to preserve fields\n const existing = await api.getNotebook({ notebookId })\n if (!existing.data) {\n throw new Error(`Notebook ${notebookId} not found`)\n }\n\n const existingAttrs = existing.data.attributes ?? {}\n\n // Build cells if provided\n let cells: v1.NotebookUpdateCell[] | undefined\n if (params.cells) {\n cells = params.cells.map((cell) => {\n if (cell.type === 'markdown') {\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: {\n type: 'markdown' as const,\n text: String(cell.content ?? '')\n }\n } as v1.NotebookCellUpdateRequestAttributes\n }\n }\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: cell.content\n } as v1.NotebookCellUpdateRequestAttributes\n }\n })\n }\n\n // Build time configuration - use type assertion for union type\n const timeConfig: v1.NotebookGlobalTime | undefined = params.time?.liveSpan\n ? ({\n liveSpan: params.time.liveSpan as v1.NotebookRelativeTime['liveSpan']\n } as v1.NotebookGlobalTime)\n : undefined\n\n const response = await api.updateNotebook({\n notebookId,\n body: {\n data: {\n type: 'notebooks',\n attributes: {\n name: params.name ?? existingAttrs.name ?? '',\n cells:\n cells ??\n existingAttrs.cells?.map((c) => ({\n id: c.id,\n type: 'notebook_cells' as const,\n attributes: c.attributes as v1.NotebookCellUpdateRequestAttributes\n })) ??\n [],\n time: timeConfig ?? existingAttrs.time ?? { liveSpan: '1h' as const },\n status: (params.status ?? existingAttrs.status) as v1.NotebookStatus\n }\n }\n }\n })\n\n if (!response.data) {\n throw new Error('Failed to update notebook')\n }\n\n return {\n success: true,\n notebook: formatNotebookDetail(response.data),\n message: `Notebook ${notebookId} updated successfully`\n }\n}\n\nexport async function deleteNotebook(api: v1.NotebooksApi, notebookId: number) {\n await api.deleteNotebook({ notebookId })\n\n return {\n success: true,\n message: `Notebook ${notebookId} deleted successfully`\n }\n}\n\nexport function registerNotebooksTool(\n server: McpServer,\n api: v1.NotebooksApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'notebooks',\n 'Manage Datadog Notebooks. Actions: list (search notebooks), get (by ID with cells), create (new notebook), update (modify notebook), delete (remove notebook). Use for: runbooks, incident documentation, investigation notes, dashboards as code.',\n InputSchema,\n async ({\n action,\n id,\n query,\n authorHandle,\n excludeAuthorHandle,\n includeCells,\n name,\n cells,\n time,\n status,\n pageSize,\n pageNumber\n }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listNotebooks(\n api,\n { query, authorHandle, excludeAuthorHandle, includeCells, pageSize, pageNumber },\n limits\n )\n )\n\n case 'get': {\n const notebookId = requireParam(id, 'id', 'get')\n return toolResult(await getNotebook(api, notebookId))\n }\n\n case 'create': {\n const notebookName = requireParam(name, 'name', 'create')\n return toolResult(\n await createNotebook(api, {\n name: notebookName,\n cells: cells as Array<{ type: string; content: unknown }>,\n time,\n status\n })\n )\n }\n\n case 'update': {\n const notebookId = requireParam(id, 'id', 'update')\n return toolResult(\n await updateNotebook(api, notebookId, {\n name,\n cells: cells as Array<{ type: string; content: unknown }>,\n time,\n status\n })\n )\n }\n\n case 'delete': {\n const notebookId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteNotebook(api, notebookId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('User ID (required for get action)'),\n filter: z.string().optional().describe('Filter users by name or email'),\n status: z.enum(['Active', 'Pending', 'Disabled']).optional().describe('Filter by user status'),\n pageSize: z.number().optional().describe('Number of users to return per page'),\n pageNumber: z.number().optional().describe('Page number for pagination')\n}\n\ninterface UserSummary {\n id: string\n email: string\n name: string\n status: string\n title: string | null\n verified: boolean\n disabled: boolean\n createdAt: string\n modifiedAt: string\n relationships: {\n roles: string[]\n org: string | null\n }\n}\n\nexport function formatUser(user: v2.User): UserSummary {\n const attrs = user.attributes ?? {}\n const relationships = user.relationships ?? {}\n\n // Extract role names from relationships\n const roles = (relationships.roles?.data ?? []).map((r) => r.id ?? '')\n const orgId = relationships.org?.data?.id ?? null\n\n return {\n id: user.id ?? '',\n email: attrs.email ?? '',\n name: attrs.name ?? '',\n status: attrs.status ?? '',\n title: attrs.title ?? null,\n verified: attrs.verified ?? false,\n disabled: attrs.disabled ?? false,\n createdAt: attrs.createdAt?.toISOString() ?? '',\n modifiedAt: attrs.modifiedAt?.toISOString() ?? '',\n relationships: {\n roles,\n org: orgId\n }\n }\n}\n\nexport async function listUsers(\n api: v2.UsersApi,\n params: {\n filter?: string\n status?: string\n pageSize?: number\n pageNumber?: number\n },\n limits: LimitsConfig\n) {\n const response = await api.listUsers({\n filter: params.filter,\n filterStatus: params.status,\n pageSize: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n pageNumber: params.pageNumber ?? 0\n })\n\n const users = (response.data ?? []).map(formatUser)\n\n return {\n users,\n meta: {\n page: response.meta?.page ?? {},\n totalCount: users.length\n }\n }\n}\n\nexport async function getUser(api: v2.UsersApi, userId: string) {\n const response = await api.getUser({ userId })\n\n if (!response.data) {\n throw new Error(`User ${userId} not found`)\n }\n\n return {\n user: formatUser(response.data)\n }\n}\n\nexport function registerUsersTool(server: McpServer, api: v2.UsersApi, limits: LimitsConfig): void {\n server.tool(\n 'users',\n 'Manage Datadog users. Actions: list (with filters), get (by ID). Use for: access management, user auditing, team organization.',\n InputSchema,\n async ({ action, id, filter, status, pageSize, pageNumber }) => {\n try {\n switch (action) {\n case 'list':\n return toolResult(\n await listUsers(api, { filter, status, pageSize, pageNumber }, limits)\n )\n\n case 'get': {\n const userId = requireParam(id, 'id', 'get')\n return toolResult(await getUser(api, userId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'members'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Team ID (required for get/members actions)'),\n filter: z.string().optional().describe('Filter teams by name'),\n pageSize: z.number().optional().describe('Number of teams to return per page'),\n pageNumber: z.number().optional().describe('Page number for pagination')\n}\n\ninterface TeamSummary {\n id: string\n name: string\n handle: string\n description: string | null\n summary: string | null\n linkCount: number\n userCount: number\n createdAt: string\n modifiedAt: string\n}\n\ninterface TeamMemberSummary {\n id: string\n type: string\n attributes: {\n role: string\n }\n relationships: {\n userId: string | null\n }\n}\n\nexport function formatTeam(team: v2.Team): TeamSummary {\n const attrs = team.attributes ?? {}\n\n return {\n id: team.id ?? '',\n name: attrs.name ?? '',\n handle: attrs.handle ?? '',\n description: attrs.description ?? null,\n summary: attrs.summary ?? null,\n linkCount: attrs.linkCount ?? 0,\n userCount: attrs.userCount ?? 0,\n createdAt: attrs.createdAt?.toISOString() ?? '',\n modifiedAt: attrs.modifiedAt?.toISOString() ?? ''\n }\n}\n\nexport function formatTeamMember(member: v2.UserTeam): TeamMemberSummary {\n const attrs = member.attributes ?? {}\n const relationships = member.relationships ?? {}\n\n return {\n id: member.id ?? '',\n type: String(member.type ?? ''),\n attributes: {\n role: String(attrs.role ?? '')\n },\n relationships: {\n userId: relationships.user?.data?.id ?? null\n }\n }\n}\n\nexport async function listTeams(\n api: v2.TeamsApi,\n params: {\n filter?: string\n pageSize?: number\n pageNumber?: number\n },\n limits: LimitsConfig\n) {\n const response = await api.listTeams({\n filterKeyword: params.filter,\n pageSize: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n pageNumber: params.pageNumber ?? 0\n })\n\n const teams = (response.data ?? []).map(formatTeam)\n\n return {\n teams,\n meta: {\n totalCount: teams.length\n }\n }\n}\n\nexport async function getTeam(api: v2.TeamsApi, teamId: string) {\n const response = await api.getTeam({ teamId })\n\n if (!response.data) {\n throw new Error(`Team ${teamId} not found`)\n }\n\n return {\n team: formatTeam(response.data)\n }\n}\n\nexport async function getTeamMembers(api: v2.TeamsApi, teamId: string, limits: LimitsConfig) {\n const response = await api.getTeamMemberships({\n teamId,\n pageSize: limits.maxResults\n })\n\n const members = (response.data ?? []).map(formatTeamMember)\n\n return {\n members,\n meta: {\n totalCount: members.length\n }\n }\n}\n\nexport function registerTeamsTool(server: McpServer, api: v2.TeamsApi, limits: LimitsConfig): void {\n server.tool(\n 'teams',\n 'Manage Datadog teams. Actions: list (with filters), get (by ID), members (list team members). Use for: team organization, access management, collaboration.',\n InputSchema,\n async ({ action, id, filter, pageSize, pageNumber }) => {\n try {\n switch (action) {\n case 'list':\n return toolResult(await listTeams(api, { filter, pageSize, pageNumber }, limits))\n\n case 'get': {\n const teamId = requireParam(id, 'id', 'get')\n return toolResult(await getTeam(api, teamId))\n }\n\n case 'members': {\n const teamId = requireParam(id, 'id', 'members')\n return toolResult(await getTeamMembers(api, teamId, limits))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'add', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n hostName: z\n .string()\n .optional()\n .describe('Host name (required for get/add/update/delete actions)'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags to add or set (for add/update actions). Format: \"key:value\"'),\n source: z\n .string()\n .optional()\n .describe('Source of the tags (e.g., \"users\", \"datadog\"). Defaults to \"users\"')\n}\n\ninterface HostTagsSummary {\n hostName: string\n tags: string[]\n source: string | null\n}\n\ninterface AllTagsSummary {\n hosts: { [key: string]: string[] }\n totalHosts: number\n}\n\nexport async function listAllTags(api: v1.TagsApi, source?: string): Promise<AllTagsSummary> {\n const response = await api.listHostTags({\n source\n })\n\n const tags = response.tags ?? {}\n\n return {\n hosts: tags,\n totalHosts: Object.keys(tags).length\n }\n}\n\nexport async function getHostTags(\n api: v1.TagsApi,\n hostName: string,\n source?: string\n): Promise<HostTagsSummary> {\n const response = await api.getHostTags({\n hostName,\n source\n })\n\n return {\n hostName,\n tags: response.tags ?? [],\n source: source ?? null\n }\n}\n\nexport async function addHostTags(\n api: v1.TagsApi,\n hostName: string,\n tags: string[],\n source?: string\n) {\n const response = await api.createHostTags({\n hostName,\n body: {\n host: hostName,\n tags\n },\n source\n })\n\n return {\n success: true,\n hostName,\n tags: response.tags ?? tags,\n message: `Tags added to host ${hostName}`\n }\n}\n\nexport async function updateHostTags(\n api: v1.TagsApi,\n hostName: string,\n tags: string[],\n source?: string\n) {\n const response = await api.updateHostTags({\n hostName,\n body: {\n host: hostName,\n tags\n },\n source\n })\n\n return {\n success: true,\n hostName,\n tags: response.tags ?? tags,\n message: `Tags updated for host ${hostName}`\n }\n}\n\nexport async function deleteHostTags(api: v1.TagsApi, hostName: string, source?: string) {\n await api.deleteHostTags({\n hostName,\n source\n })\n\n return {\n success: true,\n hostName,\n message: `Tags deleted from host ${hostName}`\n }\n}\n\nexport function registerTagsTool(\n server: McpServer,\n api: v1.TagsApi,\n _limits: LimitsConfig,\n readOnly: boolean = false\n): void {\n server.tool(\n 'tags',\n 'Manage Datadog host tags. Actions: list (all host tags), get (tags for specific host), add (create tags), update (replace tags), delete (remove all tags). Use for: infrastructure organization, filtering, grouping.',\n InputSchema,\n async ({ action, hostName, tags, source }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listAllTags(api, source))\n\n case 'get': {\n const host = requireParam(hostName, 'hostName', 'get')\n return toolResult(await getHostTags(api, host, source))\n }\n\n case 'add': {\n const host = requireParam(hostName, 'hostName', 'add')\n const tagList = requireParam(tags, 'tags', 'add')\n return toolResult(await addHostTags(api, host, tagList, source))\n }\n\n case 'update': {\n const host = requireParam(hostName, 'hostName', 'update')\n const tagList = requireParam(tags, 'tags', 'update')\n return toolResult(await updateHostTags(api, host, tagList, source))\n }\n\n case 'delete': {\n const host = requireParam(hostName, 'hostName', 'delete')\n return toolResult(await deleteHostTags(api, host, source))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime } from '../utils/time.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum([\n 'summary',\n 'hosts',\n 'logs',\n 'custom_metrics',\n 'indexed_spans',\n 'ingested_spans'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe(\n 'Action to perform: summary (overall usage), hosts, logs, custom_metrics, indexed_spans, ingested_spans'\n ),\n from: z\n .string()\n .optional()\n .describe('Start time (ISO 8601 date like \"2024-01-01\", or relative like \"30d\")'),\n to: z\n .string()\n .optional()\n .describe('End time (ISO 8601 date like \"2024-01-31\", or relative like \"now\")'),\n includeOrgDetails: z\n .boolean()\n .optional()\n .describe('Include usage breakdown by organization (for multi-org accounts)')\n}\n\ninterface UsageSummary {\n startDate: string\n endDate: string\n aggsTotal: Record<string, number | null>\n usage: Array<{\n date: string\n orgName: string | null\n apmHostTop99pSum: number | null\n infraHostTop99pSum: number | null\n logsIndexedLogsUsageSum: number | null\n ingestedEventsBytesSum: number | null\n customMetricsAvgPerHour: number | null\n }>\n}\n\ninterface HostUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n agentHostTop99p: number | null\n awsHostTop99p: number | null\n azureHostTop99p: number | null\n gcpHostTop99p: number | null\n infraHostTop99p: number | null\n containerTop99p: number | null\n }>\n}\n\ninterface LogsUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n logsIndexedLogsUsageSum: number | null\n logsLiveIndexedLogsUsageSum: number | null\n logsRehydratedIndexedLogsUsageSum: number | null\n }>\n}\n\ninterface CustomMetricsUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n avgMetricsCount: number | null\n maxMetricsCount: number | null\n }>\n}\n\ninterface SpansUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n indexedSpansCount: number | null\n ingestedSpansBytes: number | null\n }>\n}\n\nexport function parseDate(dateStr: string | undefined, defaultDate: Date): Date {\n if (!dateStr) return defaultDate\n\n // Check if it's a relative date\n if (dateStr.match(/^\\d+[hdwmy]$/)) {\n const seconds = parseTime(dateStr, Math.floor(Date.now() / 1000))\n return new Date(seconds * 1000)\n }\n\n // Try ISO date parsing\n const parsed = new Date(dateStr)\n if (!Number.isNaN(parsed.getTime())) {\n return parsed\n }\n\n return defaultDate\n}\n\nexport async function getUsageSummary(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n includeOrgDetails?: boolean\n }\n): Promise<UsageSummary> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageSummary({\n startMonth: startDate,\n endMonth: endDate,\n includeOrgDetails: params.includeOrgDetails\n })\n\n return {\n startDate: response.startDate?.toISOString() ?? startDate.toISOString(),\n endDate: response.endDate?.toISOString() ?? endDate.toISOString(),\n aggsTotal: {\n apmHostTop99p: response.apmHostTop99PSum ?? null,\n infraHostTop99p: response.infraHostTop99PSum ?? null\n },\n usage: (response.usage ?? []).map((u) => ({\n date: u.date?.toISOString() ?? '',\n orgName: ((u as Record<string, unknown>)['orgName'] as string) ?? null,\n apmHostTop99pSum: u.apmHostTop99P ?? null,\n infraHostTop99pSum: u.infraHostTop99P ?? null,\n logsIndexedLogsUsageSum: u.indexedEventsCountSum ?? null,\n ingestedEventsBytesSum: u.ingestedEventsBytesSum ?? null,\n customMetricsAvgPerHour: null // Not in summary\n }))\n }\n}\n\nexport async function getHostsUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<HostUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageHosts({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n agentHostTop99p: u.agentHostCount ?? null,\n awsHostTop99p: u.awsHostCount ?? null,\n azureHostTop99p: u.azureHostCount ?? null,\n gcpHostTop99p: u.gcpHostCount ?? null,\n infraHostTop99p: u.hostCount ?? null,\n containerTop99p: u.containerCount ?? null\n }))\n }\n}\n\nexport async function getLogsUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<LogsUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageLogs({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n logsIndexedLogsUsageSum: u.indexedEventsCount ?? null,\n logsLiveIndexedLogsUsageSum: u.indexedEventsCount ?? null,\n logsRehydratedIndexedLogsUsageSum:\n ((u as Record<string, unknown>)['logsRehydratedIndexedCount'] as number) ?? null\n }))\n }\n}\n\nexport async function getCustomMetricsUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<CustomMetricsUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageTimeseries({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n avgMetricsCount: u.numCustomTimeseries ?? null,\n maxMetricsCount: null // Not directly available\n }))\n }\n}\n\nexport async function getIndexedSpansUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<SpansUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageIndexedSpans({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n indexedSpansCount: u.indexedEventsCount ?? null,\n ingestedSpansBytes: null\n }))\n }\n}\n\nexport async function getIngestedSpansUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<SpansUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getIngestedSpans({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n indexedSpansCount: null,\n ingestedSpansBytes: ((u as Record<string, unknown>)['ingestedTracesBytes'] as number) ?? null\n }))\n }\n}\n\nexport function registerUsageTool(\n server: McpServer,\n api: v1.UsageMeteringApi,\n _limits: LimitsConfig\n): void {\n server.tool(\n 'usage',\n 'Query Datadog usage metering data. Actions: summary (overall usage), hosts (infrastructure), logs, custom_metrics, indexed_spans, ingested_spans. Use for: cost management, capacity planning, usage tracking, billing analysis.',\n InputSchema,\n async ({ action, from, to, includeOrgDetails }) => {\n try {\n switch (action) {\n case 'summary':\n return toolResult(await getUsageSummary(api, { from, to, includeOrgDetails }))\n\n case 'hosts':\n return toolResult(await getHostsUsage(api, { from, to }))\n\n case 'logs':\n return toolResult(await getLogsUsage(api, { from, to }))\n\n case 'custom_metrics':\n return toolResult(await getCustomMetricsUsage(api, { from, to }))\n\n case 'indexed_spans':\n return toolResult(await getIndexedSpansUsage(api, { from, to }))\n\n case 'ingested_spans':\n return toolResult(await getIngestedSpansUsage(api, { from, to }))\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","/**\n * Authentication tool for validating Datadog API credentials\n */\nimport { z } from 'zod'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { DatadogClients } from '../config/datadog.js'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\n\nconst ActionSchema = z.enum(['validate'])\n\nconst InputSchema = {\n action: ActionSchema.describe(\n 'Action to perform: validate - test if API key and App key are valid'\n )\n}\n\nexport function registerAuthTool(server: McpServer, clients: DatadogClients): void {\n server.tool(\n 'auth',\n 'Validate Datadog API credentials. Use this to verify that the API key and App key are correctly configured before performing other operations.',\n InputSchema,\n async ({ action }) => {\n try {\n switch (action) {\n case 'validate':\n return toolResult(await validateCredentials(clients))\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n\nexport async function validateCredentials(clients: DatadogClients) {\n // Step 1: Validate API key using the official Authentication API\n const apiKeyResult = await clients.auth.validate()\n\n if (!apiKeyResult.valid) {\n return {\n valid: false,\n apiKeyValid: false,\n appKeyValid: false,\n error: 'API key is invalid',\n suggestion: 'Check that your DD_API_KEY environment variable is correct'\n }\n }\n\n // Step 2: Validate App key by making a lightweight API call that requires it\n // The Authentication API only validates API key, so we need to test App key separately\n try {\n // Use a minimal call - list users with page size 1 requires both keys\n await clients.users.listUsers({ pageSize: 1 })\n\n return {\n valid: true,\n apiKeyValid: true,\n appKeyValid: true,\n message: 'Both API key and App key are valid and working',\n permissions: 'Credentials have sufficient permissions to access the Datadog API'\n }\n } catch (appKeyError) {\n // API key is valid but App key might be invalid or have insufficient permissions\n const errorMessage = appKeyError instanceof Error ? appKeyError.message : String(appKeyError)\n\n // Check if it's an auth error or just a permission issue\n const isAuthError =\n errorMessage.includes('401') ||\n errorMessage.includes('403') ||\n errorMessage.includes('Forbidden')\n\n return {\n valid: !isAuthError,\n apiKeyValid: true,\n appKeyValid: !isAuthError,\n warning: isAuthError\n ? 'App key may be invalid or have insufficient permissions'\n : 'API key is valid. App key validation inconclusive.',\n error: errorMessage,\n suggestion: isAuthError\n ? 'Check that your DD_APP_KEY environment variable is correct and has appropriate scopes'\n : 'Credentials appear valid but encountered an issue during validation'\n }\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { DatadogClients } from '../config/datadog.js'\nimport type { LimitsConfig, FeaturesConfig } from '../config/schema.js'\n\nimport { registerMonitorsTool } from './monitors.js'\nimport { registerDashboardsTool } from './dashboards.js'\nimport { registerLogsTool } from './logs.js'\nimport { registerMetricsTool } from './metrics.js'\nimport { registerTracesTool } from './traces.js'\nimport { registerEventsTool } from './events.js'\nimport { registerIncidentsTool } from './incidents.js'\nimport { registerSlosTool } from './slos.js'\nimport { registerSyntheticsTool } from './synthetics.js'\nimport { registerHostsTool } from './hosts.js'\nimport { registerDowntimesTool } from './downtimes.js'\nimport { registerRumTool } from './rum.js'\nimport { registerSecurityTool } from './security.js'\nimport { registerNotebooksTool } from './notebooks.js'\nimport { registerUsersTool } from './users.js'\nimport { registerTeamsTool } from './teams.js'\nimport { registerTagsTool } from './tags.js'\nimport { registerUsageTool } from './usage.js'\nimport { registerAuthTool } from './auth.js'\n\nexport function registerAllTools(\n server: McpServer,\n clients: DatadogClients,\n limits: LimitsConfig,\n features: FeaturesConfig,\n site: string = 'datadoghq.com'\n): void {\n const { readOnly, disabledTools } = features\n const enabled = (tool: string) => !disabledTools.includes(tool)\n\n if (enabled('monitors')) registerMonitorsTool(server, clients.monitors, limits, readOnly, site)\n if (enabled('dashboards'))\n registerDashboardsTool(server, clients.dashboards, limits, readOnly, site)\n if (enabled('logs')) registerLogsTool(server, clients.logs, limits, site)\n if (enabled('metrics'))\n registerMetricsTool(server, clients.metricsV1, clients.metricsV2, limits, site)\n if (enabled('traces')) registerTracesTool(server, clients.spans, clients.services, limits, site)\n if (enabled('events'))\n registerEventsTool(\n server,\n clients.eventsV1,\n clients.eventsV2,\n clients.monitors,\n limits,\n readOnly,\n site\n )\n if (enabled('incidents')) registerIncidentsTool(server, clients.incidents, limits, readOnly, site)\n if (enabled('slos')) registerSlosTool(server, clients.slo, limits, readOnly, site)\n if (enabled('synthetics'))\n registerSyntheticsTool(server, clients.synthetics, limits, readOnly, site)\n if (enabled('hosts')) registerHostsTool(server, clients.hosts, limits, readOnly)\n if (enabled('downtimes')) registerDowntimesTool(server, clients.downtimes, limits, readOnly)\n if (enabled('rum')) registerRumTool(server, clients.rum, limits, site)\n if (enabled('security')) registerSecurityTool(server, clients.security, limits)\n if (enabled('notebooks')) registerNotebooksTool(server, clients.notebooks, limits, readOnly, site)\n if (enabled('users')) registerUsersTool(server, clients.users, limits)\n if (enabled('teams')) registerTeamsTool(server, clients.teams, limits)\n if (enabled('tags')) registerTagsTool(server, clients.tags, limits, readOnly)\n if (enabled('usage')) registerUsageTool(server, clients.usage, limits)\n if (enabled('auth')) registerAuthTool(server, clients)\n}\n","import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport async function connectStdio(server: McpServer): Promise<void> {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n console.error('[MCP] Datadog MCP server running on stdio')\n}\n","/**\n * HTTP/StreamableHTTP transport for MCP server\n * Allows running the server over HTTP with configurable port\n */\nimport express, { Request, Response } from 'express'\nimport { randomUUID } from 'node:crypto'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport type { ServerConfig } from '../config/schema.js'\n\n// Store active transports by session ID\nconst transports: Record<string, StreamableHTTPServerTransport> = {}\n\n/**\n * Creates and configures an Express app for MCP server\n * Exported for testing purposes\n */\nexport function createExpressApp(server: McpServer, config: ServerConfig): express.Application {\n const app = express()\n app.disable('x-powered-by')\n app.use(express.json())\n\n // Health check endpoint\n app.get('/health', (_req: Request, res: Response) => {\n res.json({ status: 'ok', name: config.name, version: config.version })\n })\n\n // MCP endpoint - handles POST, GET, DELETE\n app.post('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n let transport: StreamableHTTPServerTransport\n\n if (sessionId && transports[sessionId]) {\n // Reuse existing session\n transport = transports[sessionId]\n } else if (!sessionId && isInitializeRequest(req.body)) {\n // New session initialization\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n transports[id] = transport\n console.error(`[MCP] Session initialized: ${id}`)\n }\n })\n\n transport.onclose = () => {\n if (transport.sessionId) {\n delete transports[transport.sessionId]\n console.error(`[MCP] Session closed: ${transport.sessionId}`)\n }\n }\n\n await server.connect(transport)\n } else {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32000, message: 'Invalid session' },\n id: null\n })\n return\n }\n\n await transport.handleRequest(req, res, req.body)\n })\n\n app.get('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string\n const transport = transports[sessionId]\n if (transport) {\n await transport.handleRequest(req, res)\n } else {\n res.status(400).json({ error: 'Invalid session' })\n }\n })\n\n app.delete('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string\n const transport = transports[sessionId]\n if (transport) {\n await transport.handleRequest(req, res)\n } else {\n res.status(400).json({ error: 'Invalid session' })\n }\n })\n\n return app\n}\n\nexport async function connectHttp(server: McpServer, config: ServerConfig): Promise<void> {\n const app = createExpressApp(server, config)\n\n // Start server\n app.listen(config.port, config.host, () => {\n console.error(`[MCP] Datadog MCP server running on http://${config.host}:${config.port}/mcp`)\n console.error(`[MCP] Health check available at http://${config.host}:${config.port}/health`)\n })\n}\n","import { loadConfig } from './config/index.js'\nimport { createServer } from './server.js'\nimport { connectStdio, connectHttp } from './transport/index.js'\n\ntry {\n const config = loadConfig()\n const server = createServer(config)\n\n if (config.server.transport === 'http') {\n await connectHttp(server, config.server)\n } else {\n await connectStdio(server)\n }\n} catch (error) {\n console.error('[MCP] Failed to start server:', error)\n process.exit(1)\n}\n"],"mappings":"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","names":["z","z","z","ActionSchema","z","InputSchema","z","date","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","snakeToCamel","normalizeConfigKeys","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema"]}
1
+ {"version":3,"sources":["../src/config/schema.ts","../src/config/index.ts","../src/server.ts","../src/config/datadog.ts","../src/tools/monitors.ts","../src/errors/datadog.ts","../src/utils/format.ts","../src/utils/urls.ts","../src/tools/dashboards.ts","../src/tools/logs.ts","../src/utils/time.ts","../src/tools/metrics.ts","../src/tools/traces.ts","../src/tools/events.ts","../src/tools/incidents.ts","../src/tools/slos.ts","../src/tools/synthetics.ts","../src/tools/hosts.ts","../src/tools/downtimes.ts","../src/tools/rum.ts","../src/tools/security.ts","../src/tools/notebooks.ts","../src/tools/users.ts","../src/tools/teams.ts","../src/tools/tags.ts","../src/tools/usage.ts","../src/tools/auth.ts","../src/tools/index.ts","../src/transport/stdio.ts","../src/transport/http.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod'\n\n// All available tool names\nexport const ALL_TOOLS = [\n 'monitors',\n 'dashboards',\n 'logs',\n 'metrics',\n 'traces',\n 'events',\n 'incidents',\n 'slos',\n 'synthetics',\n 'hosts',\n 'downtimes',\n 'rum',\n 'security',\n 'notebooks',\n 'users',\n 'teams',\n 'tags',\n 'usage',\n 'auth'\n] as const\n\nexport type ToolName = (typeof ALL_TOOLS)[number]\n\nexport const configSchema = z.object({\n datadog: z.object({\n apiKey: z.string().min(1, 'DD_API_KEY is required'),\n appKey: z.string().min(1, 'DD_APP_KEY is required'),\n site: z.string().default('datadoghq.com')\n }),\n server: z\n .object({\n name: z.string().default('datadog-mcp'),\n version: z.string().default('1.0.0'),\n transport: z.enum(['stdio', 'http']).default('stdio'),\n port: z.number().default(3000),\n host: z.string().default('localhost')\n })\n .default({}),\n limits: z\n .object({\n maxResults: z.number().default(100),\n maxLogLines: z.number().default(100), // Reduced from 500 for token efficiency\n defaultLimit: z.number().default(25), // Default limit for initial queries\n maxMetricDataPoints: z.number().default(1000),\n defaultTimeRangeHours: z.number().default(24)\n })\n .default({}),\n features: z\n .object({\n readOnly: z.boolean().default(false),\n disabledTools: z.array(z.string()).default([])\n })\n .default({})\n})\n\nexport type Config = z.infer<typeof configSchema>\nexport type DatadogConfig = Config['datadog']\nexport type ServerConfig = Config['server']\nexport type LimitsConfig = Config['limits']\nexport type FeaturesConfig = Config['features']\n","import { configSchema, ALL_TOOLS, type Config } from './schema.js'\n\ninterface ParsedArgs {\n strings: Record<string, string>\n booleans: Set<string>\n}\n\n/**\n * Parse --key=value format argument\n * Returns [key, value] or null if invalid\n */\nfunction parseEqualsFormat(arg: string): [string, string] | null {\n if (!arg.includes('=')) return null\n const parts = arg.slice(2).split('=')\n const key = parts[0]\n const value = parts.slice(1).join('=') // Handle values with = in them\n return key && value !== undefined ? [key, value] : null\n}\n\n/**\n * Parse --key value format argument\n * Returns [key, value] or null if next arg is missing/invalid\n */\nfunction parseSpacedFormat(arg: string, nextArg?: string): [string, string] | null {\n if (nextArg && !nextArg.startsWith('--')) {\n return [arg.slice(2), nextArg]\n }\n return null\n}\n\n/**\n * Parse boolean flag argument (--flag with no value)\n * Returns the flag name\n */\nfunction parseBooleanFlag(arg: string): string {\n return arg.slice(2)\n}\n\n/**\n * Parse CLI arguments\n * Supports: --transport, --port, --host, --site, --read-only, --disable-tools\n * Format: --key=value or --key value or --flag (boolean)\n */\nfunction parseArgs(): ParsedArgs {\n const strings: Record<string, string> = {}\n const booleans = new Set<string>()\n const argv = process.argv.slice(2)\n\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i]\n if (!arg) continue\n\n if (arg.startsWith('--')) {\n // Try --key=value format\n const equalsResult = parseEqualsFormat(arg)\n if (equalsResult) {\n const [key, value] = equalsResult\n strings[key] = value\n continue\n }\n\n // Try --key value format\n const spacedResult = parseSpacedFormat(arg, argv[i + 1])\n if (spacedResult) {\n const [key, value] = spacedResult\n strings[key] = value\n i += 1 // Skip next arg since we consumed it\n continue\n }\n\n // Must be boolean flag\n booleans.add(parseBooleanFlag(arg))\n }\n }\n\n return { strings, booleans }\n}\n\n/**\n * Parse disabled tools from comma-separated string\n * Example: \"incidents,notebooks\" -> those tools disabled\n */\nfunction parseDisabledTools(value: string | undefined): string[] {\n if (!value) return []\n\n const requested = value.split(',').map((s) => s.trim().toLowerCase())\n return requested.filter((t) => (ALL_TOOLS as readonly string[]).includes(t))\n}\n\nexport function loadConfig(): Config {\n const args = parseArgs()\n\n const raw = {\n datadog: {\n apiKey: process.env.DD_API_KEY ?? '',\n appKey: process.env.DD_APP_KEY ?? '',\n site: args.strings.site ?? process.env.DD_SITE ?? 'datadoghq.com'\n },\n server: {\n name: 'datadog-mcp',\n version: '1.0.0',\n transport: args.strings.transport ?? process.env.MCP_TRANSPORT ?? 'stdio',\n port: Number.parseInt(args.strings.port ?? process.env.MCP_PORT ?? '3000', 10),\n host: args.strings.host ?? process.env.MCP_HOST ?? 'localhost'\n },\n limits: {\n maxResults: Number.parseInt(process.env.MCP_MAX_RESULTS ?? '100', 10),\n maxLogLines: Number.parseInt(process.env.MCP_MAX_LOG_LINES ?? '500', 10),\n maxMetricDataPoints: Number.parseInt(process.env.MCP_MAX_METRIC_POINTS ?? '1000', 10),\n defaultTimeRangeHours: Number.parseInt(process.env.MCP_DEFAULT_TIME_RANGE ?? '24', 10)\n },\n features: {\n readOnly: args.booleans.has('read-only') || process.env.MCP_READ_ONLY === 'true',\n disabledTools: parseDisabledTools(\n args.strings['disable-tools'] ?? process.env.MCP_DISABLE_TOOLS\n )\n }\n }\n\n return configSchema.parse(raw)\n}\n\nexport {\n type Config,\n type DatadogConfig,\n type ServerConfig,\n type LimitsConfig,\n type FeaturesConfig,\n type ToolName,\n ALL_TOOLS\n} from './schema.js'\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { createDatadogClients } from './config/datadog.js'\nimport { registerAllTools } from './tools/index.js'\nimport type { Config } from './config/index.js'\n\nexport function createServer(config: Config): McpServer {\n const server = new McpServer({\n name: config.server.name,\n version: config.server.version\n })\n\n const clients = createDatadogClients(config.datadog)\n\n registerAllTools(server, clients, config.limits, config.features, config.datadog.site)\n\n return server\n}\n","import { client, v1, v2 } from '@datadog/datadog-api-client'\nimport type { DatadogConfig } from './schema.js'\n\nexport interface DatadogClients {\n monitors: v1.MonitorsApi\n dashboards: v1.DashboardsApi\n dashboardLists: v1.DashboardListsApi\n logs: v2.LogsApi\n metricsV1: v1.MetricsApi\n metricsV2: v2.MetricsApi\n eventsV1: v1.EventsApi\n eventsV2: v2.EventsApi\n incidents: v2.IncidentsApi\n downtimes: v2.DowntimesApi\n hosts: v1.HostsApi\n slo: v1.ServiceLevelObjectivesApi\n synthetics: v1.SyntheticsApi\n rum: v2.RUMApi\n security: v2.SecurityMonitoringApi\n notebooks: v1.NotebooksApi\n users: v2.UsersApi\n teams: v2.TeamsApi\n tags: v1.TagsApi\n usage: v1.UsageMeteringApi\n spans: v2.SpansApi\n services: v2.ServiceDefinitionApi\n auth: v1.AuthenticationApi\n}\n\nexport function createDatadogClients(config: DatadogConfig): DatadogClients {\n const configuration = client.createConfiguration({\n authMethods: {\n apiKeyAuth: config.apiKey,\n appKeyAuth: config.appKey\n }\n })\n\n if (config.site && config.site !== 'datadoghq.com') {\n configuration.setServerVariables({ site: config.site })\n }\n\n // Enable unstable operations for v2 APIs\n configuration.unstableOperations = {\n 'v2.listIncidents': true,\n 'v2.getIncident': true,\n 'v2.searchIncidents': true,\n 'v2.createIncident': true,\n 'v2.updateIncident': true,\n 'v2.deleteIncident': true\n }\n\n return {\n monitors: new v1.MonitorsApi(configuration),\n dashboards: new v1.DashboardsApi(configuration),\n dashboardLists: new v1.DashboardListsApi(configuration),\n logs: new v2.LogsApi(configuration),\n metricsV1: new v1.MetricsApi(configuration),\n metricsV2: new v2.MetricsApi(configuration),\n eventsV1: new v1.EventsApi(configuration),\n eventsV2: new v2.EventsApi(configuration),\n incidents: new v2.IncidentsApi(configuration),\n downtimes: new v2.DowntimesApi(configuration),\n hosts: new v1.HostsApi(configuration),\n slo: new v1.ServiceLevelObjectivesApi(configuration),\n synthetics: new v1.SyntheticsApi(configuration),\n rum: new v2.RUMApi(configuration),\n security: new v2.SecurityMonitoringApi(configuration),\n notebooks: new v1.NotebooksApi(configuration),\n users: new v2.UsersApi(configuration),\n teams: new v2.TeamsApi(configuration),\n tags: new v1.TagsApi(configuration),\n usage: new v1.UsageMeteringApi(configuration),\n spans: new v2.SpansApi(configuration),\n services: new v2.ServiceDefinitionApi(configuration),\n auth: new v1.AuthenticationApi(configuration)\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { buildMonitorUrl, buildMonitorsListUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum([\n 'list',\n 'get',\n 'search',\n 'create',\n 'update',\n 'delete',\n 'mute',\n 'unmute'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Monitor ID (required for get/update/delete/mute/unmute)'),\n query: z.string().optional().describe('Search query (for search action)'),\n name: z.string().optional().describe('Filter by name (for list action)'),\n tags: z.array(z.string()).optional().describe('Filter by tags'),\n groupStates: z\n .array(z.string())\n .optional()\n .describe(\n 'Filter multi-alert monitors by group states (e.g., alert by host). Does NOT filter by overall monitor status. Values: alert, warn, no data, ok'\n ),\n limit: z.number().optional().describe('Maximum number of monitors to return'),\n config: z.record(z.unknown()).optional().describe('Monitor configuration (for create/update)'),\n message: z.string().optional().describe('Mute message (for mute action)'),\n end: z.number().optional().describe('Mute end timestamp (for mute action)')\n}\n\ninterface MonitorSummary {\n id: number\n name: string\n type: string\n status: string\n message: string\n tags: string[]\n query: string\n created: string\n modified: string\n url: string\n}\n\nexport function formatMonitor(m: v1.Monitor, site: string = 'datadoghq.com'): MonitorSummary {\n const monitorId = m.id ?? 0\n return {\n id: monitorId,\n name: m.name ?? '',\n type: String(m.type ?? 'unknown'),\n status: String(m.overallState ?? 'unknown'),\n message: m.message ?? '',\n tags: m.tags ?? [],\n query: m.query ?? '',\n created: m.created ? new Date(m.created).toISOString() : '',\n modified: m.modified ? new Date(m.modified).toISOString() : '',\n url: buildMonitorUrl(monitorId, site)\n }\n}\n\nexport async function listMonitors(\n api: v1.MonitorsApi,\n params: { name?: string; tags?: string[]; groupStates?: string[]; limit?: number },\n limits: LimitsConfig,\n site: string\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listMonitors({\n name: params.name,\n tags: params.tags?.join(','),\n groupStates: params.groupStates?.join(',')\n })\n\n const monitors = response.slice(0, effectiveLimit).map((m) => formatMonitor(m, site))\n\n const statusCounts = {\n total: response.length,\n alert: response.filter((m) => m.overallState === 'Alert').length,\n warn: response.filter((m) => m.overallState === 'Warn').length,\n ok: response.filter((m) => m.overallState === 'OK').length,\n noData: response.filter((m) => m.overallState === 'No Data').length\n }\n\n return {\n monitors,\n summary: statusCounts,\n datadog_url: buildMonitorsListUrl(\n { name: params.name, tags: params.tags, groupStates: params.groupStates },\n site\n )\n }\n}\n\nexport async function getMonitor(api: v1.MonitorsApi, id: string, site: string) {\n const monitorId = Number.parseInt(id, 10)\n if (Number.isNaN(monitorId)) {\n throw new Error(`Invalid monitor ID: ${id}`)\n }\n\n const monitor = await api.getMonitor({ monitorId })\n return {\n monitor: formatMonitor(monitor, site),\n datadog_url: buildMonitorUrl(monitorId, site)\n }\n}\n\nexport async function searchMonitors(\n api: v1.MonitorsApi,\n query: string,\n limits: LimitsConfig,\n site: string\n) {\n const response = await api.searchMonitors({ query })\n const monitors = (response.monitors ?? []).slice(0, limits.maxResults).map((m) => ({\n id: m.id ?? 0,\n name: m.name ?? '',\n status: String(m.status ?? 'unknown'),\n type: m.type ?? '',\n tags: m.tags ?? [],\n url: buildMonitorUrl(m.id ?? 0, site)\n }))\n\n return {\n monitors,\n metadata: {\n totalCount: response.metadata?.totalCount ?? monitors.length,\n pageCount: response.metadata?.pageCount ?? 1,\n page: response.metadata?.page ?? 0\n },\n datadog_url: buildMonitorsListUrl({ name: query }, site)\n }\n}\n\n/**\n * Normalize monitor config to handle snake_case -> camelCase conversion\n * Common fields that users might pass in snake_case\n */\nexport function normalizeMonitorConfig(\n config: Record<string, unknown>,\n isUpdate: boolean = false\n): Record<string, unknown> {\n const normalized = { ...config }\n\n // Required field validation (only for create, not update)\n if (!isUpdate && !normalized.name && !normalized.type && !normalized.query) {\n throw new Error(\"Monitor config requires at least 'name', 'type', and 'query' fields\")\n }\n\n // Handle options object snake_case conversions\n if (normalized.options && typeof normalized.options === 'object') {\n const opts = { ...(normalized.options as Record<string, unknown>) }\n\n // Common snake_case -> camelCase conversions\n const optionMappings: [string, string][] = [\n ['notify_no_data', 'notifyNoData'],\n ['no_data_timeframe', 'noDataTimeframe'],\n ['new_host_delay', 'newHostDelay'],\n ['new_group_delay', 'newGroupDelay'],\n ['evaluation_delay', 'evaluationDelay'],\n ['renotify_interval', 'renotifyInterval'],\n ['renotify_occurrences', 'renotifyOccurrences'],\n ['renotify_statuses', 'renotifyStatuses'],\n ['timeout_h', 'timeoutH'],\n ['notify_audit', 'notifyAudit'],\n ['include_tags', 'includeTags'],\n ['require_full_window', 'requireFullWindow'],\n ['escalation_message', 'escalationMessage'],\n ['locked', 'locked'],\n ['silenced', 'silenced']\n ]\n\n for (const [snake, camel] of optionMappings) {\n if (snake in opts && !(camel in opts)) {\n opts[camel] = opts[snake]\n delete opts[snake]\n }\n }\n\n // Handle nested thresholds\n if (opts.thresholds && typeof opts.thresholds === 'object') {\n const thresholds = { ...(opts.thresholds as Record<string, unknown>) }\n const thresholdMappings: [string, string][] = [\n ['critical', 'critical'],\n ['warning', 'warning'],\n ['ok', 'ok'],\n ['critical_recovery', 'criticalRecovery'],\n ['warning_recovery', 'warningRecovery']\n ]\n for (const [snake, camel] of thresholdMappings) {\n if (snake in thresholds && !(camel in thresholds) && snake !== camel) {\n thresholds[camel] = thresholds[snake]\n delete thresholds[snake]\n }\n }\n opts.thresholds = thresholds\n }\n\n normalized.options = opts\n }\n\n return normalized\n}\n\nexport async function createMonitor(\n api: v1.MonitorsApi,\n config: Record<string, unknown>,\n site: string = 'datadoghq.com'\n) {\n const body = normalizeMonitorConfig(config) as unknown as v1.Monitor\n const monitor = await api.createMonitor({ body })\n return {\n success: true,\n monitor: formatMonitor(monitor, site)\n }\n}\n\nexport async function updateMonitor(\n api: v1.MonitorsApi,\n id: string,\n config: Record<string, unknown>,\n site: string = 'datadoghq.com'\n) {\n const monitorId = Number.parseInt(id, 10)\n const body = normalizeMonitorConfig(config, true) as unknown as v1.MonitorUpdateRequest\n const monitor = await api.updateMonitor({ monitorId, body })\n return {\n success: true,\n monitor: formatMonitor(monitor, site)\n }\n}\n\nexport async function deleteMonitor(api: v1.MonitorsApi, id: string) {\n const monitorId = Number.parseInt(id, 10)\n await api.deleteMonitor({ monitorId })\n return { success: true, message: `Monitor ${id} deleted` }\n}\n\nexport async function muteMonitor(api: v1.MonitorsApi, id: string, params: { end?: number }) {\n const monitorId = Number.parseInt(id, 10)\n // Use validate endpoint with mute options\n const monitor = await api.getMonitor({ monitorId })\n\n // Update the monitor with mute options\n await api.updateMonitor({\n monitorId,\n body: {\n options: {\n ...monitor.options,\n silenced: { '*': params.end ?? null }\n }\n } as unknown as v1.MonitorUpdateRequest\n })\n return { success: true, message: `Monitor ${id} muted` }\n}\n\nexport async function unmuteMonitor(api: v1.MonitorsApi, id: string) {\n const monitorId = Number.parseInt(id, 10)\n const monitor = await api.getMonitor({ monitorId })\n\n // Update the monitor to remove silenced option\n await api.updateMonitor({\n monitorId,\n body: {\n options: {\n ...monitor.options,\n silenced: {}\n }\n } as unknown as v1.MonitorUpdateRequest\n })\n return { success: true, message: `Monitor ${id} unmuted` }\n}\n\nexport function registerMonitorsTool(\n server: McpServer,\n api: v1.MonitorsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'monitors',\n `Manage Datadog monitors. Actions: list, get, search, create, update, delete, mute, unmute.\nFilters: name, tags, groupStates (alert/warn/ok/no data).\nTIP: For alert HISTORY (which monitors triggered), use the events tool with tags: [\"source:alert\"].`,\n InputSchema,\n async ({ action, id, query, name, tags, groupStates, limit, config, end }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listMonitors(api, { name, tags, groupStates, limit }, limits, site)\n )\n\n case 'get': {\n const monitorId = requireParam(id, 'id', 'get')\n return toolResult(await getMonitor(api, monitorId, site))\n }\n\n case 'search': {\n const searchQuery = requireParam(query, 'query', 'search')\n return toolResult(await searchMonitors(api, searchQuery, limits, site))\n }\n\n case 'create': {\n const monitorConfig = requireParam(config, 'config', 'create')\n return toolResult(await createMonitor(api, monitorConfig, site))\n }\n\n case 'update': {\n const monitorId = requireParam(id, 'id', 'update')\n const updateConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateMonitor(api, monitorId, updateConfig, site))\n }\n\n case 'delete': {\n const monitorId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteMonitor(api, monitorId))\n }\n\n case 'mute': {\n const monitorId = requireParam(id, 'id', 'mute')\n return toolResult(await muteMonitor(api, monitorId, { end }))\n }\n\n case 'unmute': {\n const monitorId = requireParam(id, 'id', 'unmute')\n return toolResult(await unmuteMonitor(api, monitorId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'\n\n/**\n * Custom error codes for Datadog-specific errors.\n * Uses JSON-RPC server error range (-32000 to -32099).\n * These allow LLMs to distinguish error types for retry logic.\n */\nexport const DatadogErrorCode = {\n /** 401 - Invalid or missing API/APP key */\n Unauthorized: -32050,\n /** 403 - Valid credentials but insufficient permissions */\n Forbidden: -32051,\n /** 404 - Requested resource does not exist */\n NotFound: -32052,\n /** 429 - Rate limit exceeded, should retry after delay */\n RateLimited: -32053,\n /** 5xx - Datadog service temporarily unavailable */\n ServiceUnavailable: -32054\n} as const\n\n/**\n * Maps Datadog API errors to MCP errors with appropriate error codes.\n * Uses custom error codes to allow LLMs to distinguish between:\n * - Authentication failures (retry won't help without new credentials)\n * - Authorization failures (need different permissions)\n * - Not found (check if resource exists)\n * - Rate limiting (wait and retry)\n * - Service unavailable (temporary, retry later)\n */\nexport function handleDatadogError(error: unknown): never {\n console.error('[Datadog Error]', error)\n\n // Pass through McpError unchanged (check first since McpError also has numeric code)\n if (error instanceof McpError) {\n throw error\n }\n\n // Check for Datadog API errors by duck typing\n const apiError = error as { code?: number; body?: { errors?: string[] }; message?: string }\n if (typeof apiError.code === 'number') {\n const message = apiError.body?.errors?.[0] ?? apiError.message ?? 'Unknown error'\n\n switch (apiError.code) {\n case 400:\n throw new McpError(ErrorCode.InvalidRequest, `Invalid request: ${message}`)\n case 401:\n throw new McpError(\n DatadogErrorCode.Unauthorized,\n `Authentication failed: Invalid Datadog API key or APP key`\n )\n case 403:\n throw new McpError(DatadogErrorCode.Forbidden, `Authorization denied: ${message}`)\n case 404:\n throw new McpError(DatadogErrorCode.NotFound, `Resource not found: ${message}`)\n case 429:\n throw new McpError(\n DatadogErrorCode.RateLimited,\n 'Rate limit exceeded. Retry after a short delay.'\n )\n case 500:\n case 502:\n case 503:\n throw new McpError(\n DatadogErrorCode.ServiceUnavailable,\n 'Datadog service temporarily unavailable. Retry later.'\n )\n default:\n throw new McpError(\n ErrorCode.InternalError,\n `Datadog API error (${apiError.code}): ${message}`\n )\n }\n }\n\n throw new McpError(\n ErrorCode.InternalError,\n error instanceof Error ? error.message : String(error)\n )\n}\n\n/**\n * Validates required parameters for an action\n */\nexport function requireParam<T>(value: T | undefined, name: string, action: string): T {\n if (value === undefined || value === null || value === '') {\n throw new McpError(\n ErrorCode.InvalidParams,\n `Parameter '${name}' is required for action '${action}'`\n )\n }\n return value\n}\n\n/**\n * Write actions that should be blocked in read-only mode\n */\nconst WRITE_ACTIONS = new Set([\n 'create',\n 'update',\n 'delete',\n 'mute',\n 'unmute',\n 'cancel',\n 'add',\n 'trigger'\n])\n\n/**\n * Checks if action is allowed given read-only mode setting.\n * Throws an error for write actions when in read-only mode.\n */\nexport function checkReadOnly(action: string, readOnly: boolean): void {\n if (readOnly && WRITE_ACTIONS.has(action)) {\n throw new McpError(\n ErrorCode.InvalidRequest,\n `Action '${action}' is not allowed in read-only mode. Server started with --read-only flag.`\n )\n }\n}\n","/**\n * Format tool response as MCP content\n */\nexport function formatResponse(data: unknown): { type: 'text'; text: string }[] {\n return [\n {\n type: 'text' as const,\n text: JSON.stringify(data, null, 2) ?? 'null'\n }\n ]\n}\n\n/**\n * Create a structured tool result\n */\nexport function toolResult<T>(data: T): { content: { type: 'text'; text: string }[] } {\n return {\n content: formatResponse(data)\n }\n}\n","/**\n * Datadog URL builders for deep linking to the Datadog UI\n *\n * These functions generate URLs that link directly to Datadog's web interface,\n * allowing AI tools to provide evidence links back to the source data.\n */\n\n/**\n * Map Datadog API sites to their corresponding app URLs\n */\nconst SITE_TO_APP_URL: Record<string, string> = {\n 'datadoghq.com': 'https://app.datadoghq.com',\n 'us3.datadoghq.com': 'https://us3.datadoghq.com',\n 'us5.datadoghq.com': 'https://us5.datadoghq.com',\n 'datadoghq.eu': 'https://app.datadoghq.eu',\n 'ap1.datadoghq.com': 'https://ap1.datadoghq.com',\n 'ddog-gov.com': 'https://app.ddog-gov.com'\n}\n\n/**\n * Get the app base URL for a given Datadog site\n */\nfunction getAppBaseUrl(site: string = 'datadoghq.com'): string {\n return SITE_TO_APP_URL[site] ?? SITE_TO_APP_URL['datadoghq.com']!\n}\n\n/**\n * Convert Unix seconds to milliseconds for URL params\n */\nfunction toMs(seconds: number): number {\n return seconds * 1000\n}\n\n/**\n * Build a Datadog Logs Explorer URL\n *\n * @param query - Log search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildLogsUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/logs?${params.toString()}`\n}\n\n/**\n * Extract metric name from a PromQL-style query\n * e.g., \"avg:system.cpu.user{host:foo}\" -> \"system.cpu.user\"\n */\nfunction extractMetricName(query: string): string {\n // Pattern: aggregation:metric_name{tags} or just metric_name{tags}\n const match = query.match(/^(?:\\w+:)?([a-zA-Z0-9_.]+)/)\n return match?.[1] ?? query\n}\n\n/**\n * Build a Datadog Metrics Explorer URL\n *\n * @param query - PromQL-style metric query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildMetricsUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const metricName = extractMetricName(query)\n const params = new URLSearchParams({\n exp_metric: metricName,\n exp_query: query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/metric/explorer?${params.toString()}`\n}\n\n/**\n * Build a Datadog APM Traces URL\n * Note: APM uses start/end instead of from_ts/to_ts\n *\n * @param query - APM trace search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildTracesUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n start: toMs(fromSec).toString(),\n end: toMs(toSec).toString()\n })\n return `${base}/apm/traces?${params.toString()}`\n}\n\n/**\n * Build a Datadog Events Explorer URL\n *\n * @param query - Event search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildEventsUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/event/explorer?${params.toString()}`\n}\n\n/**\n * Build a Datadog Monitor URL\n *\n * @param monitorId - Monitor ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildMonitorUrl(\n monitorId: string | number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n return `${base}/monitors/${monitorId}`\n}\n\n/**\n * Build a Datadog Monitors List URL with optional query filters\n *\n * @param options - Filter options (name, tags, groupStates)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildMonitorsListUrl(\n options?: { name?: string; tags?: string[]; groupStates?: string[] },\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams()\n\n if (options?.name) {\n params.set('query', options.name)\n }\n if (options?.tags && options.tags.length > 0) {\n params.set('tags', options.tags.join(','))\n }\n if (options?.groupStates && options.groupStates.length > 0) {\n params.set('group_states', options.groupStates.join(','))\n }\n\n const queryString = params.toString()\n return queryString ? `${base}/monitors/manage?${queryString}` : `${base}/monitors/manage`\n}\n\n/**\n * Build a Datadog RUM Explorer URL\n *\n * @param query - RUM search query\n * @param fromSec - Start time (Unix seconds)\n * @param toSec - End time (Unix seconds)\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildRumUrl(\n query: string,\n fromSec: number,\n toSec: number,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n const params = new URLSearchParams({\n query,\n from_ts: toMs(fromSec).toString(),\n to_ts: toMs(toSec).toString()\n })\n return `${base}/rum/explorer?${params.toString()}`\n}\n\n/**\n * Build a Datadog RUM Session Replay URL\n *\n * @param applicationId - RUM Application ID\n * @param sessionId - Session ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildRumSessionUrl(\n applicationId: string,\n sessionId: string,\n site: string = 'datadoghq.com'\n): string {\n const base = getAppBaseUrl(site)\n return `${base}/rum/replay/sessions/${sessionId}?applicationId=${encodeURIComponent(applicationId)}`\n}\n\n/**\n * Build a Datadog Dashboard URL\n *\n * @param dashboardId - Dashboard ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildDashboardUrl(dashboardId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/dashboard/${dashboardId}`\n}\n\n/**\n * Build a Datadog SLO URL\n *\n * @param sloId - SLO ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildSloUrl(sloId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/slo/${sloId}`\n}\n\n/**\n * Build a Datadog Incident URL\n *\n * @param incidentId - Incident ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildIncidentUrl(incidentId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/incidents/${incidentId}`\n}\n\n/**\n * Build a Datadog Synthetic Test URL\n *\n * @param publicId - Synthetic test public ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildSyntheticUrl(publicId: string, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/synthetics/details/${publicId}`\n}\n\n/**\n * Build a Datadog Notebook URL\n *\n * @param notebookId - Notebook ID\n * @param site - Datadog site (default: datadoghq.com)\n */\nexport function buildNotebookUrl(notebookId: number, site: string = 'datadoghq.com'): string {\n const base = getAppBaseUrl(site)\n return `${base}/notebook/${notebookId}`\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Dashboard ID (required for get/update/delete)'),\n name: z.string().optional().describe('Filter by name'),\n tags: z.array(z.string()).optional().describe('Filter by tags'),\n limit: z.number().optional().describe('Maximum number of dashboards to return'),\n config: z.record(z.unknown()).optional().describe('Dashboard configuration (for create/update)')\n}\n\ninterface DashboardSummary {\n id: string\n title: string\n description: string\n url: string\n layoutType: string\n created: string\n modified: string\n authorHandle: string\n}\n\nexport function formatDashboardSummary(d: v1.DashboardSummaryDefinition): DashboardSummary {\n return {\n id: d.id ?? '',\n title: d.title ?? '',\n description: d.description ?? '',\n url: d.url ?? '',\n layoutType: String(d.layoutType ?? 'unknown'),\n created: d.createdAt ? new Date(d.createdAt).toISOString() : '',\n modified: d.modifiedAt ? new Date(d.modifiedAt).toISOString() : '',\n authorHandle: d.authorHandle ?? ''\n }\n}\n\nexport async function listDashboards(\n api: v1.DashboardsApi,\n params: { name?: string; tags?: string[]; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listDashboards({\n filterShared: false\n })\n\n let dashboards = response.dashboards ?? []\n\n // Client-side filtering by name\n if (params.name) {\n const lowerName = params.name.toLowerCase()\n dashboards = dashboards.filter((d) => d.title?.toLowerCase().includes(lowerName))\n }\n\n const result = dashboards.slice(0, effectiveLimit).map(formatDashboardSummary)\n\n return {\n dashboards: result,\n total: response.dashboards?.length ?? 0\n }\n}\n\nexport async function getDashboard(api: v1.DashboardsApi, id: string) {\n const dashboard = await api.getDashboard({ dashboardId: id })\n return {\n dashboard: {\n id: dashboard.id ?? '',\n title: dashboard.title ?? '',\n description: dashboard.description ?? '',\n layoutType: String(dashboard.layoutType ?? 'unknown'),\n widgets: dashboard.widgets?.length ?? 0,\n url: dashboard.url ?? '',\n created: dashboard.createdAt ? new Date(dashboard.createdAt).toISOString() : '',\n modified: dashboard.modifiedAt ? new Date(dashboard.modifiedAt).toISOString() : '',\n authorHandle: dashboard.authorHandle ?? ''\n }\n }\n}\n\nexport function normalizeDashboardConfig(config: Record<string, unknown>): Record<string, unknown> {\n const normalized = { ...config }\n\n // Handle layout_type -> layoutType\n if ('layout_type' in normalized && !('layoutType' in normalized)) {\n normalized.layoutType = normalized.layout_type\n delete normalized.layout_type\n }\n\n // Validate required field\n if (!normalized.layoutType) {\n throw new Error(\"Dashboard config requires 'layoutType' (e.g., 'ordered', 'free')\")\n }\n\n // Validate tags if present - Datadog only allows 'team' as the tag key\n if (normalized.tags && Array.isArray(normalized.tags)) {\n const invalidTags = normalized.tags.filter((tag: unknown) => {\n if (typeof tag !== 'string') return true\n return !tag.startsWith('team:')\n })\n if (invalidTags.length > 0) {\n throw new Error(\n `Dashboard tags must use 'team:' prefix. Invalid tags: ${invalidTags.join(', ')}. Example: [\"team:operations\", \"team:frontend\"]`\n )\n }\n }\n\n return normalized\n}\n\nexport async function createDashboard(api: v1.DashboardsApi, config: Record<string, unknown>) {\n const body = normalizeDashboardConfig(config) as unknown as v1.Dashboard\n const dashboard = await api.createDashboard({ body })\n return {\n success: true,\n dashboard: {\n id: dashboard.id ?? '',\n title: dashboard.title ?? '',\n url: dashboard.url ?? ''\n }\n }\n}\n\nexport async function updateDashboard(\n api: v1.DashboardsApi,\n id: string,\n config: Record<string, unknown>\n) {\n const body = normalizeDashboardConfig(config) as unknown as v1.Dashboard\n const dashboard = await api.updateDashboard({ dashboardId: id, body })\n return {\n success: true,\n dashboard: {\n id: dashboard.id ?? '',\n title: dashboard.title ?? '',\n url: dashboard.url ?? ''\n }\n }\n}\n\nexport async function deleteDashboard(api: v1.DashboardsApi, id: string) {\n await api.deleteDashboard({ dashboardId: id })\n return { success: true, message: `Dashboard ${id} deleted` }\n}\n\nexport function registerDashboardsTool(\n server: McpServer,\n api: v1.DashboardsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'dashboards',\n 'Access Datadog dashboards and visualizations. Actions: list (filter by name/tags), get, create, update, delete. Use for: finding existing views, team dashboards, understanding what is monitored. NOTE: Dashboard tags must use \"team:\" prefix (e.g., [\"team:operations\"]).',\n InputSchema,\n async ({ action, id, name, tags, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listDashboards(api, { name, tags, limit }, limits))\n\n case 'get': {\n const dashboardId = requireParam(id, 'id', 'get')\n return toolResult(await getDashboard(api, dashboardId))\n }\n\n case 'create': {\n const dashboardConfig = requireParam(config, 'config', 'create')\n return toolResult(await createDashboard(api, dashboardConfig))\n }\n\n case 'update': {\n const dashboardId = requireParam(id, 'id', 'update')\n const updateConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateDashboard(api, dashboardId, updateConfig))\n }\n\n case 'delete': {\n const dashboardId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteDashboard(api, dashboardId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { hoursAgo, now, parseTime, ensureValidTimeRange } from '../utils/time.js'\nimport { buildLogsUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['search', 'aggregate'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe(\n 'Log search query (Datadog syntax). Examples: \"error\", \"service:my-service status:error\", \"error AND timeout\"'\n ),\n keyword: z\n .string()\n .optional()\n .describe(\n 'Simple text search - finds logs containing this text (grep-like). Merged with query using AND'\n ),\n pattern: z\n .string()\n .optional()\n .describe(\n 'Regex pattern to match in log message (grep -E style). Example: \"ERROR.*timeout|connection refused\"'\n ),\n from: z\n .string()\n .optional()\n .describe(\n 'Start time. Formats: ISO 8601, relative (30s, 15m, 2h, 7d), precise (3d@11:45:23, yesterday@14:00)'\n ),\n to: z\n .string()\n .optional()\n .describe('End time. Same formats as \"from\". Example: from=\"3d@11:45:23\" to=\"3d@12:55:34\"'),\n service: z.string().optional().describe('Filter by service name'),\n host: z.string().optional().describe('Filter by host'),\n status: z\n .enum(['error', 'warn', 'info', 'debug'])\n .optional()\n .describe('Filter by log status/level'),\n indexes: z.array(z.string()).optional().describe('Log indexes to search'),\n limit: z.number().optional().describe('Maximum number of logs to return'),\n sort: z.enum(['timestamp', '-timestamp']).optional().describe('Sort order'),\n sample: z\n .enum(['first', 'spread', 'diverse'])\n .optional()\n .describe(\n 'Sampling mode: first (chronological, default), spread (evenly across time range), diverse (distinct message patterns)'\n ),\n compact: z\n .boolean()\n .optional()\n .describe(\n 'Strip custom attributes for token efficiency. Keeps: id, timestamp, service, host, status, message (truncated), dd.trace_id, dd.span_id, pod_name, kube_namespace, kube_container_name, error info'\n ),\n groupBy: z.array(z.string()).optional().describe('Fields to group by (for aggregate)'),\n compute: z.record(z.unknown()).optional().describe('Compute operations (for aggregate)')\n}\n\ninterface LogEntry {\n id: string\n timestamp: string\n service: string\n host: string\n status: string\n message: string\n tags: string[]\n attributes: Record<string, unknown>\n}\n\nexport function formatLog(log: v2.Log): LogEntry {\n const attrs = log.attributes ?? {}\n // Handle timestamp which can be Date or string\n let timestamp = ''\n if (attrs.timestamp) {\n const ts = attrs.timestamp\n timestamp = ts instanceof Date ? ts.toISOString() : new Date(String(ts)).toISOString()\n }\n return {\n id: log.id ?? '',\n timestamp,\n service: (attrs.service as string) ?? '',\n host: (attrs.host as string) ?? '',\n status: (attrs.status as string) ?? '',\n message: (attrs.message as string) ?? '',\n tags: (attrs.tags as string[]) ?? [],\n attributes: (attrs.attributes as Record<string, unknown>) ?? {}\n }\n}\n\n/**\n * Compact log format for token efficiency\n * Strips custom attributes object, keeps only essential fields for investigation\n */\ninterface CompactLogEntry {\n id: string\n timestamp: string\n service: string\n host: string\n status: string\n message: string // truncated to 500 chars\n traceId: string // extracted from dd.trace_id for correlation\n spanId: string\n podName?: string // extracted from pod_name tag\n namespace?: string // extracted from kube_namespace tag\n container?: string // extracted from kube_container_name tag\n error?: {\n type: string\n message: string\n }\n}\n\ntype FormattedLog = LogEntry | CompactLogEntry\n\nexport function formatLogCompact(log: v2.Log): CompactLogEntry {\n const attrs = log.attributes ?? {}\n const nestedAttrs = (attrs.attributes as Record<string, unknown>) ?? {}\n const tags = (attrs.tags as string[]) ?? []\n\n // Parse Kubernetes fields from tags (format: \"key:value\")\n const findTagValue = (tagPrefix: string): string => {\n const tag = tags.find((t) => t.startsWith(tagPrefix + ':'))\n return tag ? tag.substring(tagPrefix.length + 1) : ''\n }\n\n const podName = findTagValue('pod_name')\n const namespace = findTagValue('kube_namespace')\n const container = findTagValue('kube_container_name')\n\n // Handle timestamp\n let timestamp = ''\n if (attrs.timestamp) {\n const ts = attrs.timestamp\n timestamp = ts instanceof Date ? ts.toISOString() : new Date(String(ts)).toISOString()\n }\n\n // Extract trace correlation IDs from various possible locations\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const attrsAny = attrs as any\n const traceId =\n (nestedAttrs['dd.trace_id'] as string) ??\n (nestedAttrs['trace_id'] as string) ??\n (attrsAny['dd.trace_id'] as string) ??\n ''\n const spanId =\n (nestedAttrs['dd.span_id'] as string) ??\n (nestedAttrs['span_id'] as string) ??\n (attrsAny['dd.span_id'] as string) ??\n ''\n\n // Extract error info\n const errorType =\n (nestedAttrs['error.type'] as string) ?? (nestedAttrs['error.kind'] as string) ?? ''\n const errorMessage =\n (nestedAttrs['error.message'] as string) ?? (nestedAttrs['error.msg'] as string) ?? ''\n\n // Truncate message for token efficiency\n const fullMessage = (attrs.message as string) ?? ''\n const message = fullMessage.length > 500 ? fullMessage.slice(0, 500) + '...' : fullMessage\n\n const entry: CompactLogEntry = {\n id: log.id ?? '',\n timestamp,\n service: (attrs.service as string) ?? '',\n host: (attrs.host as string) ?? '',\n status: (attrs.status as string) ?? '',\n message,\n traceId,\n spanId\n }\n\n // Add Kubernetes fields if present\n if (podName) entry.podName = podName\n if (namespace) entry.namespace = namespace\n if (container) entry.container = container\n\n // Only include error if present\n if (errorType || errorMessage) {\n entry.error = {\n type: errorType,\n message: errorMessage.length > 200 ? errorMessage.slice(0, 200) + '...' : errorMessage\n }\n }\n\n return entry\n}\n\n/**\n * Normalize a log message to a pattern by replacing variable parts\n * Used for diverse sampling to identify distinct error patterns\n */\nexport function normalizeToPattern(message: string): string {\n return (\n message\n // UUIDs (universal format)\n .replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, '{UUID}')\n // Long hex strings (16+ chars - trace IDs, hashes, object IDs)\n .replace(/\\b[0-9a-f]{16,}\\b/gi, '{HEX}')\n // Shorter hex IDs (8-15 chars)\n .replace(/\\b[0-9a-f]{8,15}\\b/gi, '{ID}')\n // ISO timestamps\n .replace(/\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}[.\\dZ]*/g, '{TS}')\n // IP addresses\n .replace(/\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/g, '{IP}')\n // Large numbers (4+ digits) - after other patterns to avoid breaking them\n .replace(/\\b\\d{4,}\\b/g, '{N}')\n // Truncate for efficient hashing\n .slice(0, 200)\n )\n}\n\n/**\n * Spread sample: evenly distributed across the array\n */\nexport function spreadSample<T>(items: T[], limit: number): T[] {\n if (items.length <= limit) return items\n const step = items.length / limit\n return Array.from({ length: limit }, (_, i) => items[Math.floor(i * step)] as T)\n}\n\n/**\n * Diverse sample: deduplicate by message pattern to get distinct error types\n */\nexport function diverseSample<T extends { message: string }>(\n items: T[],\n limit: number\n): { samples: T[]; patterns: number } {\n const seen = new Map<string, T>()\n\n for (const item of items) {\n const pattern = normalizeToPattern(item.message)\n if (!seen.has(pattern)) {\n seen.set(pattern, item)\n if (seen.size >= limit) break\n }\n }\n\n return {\n samples: Array.from(seen.values()),\n patterns: seen.size\n }\n}\n\n/**\n * Build a Datadog log query from various filter parameters\n */\nexport function buildLogQuery(params: {\n query?: string\n keyword?: string\n pattern?: string\n service?: string\n host?: string\n status?: string\n}): string {\n const parts: string[] = []\n\n // Base query or wildcard\n if (params.query) {\n parts.push(params.query)\n }\n\n // Simple keyword search (grep-like)\n if (params.keyword) {\n // Escape special characters and wrap in quotes for exact phrase\n const escaped = params.keyword.replace(/\"/g, '\\\\\"')\n parts.push(`\"${escaped}\"`)\n }\n\n // Regex pattern search on message field\n if (params.pattern) {\n // Datadog regex syntax: @field:~\"pattern\"\n const escaped = params.pattern.replace(/\"/g, '\\\\\"')\n parts.push(`@message:~\"${escaped}\"`)\n }\n\n // Service filter\n if (params.service) {\n parts.push(`service:${params.service}`)\n }\n\n // Host filter\n if (params.host) {\n parts.push(`host:${params.host}`)\n }\n\n // Status filter\n if (params.status) {\n parts.push(`status:${params.status}`)\n }\n\n // If no parts, search everything\n return parts.length > 0 ? parts.join(' ') : '*'\n}\n\nexport async function searchLogs(\n api: v2.LogsApi,\n params: {\n query?: string\n keyword?: string\n pattern?: string\n service?: string\n host?: string\n status?: string\n from?: string\n to?: string\n indexes?: string[]\n limit?: number\n sort?: 'timestamp' | '-timestamp'\n sample?: 'first' | 'spread' | 'diverse'\n compact?: boolean\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n // Build the full query from all filter params\n const fullQuery = buildLogQuery({\n query: params.query,\n keyword: params.keyword,\n pattern: params.pattern,\n service: params.service,\n host: params.host,\n status: params.status\n })\n\n const requestedLimit = params.limit ?? limits.defaultLimit\n const sampleMode = params.sample ?? 'first'\n\n // For spread/diverse sampling, fetch more logs to sample from\n const fetchMultiplier = sampleMode === 'first' ? 1 : 4\n const fetchLimit = Math.min(requestedLimit * fetchMultiplier, limits.maxLogLines)\n\n const body: v2.LogsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n indexes: params.indexes\n },\n sort: params.sort === 'timestamp' ? 'timestamp' : '-timestamp',\n page: {\n limit: fetchLimit\n }\n }\n\n const response = await api.listLogs({ body })\n\n // Format logs (compact or full)\n const formattedLogs = params.compact\n ? (response.data ?? []).map(formatLogCompact)\n : (response.data ?? []).map(formatLog)\n\n // Apply sampling based on mode\n // Type assertion needed because ternary produces CompactLogEntry[] | LogEntry[]\n // but generic functions need (CompactLogEntry | LogEntry)[]\n let logs: FormattedLog[]\n let distinctPatterns: number | undefined\n\n switch (sampleMode) {\n case 'spread':\n logs = spreadSample(formattedLogs as FormattedLog[], requestedLimit)\n break\n case 'diverse': {\n const result = diverseSample(formattedLogs as FormattedLog[], requestedLimit)\n logs = result.samples\n distinctPatterns = result.patterns\n break\n }\n case 'first':\n default:\n logs = formattedLogs.slice(0, requestedLimit)\n }\n\n return {\n logs,\n meta: {\n count: logs.length,\n query: fullQuery,\n from: fromTime,\n to: toTime,\n compact: params.compact ?? false,\n sample: sampleMode,\n ...(sampleMode !== 'first' && { fetched: formattedLogs.length }),\n ...(distinctPatterns !== undefined && { distinctPatterns }),\n datadog_url: buildLogsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\nexport async function aggregateLogs(\n api: v2.LogsApi,\n params: {\n query: string\n from?: string\n to?: string\n groupBy?: string[]\n compute?: Record<string, unknown>\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const computeOps: v2.LogsCompute[] = params.compute\n ? [params.compute as unknown as v2.LogsCompute]\n : [{ aggregation: 'count' as const, type: 'total' as const }]\n\n const body: v2.LogsAggregateRequest = {\n filter: {\n query: params.query,\n from: fromTime,\n to: toTime\n },\n compute: computeOps,\n groupBy: params.groupBy?.map((field) => ({\n facet: field,\n limit: 10\n }))\n }\n\n const response = await api.aggregateLogs({ body })\n\n return {\n buckets: response.data?.buckets ?? [],\n meta: {\n query: params.query,\n from: fromTime,\n to: toTime,\n groupBy: params.groupBy,\n datadog_url: buildLogsUrl(params.query, validFrom, validTo, site)\n }\n }\n}\n\nexport function registerLogsTool(\n server: McpServer,\n api: v2.LogsApi,\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'logs',\n `Search Datadog logs with grep-like text filtering. Actions: search (find logs), aggregate (count/group). Key filters: keyword (text grep), pattern (regex), service, host, status (error/warn/info). Time ranges: \"1h\", \"3d@11:45:23\".\nCORRELATION: Logs contain dd.trace_id in attributes for linking to traces and APM metrics.\nSAMPLING: Use sample:\"diverse\" for error investigation (dedupes by message pattern), sample:\"spread\" for time distribution.\nTOKEN TIP: Use compact:true to reduce payload size (strips heavy fields) when querying large volumes.`,\n InputSchema,\n async ({\n action,\n query,\n keyword,\n pattern,\n service,\n host,\n status,\n from,\n to,\n indexes,\n limit,\n sort,\n sample,\n compact,\n groupBy,\n compute\n }) => {\n try {\n switch (action) {\n case 'search': {\n // Query is now optional - can use keyword, pattern, or filters instead\n return toolResult(\n await searchLogs(\n api,\n {\n query,\n keyword,\n pattern,\n service,\n host,\n status,\n from,\n to,\n indexes,\n limit,\n sort,\n sample,\n compact\n },\n limits,\n site\n )\n )\n }\n\n case 'aggregate': {\n const aggregateQuery = query ?? '*'\n return toolResult(\n await aggregateLogs(\n api,\n {\n query: aggregateQuery,\n from,\n to,\n groupBy,\n compute\n },\n limits,\n site\n )\n )\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","/**\n * Get Unix timestamp from hours ago\n */\nexport function hoursAgo(hours: number): number {\n return Math.floor(Date.now() / 1000) - hours * 3600\n}\n\n/**\n * Get Unix timestamp from days ago\n */\nexport function daysAgo(days: number): number {\n return Math.floor(Date.now() / 1000) - days * 86400\n}\n\n/**\n * Get current Unix timestamp\n */\nexport function now(): number {\n return Math.floor(Date.now() / 1000)\n}\n\n/**\n * Get start of a day (midnight) N days ago\n */\nfunction startOfDayAgo(days: number): Date {\n const date = new Date()\n date.setDate(date.getDate() - days)\n date.setHours(0, 0, 0, 0)\n return date\n}\n\n/**\n * Parse time string to Unix timestamp\n *\n * Supported formats:\n * - ISO 8601: \"2024-01-15T11:45:23Z\"\n * - Relative simple: \"30s\", \"15m\", \"2h\", \"7d\"\n * - Relative with time: \"3d@11:45:23\", \"3d@11:45\", \"1d@14:30:00\"\n * - Keywords with time: \"today@09:30\", \"yesterday@14:00:00\"\n * - Unix timestamp: 1702656000 or \"1702656000\"\n *\n * Examples for LLMs:\n * - \"3d@11:45:23\" = 3 days ago at 11:45:23\n * - \"1d@14:30\" = yesterday at 14:30:00\n * - \"today@09:00\" = today at 09:00:00\n * - \"2h\" = 2 hours ago from now\n */\nexport function parseTime(input: string | number | undefined, defaultValue: number): number {\n if (input === undefined) {\n return defaultValue\n }\n\n if (typeof input === 'number') {\n return input\n }\n\n const trimmed = input.trim()\n\n // Simple relative time: 30s, 15m, 2h, 7d\n const simpleRelativeMatch = trimmed.match(/^(\\d+)([smhd])$/)\n if (simpleRelativeMatch) {\n const value = Number.parseInt(simpleRelativeMatch[1] ?? '0', 10)\n const unit = simpleRelativeMatch[2]\n const nowTs = now()\n switch (unit) {\n case 's':\n return nowTs - value\n case 'm':\n return nowTs - value * 60\n case 'h':\n return nowTs - value * 3600\n case 'd':\n return nowTs - value * 86400\n default:\n return defaultValue\n }\n }\n\n // Relative time with specific time: 3d@11:45:23 or 3d@11:45\n const relativeWithTimeMatch = trimmed.match(/^(\\d+)([dh])[@\\s](\\d{1,2}):(\\d{2})(?::(\\d{2}))?$/)\n if (relativeWithTimeMatch) {\n const value = Number.parseInt(relativeWithTimeMatch[1] ?? '0', 10)\n const unit = relativeWithTimeMatch[2]\n const hours = Number.parseInt(relativeWithTimeMatch[3] ?? '0', 10)\n const minutes = Number.parseInt(relativeWithTimeMatch[4] ?? '0', 10)\n const seconds = Number.parseInt(relativeWithTimeMatch[5] ?? '0', 10)\n\n if (unit === 'd') {\n const date = startOfDayAgo(value)\n date.setHours(hours, minutes, seconds, 0)\n return Math.floor(date.getTime() / 1000)\n }\n // For hours, we go back N hours then set to specific minute/second\n // This is less common but supported\n const date = new Date()\n date.setHours(date.getHours() - value)\n date.setMinutes(minutes, seconds, 0)\n return Math.floor(date.getTime() / 1000)\n }\n\n // Keywords: today@09:30, yesterday@14:00:00\n const keywordMatch = trimmed.match(/^(today|yesterday)[@\\s](\\d{1,2}):(\\d{2})(?::(\\d{2}))?$/i)\n if (keywordMatch) {\n const keyword = keywordMatch[1]?.toLowerCase()\n const hours = Number.parseInt(keywordMatch[2] ?? '0', 10)\n const minutes = Number.parseInt(keywordMatch[3] ?? '0', 10)\n const seconds = Number.parseInt(keywordMatch[4] ?? '0', 10)\n\n const daysAgo = keyword === 'yesterday' ? 1 : 0\n const date = startOfDayAgo(daysAgo)\n date.setHours(hours, minutes, seconds, 0)\n return Math.floor(date.getTime() / 1000)\n }\n\n // ISO 8601 date\n const date = new Date(trimmed)\n if (!Number.isNaN(date.getTime())) {\n return Math.floor(date.getTime() / 1000)\n }\n\n // Unix timestamp as string\n const ts = Number.parseInt(trimmed, 10)\n if (!Number.isNaN(ts)) {\n return ts\n }\n\n return defaultValue\n}\n\n/**\n * Ensure from < to for time range queries\n * If from >= to, adjusts to to be from + minRangeSeconds\n *\n * @param from - Start timestamp (Unix seconds)\n * @param to - End timestamp (Unix seconds)\n * @param minRangeSeconds - Minimum range in seconds (default: 60 = 1 minute)\n * @returns Tuple of [adjustedFrom, adjustedTo] where from < to\n */\nexport function ensureValidTimeRange(\n from: number,\n to: number,\n minRangeSeconds: number = 60\n): [number, number] {\n // If from > to, swap them (user probably made a mistake)\n if (from > to) {\n ;[from, to] = [to, from]\n }\n\n // If from == to (or very close), add minimum buffer to 'to'\n if (to - from < minRangeSeconds) {\n to = from + minRangeSeconds\n }\n\n return [from, to]\n}\n\n/**\n * Parse duration string to nanoseconds (for Datadog APM queries)\n *\n * Supported formats:\n * - \"100ns\" = 100 nanoseconds\n * - \"50us\" or \"50µs\" = 50 microseconds\n * - \"500ms\" = 500 milliseconds\n * - \"2s\" = 2 seconds\n * - \"1.5s\" = 1.5 seconds\n * - \"5m\" = 5 minutes\n * - \"1h\" = 1 hour\n * - Raw number = nanoseconds\n *\n * Examples for LLMs:\n * - \"1s\" = 1,000,000,000 ns (find spans >1 second)\n * - \"500ms\" = 500,000,000 ns (find spans >500ms)\n * - \"5s\" = 5,000,000,000 ns (find slow database calls)\n */\nexport function parseDurationToNs(input: string | number | undefined): number | undefined {\n if (input === undefined) {\n return undefined\n }\n\n if (typeof input === 'number') {\n return input\n }\n\n const trimmed = input.trim().toLowerCase()\n\n // Match: number + optional decimal + unit\n const match = trimmed.match(/^(\\d+(?:\\.\\d+)?)(ns|µs|us|ms|s|m|h|d|w)?$/)\n if (!match) {\n // Try parsing as raw number (assume nanoseconds)\n const raw = Number.parseInt(trimmed, 10)\n return Number.isNaN(raw) ? undefined : raw\n }\n\n const value = Number.parseFloat(match[1] ?? '0')\n const unit = match[2] ?? 'ns'\n\n const multipliers: Record<string, number> = {\n ns: 1,\n µs: 1000,\n us: 1000,\n ms: 1000000,\n s: 1000000000,\n m: 60000000000,\n h: 3600000000000,\n d: 86400000000000,\n w: 604800000000000\n }\n\n return Math.floor(value * (multipliers[unit] ?? 1))\n}\n\n/**\n * Format nanoseconds to human-readable duration\n */\nexport function formatDurationNs(ns: number): string {\n if (ns < 1000) return `${ns}ns`\n if (ns < 1000000) return `${(ns / 1000).toFixed(1)}µs`\n if (ns < 1000000000) return `${(ns / 1000000).toFixed(1)}ms`\n if (ns < 60000000000) return `${(ns / 1000000000).toFixed(2)}s`\n return `${(ns / 60000000000).toFixed(2)}m`\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1, v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { hoursAgo, now, parseTime, ensureValidTimeRange } from '../utils/time.js'\nimport { buildMetricsUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['query', 'search', 'list', 'metadata'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe(\n 'For query: PromQL expression (e.g., \"avg:system.cpu.user{*}\"). For search: grep-like filter on metric names. For list: tag filter.'\n ),\n from: z\n .string()\n .optional()\n .describe(\n 'Start time (ONLY for query action). Formats: ISO 8601, relative (30s, 15m, 2h, 7d), precise (3d@11:45:23)'\n ),\n to: z.string().optional().describe('End time (ONLY for query action). Same formats as \"from\".'),\n metric: z.string().optional().describe('Metric name (for metadata action)'),\n tag: z.string().optional().describe('Filter by tag'),\n limit: z.number().optional().describe('Maximum number of results (for search/list)')\n}\n\ninterface MetricSeriesData {\n metric: string\n points: Array<{ timestamp: number; value: number }>\n scope: string\n tags: string[]\n}\n\nexport async function queryMetrics(\n api: v1.MetricsApi,\n params: {\n query: string\n from?: string\n to?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Parse and validate time range (ensures from < to)\n const [fromTs, toTs] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n\n const response = await api.queryMetrics({\n from: fromTs,\n to: toTs,\n query: params.query\n })\n\n const series: MetricSeriesData[] = (response.series ?? []).map((s) => ({\n metric: s.metric ?? '',\n points: (s.pointlist ?? []).slice(0, limits.maxMetricDataPoints).map((p) => ({\n timestamp: p[0] ?? 0,\n value: p[1] ?? 0\n })),\n scope: s.scope ?? '',\n tags: s.tagSet ?? []\n }))\n\n return {\n series,\n meta: {\n query: params.query,\n from: new Date(fromTs * 1000).toISOString(),\n to: new Date(toTs * 1000).toISOString(),\n seriesCount: series.length,\n datadog_url: buildMetricsUrl(params.query, fromTs, toTs, site)\n }\n }\n}\n\nexport async function searchMetrics(\n api: v1.MetricsApi,\n params: { query: string; limit?: number },\n limits: LimitsConfig\n) {\n // Use listActiveMetrics with 24h window (same as list), then filter by name\n const response = await api.listActiveMetrics({\n from: hoursAgo(24),\n host: undefined,\n tagFilter: undefined // Must match listMetrics exactly\n })\n\n const allMetrics = response.metrics ?? []\n const lowerQuery = params.query.toLowerCase()\n\n // Filter by query (grep-like on metric name)\n const filtered = allMetrics\n .filter((name) => name.toLowerCase().includes(lowerQuery))\n .slice(0, params.limit ?? limits.maxResults)\n\n return {\n metrics: filtered,\n total: filtered.length,\n searchedFrom: allMetrics.length\n }\n}\n\nexport async function listMetrics(\n api: v1.MetricsApi,\n params: { query?: string },\n limits: LimitsConfig\n) {\n const response = await api.listActiveMetrics({\n from: hoursAgo(24),\n host: undefined,\n tagFilter: params.query\n })\n\n const metrics = (response.metrics ?? []).slice(0, limits.maxResults)\n\n return {\n metrics,\n total: response.metrics?.length ?? 0\n }\n}\n\nexport async function getMetricMetadata(api: v1.MetricsApi, metricName: string) {\n const metadata = await api.getMetricMetadata({ metricName })\n\n return {\n metric: metricName,\n description: metadata.description ?? '',\n unit: metadata.unit ?? '',\n perUnit: metadata.perUnit ?? '',\n type: metadata.type ?? '',\n shortName: metadata.shortName ?? '',\n integration: metadata.integration ?? ''\n }\n}\n\nexport function registerMetricsTool(\n server: McpServer,\n metricsV1Api: v1.MetricsApi,\n metricsV2Api: v2.MetricsApi,\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'metrics',\n `Query Datadog metrics. Actions:\n- query: Get timeseries data (requires from/to time range, PromQL query)\n- search: Find metrics by name (grep-like, NO time param needed)\n- list: Get recently active metrics (last 24h, optionally filter by tag)\n- metadata: Get metric details (unit, type, description)\n\nAPM METRICS (auto-generated from traces):\n- trace.{service}.hits - Request count\n- trace.{service}.errors - Error count\n- trace.{service}.duration - Latency (use avg:, p95:, max:)\nExample: max:trace.{service}.request.duration{*}`,\n InputSchema,\n async ({ action, query, from, to, metric, limit }) => {\n try {\n switch (action) {\n case 'query': {\n const metricsQuery = requireParam(query, 'query', 'query')\n return toolResult(\n await queryMetrics(\n metricsV1Api,\n {\n query: metricsQuery,\n from,\n to\n },\n limits,\n site\n )\n )\n }\n\n case 'search': {\n const searchQuery = requireParam(query, 'query', 'search')\n return toolResult(\n await searchMetrics(\n metricsV1Api,\n {\n query: searchQuery,\n limit\n },\n limits\n )\n )\n }\n\n case 'list':\n return toolResult(await listMetrics(metricsV1Api, { query }, limits))\n\n case 'metadata': {\n const metricName = requireParam(metric, 'metric', 'metadata')\n return toolResult(await getMetricMetadata(metricsV1Api, metricName))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport {\n hoursAgo,\n now,\n parseTime,\n ensureValidTimeRange,\n parseDurationToNs,\n formatDurationNs\n} from '../utils/time.js'\nimport { buildTracesUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['search', 'aggregate', 'services'])\n\n// Reserved span facets that should NOT be prefixed with @\nconst RESERVED_SPAN_FACETS = new Set([\n 'service',\n 'resource_name',\n 'operation_name',\n 'span_name',\n 'status',\n 'env',\n 'host',\n 'type',\n 'duration',\n 'trace_id',\n 'span_id'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe(\n 'APM trace search query (Datadog syntax). Example: \"@http.status_code:500\", \"service:my-service status:error\"'\n ),\n from: z\n .string()\n .optional()\n .describe(\n 'Start time. Formats: ISO 8601, relative (30s, 15m, 2h, 7d), precise (3d@11:45:23, yesterday@14:00)'\n ),\n to: z\n .string()\n .optional()\n .describe('End time. Same formats as \"from\". Example: from=\"3d@11:45\" to=\"3d@12:55\"'),\n service: z\n .string()\n .optional()\n .describe('Filter by service name. Example: \"my-service\", \"postgres\"'),\n operation: z\n .string()\n .optional()\n .describe('Filter by operation name. Example: \"express.request\", \"mongodb.query\"'),\n resource: z\n .string()\n .optional()\n .describe(\n 'Filter by resource name (endpoint/query). Supports wildcards. Example: \"GET /api/*\", \"*orders*\"'\n ),\n status: z\n .enum(['ok', 'error'])\n .optional()\n .describe('Filter by span status - \"ok\" for successful, \"error\" for failed spans'),\n env: z.string().optional().describe('Filter by environment. Example: \"production\", \"staging\"'),\n minDuration: z\n .string()\n .optional()\n .describe('Minimum span duration (find slow spans). Examples: \"1s\", \"500ms\", \"100ms\"'),\n maxDuration: z.string().optional().describe('Maximum span duration. Examples: \"5s\", \"1000ms\"'),\n httpStatus: z\n .string()\n .optional()\n .describe(\n 'HTTP status code filter. Examples: \"500\", \"5xx\" (500-599), \"4xx\" (400-499), \">=400\"'\n ),\n errorType: z\n .string()\n .optional()\n .describe('Filter by error type (grep-like). Example: \"TimeoutError\", \"ConnectionRefused\"'),\n errorMessage: z\n .string()\n .optional()\n .describe('Filter by error message (grep-like). Example: \"timeout\", \"connection refused\"'),\n limit: z.number().optional().describe('Maximum number of results'),\n sort: z.enum(['timestamp', '-timestamp']).optional().describe('Sort order'),\n groupBy: z\n .array(z.string())\n .optional()\n .describe('Fields to group by (for aggregate). Example: [\"resource_name\", \"status\"]')\n}\n\ninterface SpanSummary {\n traceId: string\n spanId: string\n service: string\n resource: string\n operation: string\n type: string\n status: string\n duration: string\n durationNs: number\n http: {\n statusCode: string\n method: string\n url: string\n }\n error: {\n type: string\n message: string\n }\n env: string\n tags: string[]\n}\n\n// SDK types are incomplete - extend with actual API response fields\ninterface SpanAttributesExtended {\n tags?: string[]\n attributes?: Record<string, unknown>\n custom?: {\n error?: Record<string, unknown>\n [key: string]: unknown\n }\n error?: Record<string, unknown>\n status?: string\n operationName?: string\n startTimestamp?: Date\n endTimestamp?: Date\n traceId?: string\n spanId?: string\n service?: string\n resourceName?: string\n type?: string\n env?: string\n [key: string]: unknown\n}\n\nexport function formatSpan(span: v2.Span): SpanSummary {\n // SDK types are incomplete - actual API returns more fields than typed\n // Using SpanAttributesExtended to access real API fields: error, status, operationName\n const attrs = (span.attributes ?? {}) as SpanAttributesExtended\n const tags = (attrs.tags as string[]) ?? []\n const nestedAttrs = (attrs.attributes ?? {}) as Record<string, unknown>\n const custom = (attrs.custom ?? {}) as Record<string, unknown>\n const attrsError = (attrs.error ?? {}) as Record<string, unknown>\n const customError = (custom.error ?? {}) as Record<string, unknown>\n\n // Extract common tags into a map\n const tagMap: Record<string, string> = {}\n for (const tag of tags) {\n const [key, value] = tag.split(':')\n if (key && value) tagMap[key] = value\n }\n\n // Calculate duration from timestamps or get from nested attributes\n let durationNs = 0\n if (attrs.startTimestamp && attrs.endTimestamp) {\n const startMs = attrs.startTimestamp.getTime()\n const endMs = attrs.endTimestamp.getTime()\n durationNs = (endMs - startMs) * 1_000_000 // ms to ns\n } else if (typeof nestedAttrs['duration'] === 'number') {\n durationNs = nestedAttrs['duration']\n } else if (typeof custom['duration'] === 'number') {\n durationNs = custom['duration']\n }\n\n // Get status - prioritize direct attrs field, then custom, then tags\n const status = (attrs.status as string) ?? (custom['status'] as string) ?? tagMap['status'] ?? ''\n\n return {\n traceId: attrs.traceId ?? '',\n spanId: attrs.spanId ?? '',\n service: attrs.service ?? '',\n resource: attrs.resourceName ?? '',\n operation: (attrs.operationName as string) ?? (custom['operation_name'] as string) ?? '',\n type: attrs.type ?? '',\n status,\n duration: formatDurationNs(durationNs),\n durationNs,\n http: {\n statusCode: tagMap['http.status_code'] ?? '',\n method: tagMap['http.method'] ?? '',\n url: tagMap['http.url'] ?? ''\n },\n error: {\n type:\n (attrsError['type'] as string) ??\n (customError['type'] as string) ??\n tagMap['error.type'] ??\n '',\n message:\n (customError['message'] as string) ?? tagMap['error.message'] ?? tagMap['error.msg'] ?? ''\n },\n env: attrs.env ?? tagMap['env'] ?? '',\n tags\n }\n}\n\n/**\n * Build HTTP status code filter string for trace query\n * Handles ranges (5xx), comparisons (>=500), and exact values (404)\n */\nfunction buildHttpStatusFilter(httpStatus: string): string {\n const status = httpStatus.toLowerCase()\n\n if (status.endsWith('xx')) {\n const base = Number.parseInt(status[0] ?? '0', 10) * 100\n return `@http.status_code:[${base} TO ${base + 99}]`\n }\n if (status.startsWith('>=')) return `@http.status_code:>=${status.slice(2)}`\n if (status.startsWith('>')) return `@http.status_code:>${status.slice(1)}`\n if (status.startsWith('<=')) return `@http.status_code:<=${status.slice(2)}`\n if (status.startsWith('<')) return `@http.status_code:<${status.slice(1)}`\n\n return `@http.status_code:${httpStatus}`\n}\n\n/**\n * Build a Datadog APM trace query from filter parameters\n */\nexport function buildTraceQuery(params: {\n query?: string\n service?: string\n operation?: string\n resource?: string\n status?: 'ok' | 'error'\n env?: string\n minDuration?: string\n maxDuration?: string\n httpStatus?: string\n errorType?: string\n errorMessage?: string\n}): string {\n const parts: string[] = []\n\n // Base query\n if (params.query) {\n parts.push(params.query)\n }\n\n // Service filter\n if (params.service) {\n parts.push(`service:${params.service}`)\n }\n\n // Operation name filter\n if (params.operation) {\n parts.push(`operation_name:${params.operation}`)\n }\n\n // Resource name filter (endpoint/query name)\n if (params.resource) {\n parts.push(`resource_name:${params.resource}`)\n }\n\n // Span status filter (ok/error)\n if (params.status) {\n parts.push(`status:${params.status}`)\n }\n\n // Environment filter\n if (params.env) {\n parts.push(`env:${params.env}`)\n }\n\n // Duration filters (convert to nanoseconds)\n if (params.minDuration) {\n const ns = parseDurationToNs(params.minDuration)\n if (ns !== undefined) {\n parts.push(`@duration:>=${ns}`)\n }\n }\n if (params.maxDuration) {\n const ns = parseDurationToNs(params.maxDuration)\n if (ns !== undefined) {\n parts.push(`@duration:<=${ns}`)\n }\n }\n\n // HTTP status code filter\n if (params.httpStatus) {\n parts.push(buildHttpStatusFilter(params.httpStatus))\n }\n\n // Error type grep (wildcard search)\n if (params.errorType) {\n const escaped = params.errorType.replace(/\"/g, '\\\\\"')\n parts.push(`error.type:*${escaped}*`)\n }\n\n // Error message grep (wildcard search)\n if (params.errorMessage) {\n const escaped = params.errorMessage.replace(/\"/g, '\\\\\"')\n parts.push(`error.message:*${escaped}*`)\n }\n\n return parts.length > 0 ? parts.join(' ') : '*'\n}\n\nexport async function searchTraces(\n api: v2.SpansApi,\n params: {\n query?: string\n from?: string\n to?: string\n service?: string\n operation?: string\n resource?: string\n status?: 'ok' | 'error'\n env?: string\n minDuration?: string\n maxDuration?: string\n httpStatus?: string\n errorType?: string\n errorMessage?: string\n limit?: number\n sort?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Build query from all filter params\n const fullQuery = buildTraceQuery({\n query: params.query,\n service: params.service,\n operation: params.operation,\n resource: params.resource,\n status: params.status,\n env: params.env,\n minDuration: params.minDuration,\n maxDuration: params.maxDuration,\n httpStatus: params.httpStatus,\n errorType: params.errorType,\n errorMessage: params.errorMessage\n })\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const body: v2.SpansListRequest = {\n data: {\n type: 'search_request',\n attributes: {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: params.sort === 'timestamp' ? 'timestamp' : '-timestamp',\n page: {\n limit: Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n }\n }\n }\n }\n\n const response = await api.listSpans({ body })\n const spans = (response.data ?? []).map(formatSpan)\n\n return {\n spans,\n meta: {\n count: spans.length,\n query: fullQuery,\n from: fromTime,\n to: toTime,\n datadog_url: buildTracesUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\nexport async function aggregateTraces(\n api: v2.SpansApi,\n params: {\n query?: string\n from?: string\n to?: string\n service?: string\n operation?: string\n resource?: string\n status?: 'ok' | 'error'\n env?: string\n minDuration?: string\n maxDuration?: string\n httpStatus?: string\n errorType?: string\n errorMessage?: string\n groupBy?: string[]\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n // Build query from all filter params\n const fullQuery = buildTraceQuery({\n query: params.query,\n service: params.service,\n operation: params.operation,\n resource: params.resource,\n status: params.status,\n env: params.env,\n minDuration: params.minDuration,\n maxDuration: params.maxDuration,\n httpStatus: params.httpStatus,\n errorType: params.errorType,\n errorMessage: params.errorMessage\n })\n\n // Parse and validate time range (ensures from < to)\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n // Use raw object structure to avoid TypeScript SDK type issues\n // Note: sort is omitted from group_by as it causes API validation errors\n const body = {\n data: {\n type: 'aggregate_request',\n attributes: {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n compute: [{ aggregation: 'count', type: 'total' }],\n groupBy: params.groupBy?.map((field) => ({\n facet: RESERVED_SPAN_FACETS.has(field) || field.startsWith('@') ? field : `@${field}`,\n limit: 10\n }))\n }\n }\n } as v2.SpansAggregateRequest\n\n const response = await api.aggregateSpans({ body })\n\n return {\n data: response.data ?? [],\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n groupBy: params.groupBy,\n datadog_url: buildTracesUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\nexport async function listApmServices(\n api: v2.SpansApi,\n params: { env?: string; from?: string; to?: string },\n limits: LimitsConfig\n) {\n const defaultFrom = hoursAgo(24) // Look back 24 hours for services\n const defaultTo = now()\n\n // Parse and validate time range\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n // Build query - env filter is optional\n const query = params.env ? `env:${params.env}` : '*'\n\n // Aggregate spans by service name to discover APM services\n // Use raw object structure to avoid TypeScript SDK type issues\n // Note: sort is omitted as it causes API validation errors\n const body = {\n data: {\n type: 'aggregate_request',\n attributes: {\n filter: {\n query,\n from: fromTime,\n to: toTime\n },\n compute: [{ aggregation: 'count', type: 'total' }],\n groupBy: [\n {\n facet: 'service',\n limit: limits.maxResults\n }\n ]\n }\n }\n } as v2.SpansAggregateRequest\n\n const response = await api.aggregateSpans({ body })\n\n // Extract service names from aggregation buckets\n // SDK types define 'computes' but API returns 'compute' (singular)\n const buckets = (response.data ?? []) as Array<{\n attributes?: {\n by?: Record<string, string>\n compute?: Record<string, number>\n }\n }>\n\n const services = buckets\n .map((bucket) => ({\n name: bucket.attributes?.by?.['service'] ?? '',\n spanCount: bucket.attributes?.compute?.['c0'] ?? 0\n }))\n .filter((s) => s.name !== '')\n\n return {\n services,\n total: services.length,\n meta: {\n query,\n env: params.env ?? 'all',\n from: fromTime,\n to: toTime\n }\n }\n}\n\nexport function registerTracesTool(\n server: McpServer,\n spansApi: v2.SpansApi,\n _servicesApi: v2.ServiceDefinitionApi, // Keep for backward compatibility, not used\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'traces',\n `Analyze APM traces for request flow and latency debugging. Actions: search (find spans), aggregate (group stats), services (list APM services). Key filters: minDuration/maxDuration (\"500ms\", \"2s\"), httpStatus (\"5xx\", \">=400\"), status (ok/error), errorMessage (grep).\nAPM METRICS: Traces auto-generate metrics in trace.{service}.* namespace. Use metrics tool to query: avg:trace.{service}.request.duration{*}`,\n InputSchema,\n async ({\n action,\n query,\n from,\n to,\n service,\n operation,\n resource,\n status,\n env,\n minDuration,\n maxDuration,\n httpStatus,\n errorType,\n errorMessage,\n limit,\n sort,\n groupBy\n }) => {\n try {\n switch (action) {\n case 'search': {\n return toolResult(\n await searchTraces(\n spansApi,\n {\n query,\n from,\n to,\n service,\n operation,\n resource,\n status,\n env,\n minDuration,\n maxDuration,\n httpStatus,\n errorType,\n errorMessage,\n limit,\n sort\n },\n limits,\n site\n )\n )\n }\n\n case 'aggregate': {\n return toolResult(\n await aggregateTraces(\n spansApi,\n {\n query,\n from,\n to,\n service,\n operation,\n resource,\n status,\n env,\n minDuration,\n maxDuration,\n httpStatus,\n errorType,\n errorMessage,\n groupBy\n },\n limits,\n site\n )\n )\n }\n\n case 'services':\n return toolResult(await listApmServices(spansApi, { env, from, to }, limits))\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1, v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { hoursAgo, now, parseTime, ensureValidTimeRange, parseDurationToNs } from '../utils/time.js'\nimport { buildEventsUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum([\n 'list',\n 'get',\n 'create',\n 'search',\n 'aggregate',\n 'top',\n 'timeseries',\n 'incidents'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Event ID (for get action)'),\n query: z.string().optional().describe('Search query'),\n from: z\n .string()\n .optional()\n .describe('Start time (ISO 8601, relative like \"1h\", or Unix timestamp)'),\n to: z.string().optional().describe('End time (ISO 8601, relative like \"1h\", or Unix timestamp)'),\n priority: z.enum(['normal', 'low']).optional().describe('Event priority'),\n sources: z.array(z.string()).optional().describe('Filter by sources'),\n tags: z.array(z.string()).optional().describe('Filter by tags'),\n limit: z.number().optional().describe('Maximum number of events to return'),\n title: z.string().optional().describe('Event title (for create)'),\n text: z.string().optional().describe('Event text (for create)'),\n alertType: z\n .enum(['error', 'warning', 'info', 'success'])\n .optional()\n .describe('Alert type (for create)'),\n groupBy: z\n .array(z.string())\n .optional()\n .describe('Fields to group by: monitor_name, priority, alert_type, source'),\n cursor: z.string().optional().describe('Pagination cursor from previous response'),\n // Phase 2: Timeseries\n interval: z\n .string()\n .optional()\n .describe('Time bucket interval for timeseries: 1h, 4h, 1d (default: 1h)'),\n // Phase 2: Incidents deduplication\n dedupeWindow: z\n .string()\n .optional()\n .describe('Deduplication window for incidents: 5m, 15m, 1h (default: 5m)'),\n // Phase 3: Monitor enrichment\n enrich: z\n .boolean()\n .optional()\n .describe('Enrich events with monitor metadata (slower, adds monitor details)')\n}\n\n// v1 Event summary format\ninterface EventSummaryV1 {\n id: number\n title: string\n text: string\n dateHappened: string\n priority: string\n source: string\n tags: string[]\n alertType: string\n host: string\n}\n\n// v2 Event summary format\ninterface EventSummaryV2 {\n id: string\n title: string\n message: string\n timestamp: string\n priority: string\n source: string\n tags: string[]\n alertType: string\n host: string\n monitorId?: number\n monitorInfo?: {\n name: string\n status: string\n scope: string\n priority?: string\n }\n}\n\n// Aggregation bucket format\ninterface AggregationBucket {\n key: string\n count: number\n sample: EventSummaryV2\n}\n\n// Timeseries bucket format (Phase 2)\ninterface TimeseriesBucket {\n timestamp: string\n timestampMs: number\n counts: Record<string, number>\n total: number\n}\n\n// Incident format (Phase 2 - deduplicated events)\ninterface IncidentEvent {\n monitorName: string\n firstTrigger: string\n lastTrigger: string\n triggerCount: number\n recovered: boolean\n recoveredAt?: string\n duration?: string\n sample: EventSummaryV2\n}\n\n// Enriched event with monitor metadata (Phase 3)\ninterface EnrichedEvent extends EventSummaryV2 {\n monitorMetadata?: {\n id: number\n type: string\n message: string\n tags: string[]\n options?: {\n thresholds?: Record<string, number>\n notifyNoData?: boolean\n escalationMessage?: string\n }\n }\n}\n\n/**\n * Extract monitor information from alert event title\n * Handles patterns like:\n * - [Triggered on {scope}] Monitor Name\n * - [P1] [Triggered on {scope}] Monitor Name\n * - [Warn on {scope}] Monitor Name\n * - [Recovered on {scope}] Monitor Name\n */\nexport function extractMonitorInfo(title: string): {\n status: string\n scope: string\n name: string\n priority?: string\n} {\n // Extract priority prefix if present\n const priorityMatch = title.match(/^\\[P(\\d+)\\]\\s*/)\n const priority = priorityMatch ? `P${priorityMatch[1]}` : undefined\n const withoutPriority = title.replace(/^\\[P\\d+\\]\\s*/, '')\n\n // Extract status, scope, and name\n // NOSONAR S5852: Anchored pattern with no nested quantifiers, input is bounded Datadog event titles\n const match = withoutPriority.match(\n /^\\[(Triggered|Recovered|Warn|Alert|OK|No Data|Re-Triggered|Renotify)(?:\\s+on\\s+\\{([^}]+)\\})?\\]\\s*(.+)$/i\n )\n\n if (match) {\n return {\n status: match[1] ?? '',\n scope: match[2] ?? '',\n name: match[3]?.trim() ?? title,\n priority\n }\n }\n\n return { status: '', scope: '', name: title, priority }\n}\n\n/**\n * Extract title/monitor name from v2 event message body\n * v2 API returns empty title, but message contains the alert text\n * Format: \"%%%\\nMonitor title here\\n\\n...\"\n */\nexport function extractTitleFromMessage(message: string): string {\n if (!message) return ''\n\n // Remove %%% markdown delimiter if present\n const content = message.replace(/^%%%\\s*\\n?/, '').trim()\n\n // Get first line (up to first newline)\n const firstLine = content.split('\\n')[0]?.trim() ?? ''\n\n // Clean up common trailing patterns like \" !\" or extra whitespace\n // NOSONAR S5852: Simplified pattern, .trim() handles whitespace\n return firstLine.replace(/\\s*!?\\s*$/, '').trim()\n}\n\n/**\n * Extract monitor ID from v2 event message body\n * Messages contain links like: [[Monitor Status](/monitors/67860480?...)]\n */\nexport function extractMonitorIdFromMessage(message: string): number | undefined {\n if (!message) return undefined\n\n // Match /monitors/{id} pattern in the message\n const match = message.match(/\\/monitors\\/(\\d+)/)\n if (match?.[1]) {\n const id = Number.parseInt(match[1], 10)\n return Number.isNaN(id) ? undefined : id\n }\n\n return undefined\n}\n\n/**\n * Build a group key for aggregation based on the event and groupBy fields\n */\nexport function buildGroupKey(event: EventSummaryV2, groupBy: string[]): string {\n const parts: string[] = []\n\n for (const field of groupBy) {\n switch (field) {\n case 'monitor_name':\n parts.push(event.monitorInfo?.name ?? event.title)\n break\n case 'monitor_id':\n parts.push(event.monitorId?.toString() ?? '')\n break\n case 'priority':\n parts.push(event.monitorInfo?.priority ?? event.priority)\n break\n case 'source':\n parts.push(event.source)\n break\n case 'alert_type':\n parts.push(event.alertType)\n break\n case 'status':\n parts.push(event.monitorInfo?.status ?? '')\n break\n case 'host':\n parts.push(event.host)\n break\n default: {\n // For unknown fields, try to find in tags\n const tagValue = event.tags.find((t) => t.startsWith(`${field}:`))?.split(':')[1] ?? ''\n parts.push(tagValue)\n }\n }\n }\n\n return parts.join('|')\n}\n\nexport function formatEventV1(e: v1.Event): EventSummaryV1 {\n const event = e as v1.Event & { sourceTypeName?: string }\n return {\n id: e.id ?? 0,\n title: e.title ?? '',\n text: e.text ?? '',\n dateHappened: e.dateHappened ? new Date(e.dateHappened * 1000).toISOString() : '',\n priority: String(e.priority ?? 'normal'),\n source: event.sourceTypeName ?? '',\n tags: e.tags ?? [],\n alertType: String(e.alertType ?? 'info'),\n host: e.host ?? ''\n }\n}\n\nexport function formatEventV2(e: v2.EventResponse): EventSummaryV2 {\n const attrs = e.attributes ?? {}\n\n // Parse timestamp\n let timestamp = ''\n if (attrs.timestamp) {\n const ts = attrs.timestamp\n timestamp = ts instanceof Date ? ts.toISOString() : new Date(String(ts)).toISOString()\n }\n\n const message = (attrs.message as string) ?? ''\n\n // v2 API often returns empty title - extract from message body instead\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let title = ((attrs as any).title as string) ?? ''\n if (!title && message) {\n title = extractTitleFromMessage(message)\n }\n\n const monitorInfo = extractMonitorInfo(title)\n const monitorId = extractMonitorIdFromMessage(message)\n\n // Extract source from tags or attributes\n const tags = (attrs.tags as string[]) ?? []\n const sourceTag = tags.find((t) => t.startsWith('source:'))\n const source = sourceTag?.split(':')[1] ?? ''\n\n // Extract alert_type from tags\n const alertTypeTag = tags.find((t) => t.startsWith('alert_type:'))\n const alertType = alertTypeTag?.split(':')[1] ?? ''\n\n // Extract host from tags\n const hostTag = tags.find((t) => t.startsWith('host:'))\n const host = hostTag?.split(':')[1] ?? ''\n\n // Extract priority from tags\n const priorityTag = tags.find((t) => t.startsWith('priority:'))\n const priority = priorityTag?.split(':')[1] ?? 'normal'\n\n return {\n id: String(e.id ?? ''),\n title,\n message,\n timestamp,\n priority,\n source,\n tags,\n alertType,\n host,\n monitorId,\n monitorInfo:\n monitorInfo.name !== title\n ? {\n name: monitorInfo.name,\n status: monitorInfo.status,\n scope: monitorInfo.scope,\n priority: monitorInfo.priority\n }\n : undefined\n }\n}\n\n// ============ V1 API Functions (backward compatible) ============\n\nexport async function listEventsV1(\n api: v1.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n priority?: 'normal' | 'low'\n sources?: string[]\n tags?: string[]\n limit?: number\n },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.defaultLimit, limits.maxResults)\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const response = await api.listEvents({\n start: parseTime(params.from, defaultFrom),\n end: parseTime(params.to, defaultTo),\n priority: params.priority === 'low' ? 'low' : 'normal',\n sources: params.sources?.join(','),\n tags: params.tags?.join(','),\n unaggregated: true\n })\n\n let events = response.events ?? []\n\n // Client-side query filter\n if (params.query) {\n const lowerQuery = params.query.toLowerCase()\n events = events.filter(\n (e) =>\n e.title?.toLowerCase().includes(lowerQuery) || e.text?.toLowerCase().includes(lowerQuery)\n )\n }\n\n const result = events.slice(0, effectiveLimit).map(formatEventV1)\n\n return {\n events: result,\n total: events.length\n }\n}\n\nexport async function getEventV1(api: v1.EventsApi, id: string) {\n const eventId = Number.parseInt(id, 10)\n if (Number.isNaN(eventId)) {\n throw new Error(`Invalid event ID: ${id}`)\n }\n\n const response = await api.getEvent({ eventId })\n return { event: formatEventV1(response.event ?? {}) }\n}\n\nexport async function createEventV1(\n api: v1.EventsApi,\n params: {\n title: string\n text: string\n priority?: 'normal' | 'low'\n tags?: string[]\n alertType?: 'error' | 'warning' | 'info' | 'success'\n }\n) {\n const body: v1.EventCreateRequest = {\n title: params.title,\n text: params.text,\n priority: params.priority === 'low' ? 'low' : 'normal',\n tags: params.tags,\n alertType: params.alertType ?? 'info'\n }\n\n const response = await api.createEvent({ body })\n\n return {\n success: true,\n event: {\n id: response.event?.id ?? 0,\n title: response.event?.title ?? '',\n status: response.status ?? ''\n }\n }\n}\n\n// ============ V2 API Functions (new capabilities) ============\n\n/**\n * Build a Datadog event search query from filter parameters\n */\nexport function buildEventQuery(params: {\n query?: string\n sources?: string[]\n tags?: string[]\n priority?: string\n}): string {\n const parts: string[] = []\n\n if (params.query) {\n parts.push(params.query)\n }\n\n if (params.sources && params.sources.length > 0) {\n const sourceFilter = params.sources.map((s) => `source:${s}`).join(' OR ')\n parts.push(`(${sourceFilter})`)\n }\n\n if (params.tags && params.tags.length > 0) {\n for (const tag of params.tags) {\n parts.push(tag)\n }\n }\n\n if (params.priority) {\n parts.push(`priority:${params.priority}`)\n }\n\n return parts.length > 0 ? parts.join(' ') : '*'\n}\n\nexport async function searchEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n priority?: string\n limit?: number\n cursor?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query,\n sources: params.sources,\n tags: params.tags,\n priority: params.priority\n })\n\n const effectiveLimit = Math.min(params.limit ?? limits.defaultLimit, limits.maxResults)\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: {\n limit: effectiveLimit,\n cursor: params.cursor\n }\n }\n\n const response = await api.searchEvents({ body })\n\n const events = (response.data ?? []).map(formatEventV2)\n const nextCursor = response.meta?.page?.after\n\n return {\n events,\n meta: {\n count: events.length,\n query: fullQuery,\n from: fromTime,\n to: toTime,\n nextCursor,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n/**\n * Client-side aggregation for events\n * Streams through all matching events and counts by group key\n */\nexport async function aggregateEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n groupBy?: string[]\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n const counts = new Map<string, { count: number; sample: EventSummaryV2 }>()\n\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query,\n sources: params.sources,\n tags: params.tags\n })\n\n const groupByFields = params.groupBy ?? ['monitor_name']\n\n // Use pagination to stream through all events\n // Limit to maxEventsToAggregate to prevent runaway queries\n const maxEventsToAggregate = 10000\n let eventCount = 0\n let pageCount = 0\n const maxPages = 100\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: {\n limit: 1000 // Max per page\n }\n }\n\n // Manual pagination since searchEventsWithPagination may not be available\n let cursor: string | undefined\n\n while (pageCount < maxPages && eventCount < maxEventsToAggregate) {\n const pageBody = { ...body, page: { ...body.page, cursor } }\n const response = await api.searchEvents({ body: pageBody })\n\n const events = response.data ?? []\n if (events.length === 0) break\n\n for (const event of events) {\n const formatted = formatEventV2(event)\n const groupKey = buildGroupKey(formatted, groupByFields)\n\n const existing = counts.get(groupKey)\n if (existing) {\n existing.count++\n } else {\n counts.set(groupKey, { count: 1, sample: formatted })\n }\n\n eventCount++\n if (eventCount >= maxEventsToAggregate) break\n }\n\n cursor = response.meta?.page?.after\n if (!cursor) break\n pageCount++\n }\n\n // Sort by count descending, apply limit\n const effectiveLimit = Math.min(params.limit ?? 100, 1000)\n const sorted = [...counts.entries()]\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, effectiveLimit)\n\n const buckets: AggregationBucket[] = sorted.map(([key, data]) => ({\n key,\n count: data.count,\n sample: data.sample\n }))\n\n return {\n buckets,\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n groupBy: groupByFields,\n totalGroups: counts.size,\n totalEvents: eventCount,\n truncated: eventCount >= maxEventsToAggregate,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n/**\n * Top N events by count - convenience wrapper for aggregate\n * Direct answer to \"which monitors triggered the most alerts\"\n */\nexport async function topEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n groupBy?: string[]\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n // Default to source:alert for alert-related queries\n const effectiveQuery = params.query ?? 'source:alert'\n const effectiveTags = params.tags ?? ['source:alert']\n\n const result = await aggregateEventsV2(\n api,\n {\n ...params,\n query: effectiveQuery,\n tags: effectiveTags,\n groupBy: params.groupBy ?? ['monitor_name'],\n limit: params.limit ?? 10\n },\n limits,\n site\n )\n\n // Format for easier consumption\n return {\n top: result.buckets.map((bucket, index) => ({\n rank: index + 1,\n name: bucket.key,\n monitorId: bucket.sample.monitorId,\n alertCount: bucket.count,\n lastAlert: bucket.sample.timestamp,\n sample: {\n title: bucket.sample.title,\n source: bucket.sample.source,\n alertType: bucket.sample.alertType\n }\n })),\n meta: result.meta\n }\n}\n\n// ============ Phase 2: Timeseries Action ============\n\n/**\n * Parse interval string to milliseconds\n * Supports: 1h, 4h, 1d, 15m, etc.\n */\nexport function parseIntervalToMs(interval: string | undefined): number {\n const ns = parseDurationToNs(interval ?? '1h')\n return ns ? Math.floor(ns / 1000000) : 3600000 // default 1h\n}\n\n/**\n * Time-bucketed alert trends\n * Buckets events by time interval and groups by specified fields\n */\nexport async function timeseriesEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n groupBy?: string[]\n interval?: string\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query ?? 'source:alert',\n sources: params.sources,\n tags: params.tags\n })\n\n const intervalMs = parseIntervalToMs(params.interval)\n const groupByFields = params.groupBy ?? ['monitor_name']\n\n // Map: bucketTs -> groupKey -> count\n const timeBuckets = new Map<number, Map<string, number>>()\n\n const maxEventsToProcess = 10000\n let eventCount = 0\n let pageCount = 0\n const maxPages = 100\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: { limit: 1000 }\n }\n\n let cursor: string | undefined\n\n while (pageCount < maxPages && eventCount < maxEventsToProcess) {\n const pageBody = { ...body, page: { ...body.page, cursor } }\n const response = await api.searchEvents({ body: pageBody })\n\n const events = response.data ?? []\n if (events.length === 0) break\n\n for (const event of events) {\n const formatted = formatEventV2(event)\n const groupKey = buildGroupKey(formatted, groupByFields)\n\n // Parse timestamp and bucket it\n const eventTs = new Date(formatted.timestamp).getTime()\n const bucketTs = Math.floor(eventTs / intervalMs) * intervalMs\n\n if (!timeBuckets.has(bucketTs)) {\n timeBuckets.set(bucketTs, new Map())\n }\n const groupCounts = timeBuckets.get(bucketTs)!\n groupCounts.set(groupKey, (groupCounts.get(groupKey) ?? 0) + 1)\n\n eventCount++\n if (eventCount >= maxEventsToProcess) break\n }\n\n cursor = response.meta?.page?.after\n if (!cursor) break\n pageCount++\n }\n\n // Convert to sorted array of buckets\n const sortedBuckets = [...timeBuckets.entries()]\n .sort((a, b) => a[0] - b[0])\n .map(([bucketTs, groupCounts]) => {\n const counts: Record<string, number> = {}\n let total = 0\n for (const [key, count] of groupCounts) {\n counts[key] = count\n total += count\n }\n return {\n timestamp: new Date(bucketTs).toISOString(),\n timestampMs: bucketTs,\n counts,\n total\n } satisfies TimeseriesBucket\n })\n\n // Apply limit to buckets if specified\n const effectiveLimit = params.limit ?? 100\n const limitedBuckets = sortedBuckets.slice(0, effectiveLimit)\n\n return {\n timeseries: limitedBuckets,\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n interval: params.interval ?? '1h',\n intervalMs,\n groupBy: groupByFields,\n totalBuckets: sortedBuckets.length,\n totalEvents: eventCount,\n truncated: eventCount >= maxEventsToProcess,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n// ============ Phase 2: Incidents Action (Deduplication) ============\n\n/**\n * Deduplicate alert events into incidents\n * Groups Triggered events within a time window, pairs with Recovered events\n */\nexport async function incidentsEventsV2(\n api: v2.EventsApi,\n params: {\n query?: string\n from?: string\n to?: string\n sources?: string[]\n tags?: string[]\n dedupeWindow?: string\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n const defaultFrom = hoursAgo(limits.defaultTimeRangeHours)\n const defaultTo = now()\n\n const [validFrom, validTo] = ensureValidTimeRange(\n parseTime(params.from, defaultFrom),\n parseTime(params.to, defaultTo)\n )\n const fromTime = new Date(validFrom * 1000).toISOString()\n const toTime = new Date(validTo * 1000).toISOString()\n\n const fullQuery = buildEventQuery({\n query: params.query ?? 'source:alert',\n sources: params.sources,\n tags: params.tags\n })\n\n // Parse dedupe window (default 5 minutes)\n const dedupeWindowNs = parseDurationToNs(params.dedupeWindow ?? '5m')\n const dedupeWindowMs = dedupeWindowNs ? Math.floor(dedupeWindowNs / 1000000) : 300000\n\n // Track incidents per monitor\n interface IncidentTracker {\n monitorName: string\n firstTrigger: Date\n lastTrigger: Date\n triggerCount: number\n recovered: boolean\n recoveredAt?: Date\n sample: EventSummaryV2\n }\n const incidents = new Map<string, IncidentTracker>()\n\n const maxEventsToProcess = 10000\n let eventCount = 0\n let pageCount = 0\n const maxPages = 100\n\n const body: v2.EventsListRequest = {\n filter: {\n query: fullQuery,\n from: fromTime,\n to: toTime\n },\n sort: 'timestamp' as v2.EventsSort,\n page: { limit: 1000 }\n }\n\n let cursor: string | undefined\n\n while (pageCount < maxPages && eventCount < maxEventsToProcess) {\n const pageBody = { ...body, page: { ...body.page, cursor } }\n const response = await api.searchEvents({ body: pageBody })\n\n const events = response.data ?? []\n if (events.length === 0) break\n\n for (const event of events) {\n const formatted = formatEventV2(event)\n\n // Use monitorInfo.name if available, otherwise fall back to title\n const monitorName = formatted.monitorInfo?.name ?? formatted.title\n if (!monitorName) {\n eventCount++\n continue\n }\n\n const eventTs = new Date(formatted.timestamp)\n\n // Derive status from monitorInfo, alertType, or message content for v2 events\n let status = formatted.monitorInfo?.status?.toLowerCase() ?? ''\n if (!status && formatted.alertType) {\n // Map alertType to status for v2 events without structured monitorInfo\n const alertType = formatted.alertType.toLowerCase()\n if (alertType === 'error' || alertType === 'warning') {\n status = 'triggered'\n } else if (alertType === 'success') {\n status = 'recovered'\n }\n }\n // For source:alert events without explicit status, check message for recovery indicators\n // or default to 'triggered' since alert events are triggers by nature\n if (!status && formatted.source === 'alert') {\n const msgLower = formatted.message.toLowerCase()\n if (\n msgLower.includes('recovered') ||\n msgLower.includes('[ok]') ||\n msgLower.includes('resolved')\n ) {\n status = 'recovered'\n } else {\n status = 'triggered'\n }\n }\n\n const existing = incidents.get(monitorName)\n\n if (\n status === 'triggered' ||\n status === 'alert' ||\n status === 're-triggered' ||\n status === 'renotify'\n ) {\n if (existing) {\n // Check if within dedupe window\n const timeSinceLastTrigger = eventTs.getTime() - existing.lastTrigger.getTime()\n if (timeSinceLastTrigger <= dedupeWindowMs) {\n // Same incident, update\n existing.lastTrigger = eventTs\n existing.triggerCount++\n existing.sample = formatted // Keep latest sample\n } else {\n // New incident for this monitor, close old one\n // Store the old one with a unique key\n const oldKey = `${monitorName}::${existing.firstTrigger.toISOString()}`\n incidents.set(oldKey, existing)\n\n // Start new incident\n incidents.set(monitorName, {\n monitorName,\n firstTrigger: eventTs,\n lastTrigger: eventTs,\n triggerCount: 1,\n recovered: false,\n sample: formatted\n })\n }\n } else {\n // First trigger for this monitor\n incidents.set(monitorName, {\n monitorName,\n firstTrigger: eventTs,\n lastTrigger: eventTs,\n triggerCount: 1,\n recovered: false,\n sample: formatted\n })\n }\n } else if (status === 'recovered' || status === 'ok') {\n if (existing && !existing.recovered) {\n existing.recovered = true\n existing.recoveredAt = eventTs\n }\n }\n\n eventCount++\n if (eventCount >= maxEventsToProcess) break\n }\n\n cursor = response.meta?.page?.after\n if (!cursor) break\n pageCount++\n }\n\n // Convert to array and calculate durations\n const incidentList: IncidentEvent[] = [...incidents.values()].map((inc) => {\n let duration: string | undefined\n if (inc.recoveredAt) {\n const durationMs = inc.recoveredAt.getTime() - inc.firstTrigger.getTime()\n if (durationMs < 60000) {\n duration = `${Math.round(durationMs / 1000)}s`\n } else if (durationMs < 3600000) {\n duration = `${Math.round(durationMs / 60000)}m`\n } else {\n duration = `${(durationMs / 3600000).toFixed(1)}h`\n }\n }\n\n return {\n monitorName: inc.monitorName,\n firstTrigger: inc.firstTrigger.toISOString(),\n lastTrigger: inc.lastTrigger.toISOString(),\n triggerCount: inc.triggerCount,\n recovered: inc.recovered,\n recoveredAt: inc.recoveredAt?.toISOString(),\n duration,\n sample: inc.sample\n }\n })\n\n // Sort by first trigger descending, apply limit\n incidentList.sort(\n (a, b) => new Date(b.firstTrigger).getTime() - new Date(a.firstTrigger).getTime()\n )\n const effectiveLimit = Math.min(params.limit ?? 100, 500)\n\n return {\n incidents: incidentList.slice(0, effectiveLimit),\n meta: {\n query: fullQuery,\n from: fromTime,\n to: toTime,\n dedupeWindow: params.dedupeWindow ?? '5m',\n dedupeWindowMs,\n totalIncidents: incidentList.length,\n totalEvents: eventCount,\n recoveredCount: incidentList.filter((i) => i.recovered).length,\n activeCount: incidentList.filter((i) => !i.recovered).length,\n truncated: eventCount >= maxEventsToProcess,\n datadog_url: buildEventsUrl(fullQuery, validFrom, validTo, site)\n }\n }\n}\n\n// ============ Phase 3: Monitor Metadata Enrichment ============\n\n/**\n * Enrich events with monitor metadata from the Monitors API\n */\nexport async function enrichWithMonitorMetadata(\n events: EventSummaryV2[],\n monitorsApi: v1.MonitorsApi\n): Promise<EnrichedEvent[]> {\n // Extract unique monitor names\n const monitorNames = new Set<string>()\n for (const event of events) {\n if (event.monitorInfo?.name) {\n monitorNames.add(event.monitorInfo.name)\n }\n }\n\n if (monitorNames.size === 0) {\n return events as EnrichedEvent[]\n }\n\n // Fetch monitors - search by name\n const monitorCache = new Map<string, v1.Monitor>()\n\n try {\n // Fetch all monitors and filter locally\n // The API doesn't support searching by exact name, so we need to filter\n const response = await monitorsApi.listMonitors({\n pageSize: 1000\n })\n\n const monitors = response ?? []\n for (const monitor of monitors) {\n if (monitor.name) {\n monitorCache.set(monitor.name, monitor)\n }\n }\n } catch {\n // If monitor fetch fails, return events without enrichment\n return events as EnrichedEvent[]\n }\n\n // Enrich events\n return events.map((event) => {\n const enriched: EnrichedEvent = { ...event }\n\n if (event.monitorInfo?.name) {\n const monitor = monitorCache.get(event.monitorInfo.name)\n if (monitor) {\n enriched.monitorMetadata = {\n id: monitor.id ?? 0,\n type: String(monitor.type ?? ''),\n message: monitor.message ?? '',\n tags: monitor.tags ?? [],\n options: {\n thresholds: monitor.options?.thresholds as Record<string, number> | undefined,\n notifyNoData: monitor.options?.notifyNoData,\n escalationMessage: monitor.options?.escalationMessage\n }\n }\n }\n }\n\n return enriched\n })\n}\n\nexport function registerEventsTool(\n server: McpServer,\n apiV1: v1.EventsApi,\n apiV2: v2.EventsApi,\n monitorsApi: v1.MonitorsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'events',\n `Track Datadog events. Actions: list, get, create, search, aggregate, top, timeseries, incidents.\nIMPORTANT: For monitor alert history, use tags: [\"source:alert\"] to find all triggered monitors.\nFilters: query (text search), sources, tags, priority, time range.\nUse for: monitor alerts, deployments, incidents, change tracking.\n\nUse action:\"top\" with from:\"7d\" to find the noisiest monitors.\nUse action:\"aggregate\" with groupBy:[\"monitor_name\"] for alert counts per monitor.\nUse action:\"timeseries\" with interval:\"1h\" to see alert trends over time.\nUse action:\"incidents\" with dedupeWindow:\"5m\" to deduplicate alerts into incidents.\nUse enrich:true with search to get monitor metadata (slower).`,\n InputSchema,\n async ({\n action,\n id,\n query,\n from,\n to,\n priority,\n sources,\n tags,\n limit,\n title,\n text,\n alertType,\n groupBy,\n cursor,\n interval,\n dedupeWindow,\n enrich\n }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listEventsV1(\n apiV1,\n {\n query,\n from,\n to,\n priority,\n sources,\n tags,\n limit\n },\n limits\n )\n )\n\n case 'get': {\n const eventId = requireParam(id, 'id', 'get')\n return toolResult(await getEventV1(apiV1, eventId))\n }\n\n case 'create': {\n const eventTitle = requireParam(title, 'title', 'create')\n const eventText = requireParam(text, 'text', 'create')\n return toolResult(\n await createEventV1(apiV1, {\n title: eventTitle,\n text: eventText,\n priority,\n tags,\n alertType\n })\n )\n }\n\n case 'search': {\n const result = await searchEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n priority,\n limit,\n cursor\n },\n limits,\n site\n )\n\n // Phase 3: Optional enrichment\n if (enrich && result.events.length > 0) {\n const enrichedEvents = await enrichWithMonitorMetadata(result.events, monitorsApi)\n return toolResult({ ...result, events: enrichedEvents })\n }\n\n return toolResult(result)\n }\n\n case 'aggregate':\n return toolResult(\n await aggregateEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n groupBy,\n limit\n },\n limits,\n site\n )\n )\n\n case 'top':\n return toolResult(\n await topEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n groupBy,\n limit\n },\n limits,\n site\n )\n )\n\n case 'timeseries':\n return toolResult(\n await timeseriesEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n groupBy,\n interval,\n limit\n },\n limits,\n site\n )\n )\n\n case 'incidents':\n return toolResult(\n await incidentsEventsV2(\n apiV2,\n {\n query,\n from,\n to,\n sources,\n tags,\n dedupeWindow,\n limit\n },\n limits,\n site\n )\n )\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'search', 'create', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Incident ID (required for get/update/delete)'),\n query: z.string().optional().describe('Search query (for search action)'),\n status: z\n .enum(['active', 'stable', 'resolved'])\n .optional()\n .describe('Filter by status (for list)'),\n limit: z.number().optional().describe('Maximum number of incidents to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe(\n 'Incident configuration (for create/update). Create requires: title. Update can modify: title, status, severity, fields.'\n )\n}\n\ninterface IncidentSummary {\n id: string\n title: string\n status: string\n severity: string | null\n state: string | null\n customerImpactScope: string | null\n customerImpacted: boolean\n commander: {\n name: string | null\n email: string | null\n handle: string | null\n }\n createdAt: string\n modifiedAt: string\n resolvedAt: string | null\n timeToDetect: number | null\n timeToRepair: number | null\n}\n\nexport function formatIncident(i: v2.IncidentResponseData): IncidentSummary {\n const attrs = i.attributes\n const commander = i.relationships?.commanderUser?.data\n return {\n id: i.id ?? '',\n title: attrs?.title ?? '',\n status: String(attrs?.state ?? 'unknown'),\n severity: attrs?.severity ? String(attrs.severity) : null,\n state: attrs?.state ? String(attrs.state) : null,\n customerImpactScope: attrs?.customerImpactScope ?? null,\n customerImpacted: attrs?.customerImpacted ?? false,\n commander: {\n name: null, // Would need to resolve from relationships\n email: null,\n handle: commander?.id ?? null\n },\n createdAt: attrs?.created ? new Date(attrs.created).toISOString() : '',\n modifiedAt: attrs?.modified ? new Date(attrs.modified).toISOString() : '',\n resolvedAt: attrs?.resolved ? new Date(attrs.resolved).toISOString() : null,\n timeToDetect: attrs?.timeToDetect ?? null,\n timeToRepair: attrs?.timeToRepair ?? null\n }\n}\n\nexport async function listIncidents(\n api: v2.IncidentsApi,\n params: { status?: 'active' | 'stable' | 'resolved'; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n // Note: listIncidents is an unstable operation that requires enablement\n const response = await api.listIncidents({\n pageSize: effectiveLimit\n })\n\n let incidents = (response.data ?? []).map(formatIncident)\n\n // Filter by status client-side if specified\n if (params.status) {\n incidents = incidents.filter((i) => i.state?.toLowerCase() === params.status)\n }\n\n // Apply limit after filtering (in case status filter reduced count)\n incidents = incidents.slice(0, effectiveLimit)\n\n return {\n incidents,\n total: incidents.length\n }\n}\n\nexport async function getIncident(api: v2.IncidentsApi, id: string) {\n const response = await api.getIncident({ incidentId: id })\n return {\n incident: response.data ? formatIncident(response.data) : null\n }\n}\n\nexport async function searchIncidents(api: v2.IncidentsApi, query: string, limits: LimitsConfig) {\n const response = await api.searchIncidents({\n query,\n pageSize: limits.maxResults\n })\n\n const incidents = (response.data?.attributes?.incidents ?? []).map(\n (i: v2.IncidentSearchResponseIncidentsData) => ({\n id: i.data?.id ?? '',\n title: i.data?.attributes?.title ?? '',\n state: i.data?.attributes?.state ?? 'unknown'\n })\n )\n\n return {\n incidents,\n total: response.data?.attributes?.total ?? incidents.length\n }\n}\n\nexport async function createIncident(api: v2.IncidentsApi, config: Record<string, unknown>) {\n const body = {\n data: {\n type: 'incidents' as const,\n attributes: config\n }\n } as unknown as v2.IncidentCreateRequest\n\n const response = await api.createIncident({ body })\n return {\n success: true,\n incident: response.data ? formatIncident(response.data) : null\n }\n}\n\nexport async function updateIncident(\n api: v2.IncidentsApi,\n id: string,\n config: Record<string, unknown>\n) {\n const body = {\n data: {\n type: 'incidents' as const,\n id,\n attributes: config\n }\n } as unknown as v2.IncidentUpdateRequest\n\n const response = await api.updateIncident({ incidentId: id, body })\n return {\n success: true,\n incident: response.data ? formatIncident(response.data) : null\n }\n}\n\nexport async function deleteIncident(api: v2.IncidentsApi, id: string) {\n await api.deleteIncident({ incidentId: id })\n return {\n success: true,\n message: `Incident ${id} deleted`\n }\n}\n\nexport function registerIncidentsTool(\n server: McpServer,\n api: v2.IncidentsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'incidents',\n 'Manage Datadog incidents for incident response. Actions: list, get, search, create, update, delete. Use for: incident management, on-call response, postmortems, tracking MTTR/MTTD.',\n InputSchema,\n async ({ action, id, query, status, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listIncidents(api, { status, limit }, limits))\n\n case 'get': {\n const incidentId = requireParam(id, 'id', 'get')\n return toolResult(await getIncident(api, incidentId))\n }\n\n case 'search': {\n const searchQuery = requireParam(query, 'query', 'search')\n return toolResult(await searchIncidents(api, searchQuery, limits))\n }\n\n case 'create': {\n const incidentConfig = requireParam(config, 'config', 'create')\n return toolResult(await createIncident(api, incidentConfig))\n }\n\n case 'update': {\n const incidentId = requireParam(id, 'id', 'update')\n const incidentConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateIncident(api, incidentId, incidentConfig))\n }\n\n case 'delete': {\n const incidentId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteIncident(api, incidentId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime, ensureValidTimeRange } from '../utils/time.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete', 'history'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('SLO ID (required for get/update/delete/history)'),\n ids: z.array(z.string()).optional().describe('Multiple SLO IDs (for list with specific IDs)'),\n query: z.string().optional().describe('Search query (for list)'),\n tags: z.array(z.string()).optional().describe('Filter by tags (for list)'),\n limit: z.number().optional().describe('Maximum number of SLOs to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe('SLO configuration (for create/update). Must include type, name, thresholds.'),\n from: z\n .string()\n .optional()\n .describe('Start time for history (ISO 8601 or relative like \"7d\", \"1w\")'),\n to: z.string().optional().describe('End time for history (ISO 8601 or relative, default: now)')\n}\n\ninterface SloSummary {\n id: string\n name: string\n description: string | null\n type: string\n targetThreshold: number\n warningThreshold: number | null\n timeframe: string\n tags: string[]\n status: {\n sli: number | null\n errorBudgetRemaining: number | null\n state: string\n }\n createdAt: string\n modifiedAt: string\n}\n\nexport function formatSlo(s: v1.ServiceLevelObjective | v1.SLOResponseData): SloSummary {\n const primaryThreshold = s.thresholds?.[0]\n return {\n id: s.id ?? '',\n name: s.name ?? '',\n description: s.description ?? null,\n type: String(s.type ?? 'unknown'),\n targetThreshold: primaryThreshold?.target ?? 0,\n warningThreshold: primaryThreshold?.warning ?? null,\n timeframe: String(primaryThreshold?.timeframe ?? ''),\n tags: s.tags ?? [],\n status: {\n // Note: SLI status requires a separate API call to getSLOHistory\n sli: null,\n errorBudgetRemaining: null,\n state: 'unknown'\n },\n createdAt: s.createdAt ? new Date(s.createdAt * 1000).toISOString() : '',\n modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1000).toISOString() : ''\n }\n}\n\nexport async function listSlos(\n api: v1.ServiceLevelObjectivesApi,\n params: { ids?: string[]; query?: string; tags?: string[]; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listSLOs({\n ids: params.ids?.join(','),\n query: params.query,\n tagsQuery: params.tags?.join(','),\n limit: effectiveLimit\n })\n\n const slos = (response.data ?? []).map(formatSlo)\n\n return {\n slos,\n total: response.data?.length ?? 0\n }\n}\n\nexport async function getSlo(api: v1.ServiceLevelObjectivesApi, id: string) {\n const response = await api.getSLO({ sloId: id })\n return {\n slo: response.data ? formatSlo(response.data) : null\n }\n}\n\n/**\n * Recursively convert snake_case keys to camelCase\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())\n}\n\nexport function normalizeConfigKeys(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj\n if (Array.isArray(obj)) return obj.map(normalizeConfigKeys)\n if (typeof obj !== 'object') return obj\n\n const normalized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const camelKey = snakeToCamel(key)\n normalized[camelKey] = normalizeConfigKeys(value)\n }\n return normalized\n}\n\n/**\n * Normalize SLO config to handle snake_case -> camelCase\n */\nexport function normalizeSloConfig(config: Record<string, unknown>): Record<string, unknown> {\n const normalized = normalizeConfigKeys(config) as Record<string, unknown>\n\n // Validate required fields\n if (!normalized.name) {\n throw new Error(\"SLO config requires 'name' field\")\n }\n if (!normalized.type) {\n throw new Error(\"SLO config requires 'type' field (e.g., 'metric', 'monitor')\")\n }\n if (!normalized.thresholds || !Array.isArray(normalized.thresholds)) {\n throw new Error(\"SLO config requires 'thresholds' array with at least one threshold\")\n }\n\n return normalized\n}\n\nexport async function createSlo(\n api: v1.ServiceLevelObjectivesApi,\n config: Record<string, unknown>\n) {\n const body = normalizeSloConfig(config) as unknown as v1.ServiceLevelObjectiveRequest\n const response = await api.createSLO({ body })\n return {\n success: true,\n slo: response.data?.[0] ? formatSlo(response.data[0]) : null\n }\n}\n\nexport async function updateSlo(\n api: v1.ServiceLevelObjectivesApi,\n id: string,\n config: Record<string, unknown>\n) {\n const body = normalizeConfigKeys(config) as unknown as v1.ServiceLevelObjective\n const response = await api.updateSLO({ sloId: id, body })\n return {\n success: true,\n slo: response.data?.[0] ? formatSlo(response.data[0]) : null\n }\n}\n\nexport async function deleteSlo(api: v1.ServiceLevelObjectivesApi, id: string) {\n await api.deleteSLO({ sloId: id })\n return {\n success: true,\n message: `SLO ${id} deleted`\n }\n}\n\nexport async function getSloHistory(\n api: v1.ServiceLevelObjectivesApi,\n id: string,\n params: { from?: string; to?: string }\n) {\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 7 * 24 * 60 * 60 * 1000 // Default 7 days\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000)) * 1000\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000)) * 1000\n\n const [validFrom, validTo] = ensureValidTimeRange(fromTime, toTime)\n\n const response = await api.getSLOHistory({\n sloId: id,\n fromTs: Math.floor(validFrom / 1000),\n toTs: Math.floor(validTo / 1000)\n })\n\n const data = response.data\n return {\n history: {\n overall: {\n sliValue: data?.overall?.sliValue ?? null,\n spanPrecision: data?.overall?.spanPrecision ?? null,\n uptime: data?.overall?.uptime ?? null\n },\n series: {\n numerator: data?.series?.numerator?.values ?? [],\n denominator: data?.series?.denominator?.values ?? [],\n times: data?.series?.times ?? []\n },\n thresholds: data?.thresholds ?? {},\n fromTs: new Date(validFrom).toISOString(),\n toTs: new Date(validTo).toISOString()\n }\n }\n}\n\nexport function registerSlosTool(\n server: McpServer,\n api: v1.ServiceLevelObjectivesApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'slos',\n 'Manage Datadog Service Level Objectives. Actions: list, get, create, update, delete, history. SLO types: metric-based, monitor-based. Use for: reliability tracking, error budgets, SLA compliance, performance targets.',\n InputSchema,\n async ({ action, id, ids, query, tags, limit, config, from, to }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listSlos(api, { ids, query, tags, limit }, limits))\n\n case 'get': {\n const sloId = requireParam(id, 'id', 'get')\n return toolResult(await getSlo(api, sloId))\n }\n\n case 'create': {\n const sloConfig = requireParam(config, 'config', 'create')\n return toolResult(await createSlo(api, sloConfig))\n }\n\n case 'update': {\n const sloId = requireParam(id, 'id', 'update')\n const sloConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateSlo(api, sloId, sloConfig))\n }\n\n case 'delete': {\n const sloId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteSlo(api, sloId))\n }\n\n case 'history': {\n const sloId = requireParam(id, 'id', 'history')\n return toolResult(await getSloHistory(api, sloId, { from, to }))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete', 'trigger', 'results'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z\n .string()\n .optional()\n .describe('Test public ID (required for get/update/delete/trigger/results)'),\n ids: z.array(z.string()).optional().describe('Multiple test IDs (for bulk trigger)'),\n testType: z\n .enum(['api', 'browser'])\n .optional()\n .describe('Test type filter (for list) or type for create'),\n locations: z.array(z.string()).optional().describe('Filter by locations (for list)'),\n tags: z.array(z.string()).optional().describe('Filter by tags (for list)'),\n limit: z.number().optional().describe('Maximum number of tests to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe(\n 'Test configuration (for create/update). Includes: name, type, config, options, locations, message.'\n )\n}\n\ninterface SyntheticTestSummary {\n publicId: string\n name: string\n type: string\n subtype: string | null\n status: string\n message: string\n tags: string[]\n locations: string[]\n monitorId: number | null\n}\n\nexport function formatTest(t: v1.SyntheticsTestDetails): SyntheticTestSummary {\n return {\n publicId: t.publicId ?? '',\n name: t.name ?? '',\n type: String(t.type ?? 'unknown'),\n subtype: t.subtype ? String(t.subtype) : null,\n status: String(t.status ?? 'unknown'),\n message: t.message ?? '',\n tags: t.tags ?? [],\n locations: t.locations ?? [],\n monitorId: t.monitorId ?? null\n }\n}\n\nexport async function listTests(\n api: v1.SyntheticsApi,\n params: { locations?: string[]; tags?: string[]; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n // Note: listTests API only accepts pageSize/pageNumber, filtering done client-side\n const response = await api.listTests({\n pageSize: effectiveLimit\n })\n\n let tests = (response.tests ?? []).map(formatTest)\n\n // Client-side filtering by tags\n if (params.tags && params.tags.length > 0) {\n tests = tests.filter((t) => params.tags!.some((tag) => t.tags.includes(tag)))\n }\n\n // Client-side filtering by locations\n if (params.locations && params.locations.length > 0) {\n tests = tests.filter((t) => params.locations!.some((loc) => t.locations.includes(loc)))\n }\n\n tests = tests.slice(0, effectiveLimit)\n\n const summary = {\n total: response.tests?.length ?? 0,\n api: tests.filter((t) => t.type === 'api').length,\n browser: tests.filter((t) => t.type === 'browser').length,\n passing: tests.filter((t) => t.status === 'OK' || t.status === 'live').length,\n failing: tests.filter((t) => t.status === 'Alert').length\n }\n\n return { tests, summary }\n}\n\nexport async function getTest(api: v1.SyntheticsApi, id: string) {\n // Try API test first, then browser\n try {\n const response = await api.getAPITest({ publicId: id })\n return { test: formatTest(response) }\n } catch {\n const response = await api.getBrowserTest({ publicId: id })\n return { test: formatTest(response) }\n }\n}\n\n/**\n * Recursively convert snake_case keys to camelCase in an object\n */\nexport function snakeToCamel(str: string): string {\n return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())\n}\n\nexport function normalizeConfigKeys(obj: unknown): unknown {\n if (obj === null || obj === undefined) return obj\n if (Array.isArray(obj)) return obj.map(normalizeConfigKeys)\n if (typeof obj !== 'object') return obj\n\n const normalized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n const camelKey = snakeToCamel(key)\n normalized[camelKey] = normalizeConfigKeys(value)\n }\n return normalized\n}\n\n/**\n * Normalize synthetics test config to handle snake_case -> camelCase\n */\nexport function normalizeSyntheticsConfig(\n config: Record<string, unknown>\n): Record<string, unknown> {\n // Recursively convert all snake_case keys to camelCase\n const normalized = normalizeConfigKeys(config) as Record<string, unknown>\n\n // Validate required fields\n if (!normalized.name) {\n throw new Error(\"Synthetics test config requires 'name' field\")\n }\n if (\n !normalized.locations ||\n !Array.isArray(normalized.locations) ||\n normalized.locations.length === 0\n ) {\n throw new Error(\"Synthetics test config requires 'locations' array (e.g., ['aws:us-east-1'])\")\n }\n\n return normalized\n}\n\nexport async function createTest(\n api: v1.SyntheticsApi,\n config: Record<string, unknown>,\n testType?: 'api' | 'browser'\n) {\n const normalizedConfig = normalizeSyntheticsConfig(config)\n const type = testType ?? (normalizedConfig.type === 'browser' ? 'browser' : 'api')\n\n if (type === 'browser') {\n const body = normalizedConfig as unknown as v1.SyntheticsBrowserTest\n const response = await api.createSyntheticsBrowserTest({ body })\n return {\n success: true,\n test: formatTest(response)\n }\n } else {\n const body = normalizedConfig as unknown as v1.SyntheticsAPITest\n const response = await api.createSyntheticsAPITest({ body })\n return {\n success: true,\n test: formatTest(response)\n }\n }\n}\n\nexport async function updateTest(\n api: v1.SyntheticsApi,\n id: string,\n config: Record<string, unknown>\n) {\n // Normalize config first\n const normalizedConfig = normalizeConfigKeys(config) as Record<string, unknown>\n\n // Determine test type by fetching it first\n let testType: 'api' | 'browser'\n try {\n await api.getAPITest({ publicId: id })\n testType = 'api'\n } catch {\n testType = 'browser'\n }\n\n if (testType === 'browser') {\n const body = normalizedConfig as unknown as v1.SyntheticsBrowserTest\n const response = await api.updateBrowserTest({ publicId: id, body })\n return {\n success: true,\n test: formatTest(response)\n }\n } else {\n const body = normalizedConfig as unknown as v1.SyntheticsAPITest\n const response = await api.updateAPITest({ publicId: id, body })\n return {\n success: true,\n test: formatTest(response)\n }\n }\n}\n\nexport async function deleteTests(api: v1.SyntheticsApi, ids: string[]) {\n await api.deleteTests({\n body: { publicIds: ids }\n })\n return {\n success: true,\n message: `Deleted ${ids.length} test(s): ${ids.join(', ')}`\n }\n}\n\nexport async function triggerTests(api: v1.SyntheticsApi, ids: string[]) {\n const response = await api.triggerTests({\n body: {\n tests: ids.map((id) => ({ publicId: id }))\n }\n })\n\n const results =\n response.results?.map((r) => ({\n publicId: r.publicId ?? '',\n resultId: r.resultId ?? '',\n triggered: true\n })) ?? []\n\n return {\n triggered: results,\n total: results.length\n }\n}\n\nexport async function getTestResults(api: v1.SyntheticsApi, id: string) {\n // Try API test results first, then browser\n try {\n const response = await api.getAPITestLatestResults({ publicId: id })\n const results = (response.results ?? []).map((r) => ({\n resultId: r.resultId ?? '',\n status: r.result?.passed ? 'passed' : 'failed',\n checkTime: r.checkTime ? new Date(r.checkTime * 1000).toISOString() : '',\n responseTime: r.result?.timings?.total ?? null\n }))\n return { results, testType: 'api' }\n } catch {\n const response = await api.getBrowserTestLatestResults({ publicId: id })\n const results = (response.results ?? []).map((r) => ({\n resultId: r.resultId ?? '',\n // Browser tests don't have 'passed' - determine from errorCount\n status: (r.result?.errorCount ?? 0) === 0 ? 'passed' : 'failed',\n checkTime: r.checkTime ? new Date(r.checkTime * 1000).toISOString() : '',\n duration: r.result?.duration ?? null\n }))\n return { results, testType: 'browser' }\n }\n}\n\nexport function registerSyntheticsTool(\n server: McpServer,\n api: v1.SyntheticsApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'synthetics',\n 'Manage Datadog Synthetic tests (API and Browser). Actions: list, get, create, update, delete, trigger, results. Use for: uptime monitoring, API testing, user journey testing, performance testing, canary deployments.',\n InputSchema,\n async ({ action, id, ids, testType, locations, tags, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listTests(api, { locations, tags, limit }, limits))\n\n case 'get': {\n const testId = requireParam(id, 'id', 'get')\n return toolResult(await getTest(api, testId))\n }\n\n case 'create': {\n const testConfig = requireParam(config, 'config', 'create')\n return toolResult(await createTest(api, testConfig, testType))\n }\n\n case 'update': {\n const testId = requireParam(id, 'id', 'update')\n const testConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateTest(api, testId, testConfig))\n }\n\n case 'delete': {\n const testIds = ids ?? (id ? [id] : undefined)\n const deleteIds = requireParam(testIds, 'id or ids', 'delete')\n return toolResult(await deleteTests(api, deleteIds))\n }\n\n case 'trigger': {\n const testIds = ids ?? (id ? [id] : undefined)\n const triggerIds = requireParam(testIds, 'id or ids', 'trigger')\n return toolResult(await triggerTests(api, triggerIds))\n }\n\n case 'results': {\n const testId = requireParam(id, 'id', 'results')\n return toolResult(await getTestResults(api, testId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'totals', 'mute', 'unmute'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n filter: z.string().optional().describe('Filter hosts by name, alias, or tag (e.g., \"env:prod\")'),\n from: z.number().optional().describe('Starting offset for pagination'),\n count: z.number().optional().describe('Number of hosts to return'),\n sortField: z.string().optional().describe('Field to sort by (e.g., \"apps\", \"cpu\", \"name\")'),\n sortDir: z.enum(['asc', 'desc']).optional().describe('Sort direction'),\n hostName: z.string().optional().describe('Host name (required for mute/unmute)'),\n message: z.string().optional().describe('Mute reason message'),\n end: z.number().optional().describe('Mute end timestamp (POSIX). Omit for indefinite mute'),\n override: z.boolean().optional().describe('If true, replaces existing mute instead of failing')\n}\n\ninterface HostSummary {\n hostName: string\n aliases: string[]\n apps: string[]\n sources: string[]\n up: boolean\n isMuted: boolean\n muteTimeout: number | null\n lastReportedTime: string\n meta: {\n cpuCores: number | null\n platform: string | null\n gohai: string | null\n }\n}\n\nexport function formatHost(h: v1.Host): HostSummary {\n return {\n hostName: h.hostName ?? '',\n aliases: h.aliases ?? [],\n apps: h.apps ?? [],\n sources: h.sources ?? [],\n up: h.up ?? false,\n isMuted: h.isMuted ?? false,\n muteTimeout: h.muteTimeout ?? null,\n lastReportedTime: h.lastReportedTime ? new Date(h.lastReportedTime * 1000).toISOString() : '',\n meta: {\n cpuCores: h.meta?.cpuCores ?? null,\n platform: h.meta?.platform ?? null,\n gohai: h.meta?.gohai ?? null\n }\n }\n}\n\nexport async function listHosts(\n api: v1.HostsApi,\n params: {\n filter?: string\n from?: number\n count?: number\n sortField?: string\n sortDir?: 'asc' | 'desc'\n },\n limits: LimitsConfig\n) {\n const response = await api.listHosts({\n filter: params.filter,\n from: params.from,\n count: Math.min(params.count ?? limits.maxResults, limits.maxResults),\n sortField: params.sortField,\n sortDir: params.sortDir\n })\n\n const hosts = (response.hostList ?? []).map(formatHost)\n\n return {\n hosts,\n totalReturned: response.totalReturned ?? hosts.length,\n totalMatching: response.totalMatching ?? hosts.length\n }\n}\n\nexport async function getHostTotals(api: v1.HostsApi) {\n const response = await api.getHostTotals({})\n return {\n totals: {\n totalUp: response.totalUp ?? 0,\n totalActive: response.totalActive ?? 0\n }\n }\n}\n\nexport async function muteHost(\n api: v1.HostsApi,\n hostName: string,\n params: { message?: string; end?: number; override?: boolean }\n) {\n await api.muteHost({\n hostName,\n body: {\n message: params.message,\n end: params.end,\n override: params.override\n }\n })\n const muteEndMessage = params.end\n ? ` until ${new Date(params.end * 1000).toISOString()}`\n : ' indefinitely'\n return {\n success: true,\n message: `Host ${hostName} muted${muteEndMessage}`\n }\n}\n\nexport async function unmuteHost(api: v1.HostsApi, hostName: string) {\n await api.unmuteHost({ hostName })\n return {\n success: true,\n message: `Host ${hostName} unmuted`\n }\n}\n\nexport function registerHostsTool(\n server: McpServer,\n api: v1.HostsApi,\n limits: LimitsConfig,\n readOnly: boolean = false\n): void {\n server.tool(\n 'hosts',\n 'Manage Datadog infrastructure hosts. Actions: list (with filters), totals (counts), mute (silence alerts), unmute. Use for: infrastructure inventory, host health, silencing noisy hosts during maintenance.',\n InputSchema,\n async ({\n action,\n filter,\n from,\n count,\n sortField,\n sortDir,\n hostName,\n message,\n end,\n override\n }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listHosts(api, { filter, from, count, sortField, sortDir }, limits)\n )\n\n case 'totals':\n return toolResult(await getHostTotals(api))\n\n case 'mute': {\n const host = requireParam(hostName, 'hostName', 'mute')\n return toolResult(await muteHost(api, host, { message, end, override }))\n }\n\n case 'unmute': {\n const host = requireParam(hostName, 'hostName', 'unmute')\n return toolResult(await unmuteHost(api, host))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'cancel', 'listByMonitor'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Downtime ID (required for get/update/cancel)'),\n monitorId: z.number().optional().describe('Monitor ID (required for listByMonitor)'),\n currentOnly: z.boolean().optional().describe('Only return active downtimes (for list)'),\n limit: z.number().optional().describe('Maximum number of downtimes to return'),\n config: z\n .record(z.unknown())\n .optional()\n .describe('Downtime configuration (for create/update). Must include scope and schedule.')\n}\n\ninterface DowntimeSummary {\n id: string\n displayTimezone: string\n message: string | null\n monitorIdentifier: {\n monitorId: number | null\n monitorTags: string[]\n }\n scope: string\n status: string\n schedule: unknown\n createdAt: string\n modifiedAt: string\n}\n\nexport function extractMonitorIdentifier(mi?: v2.DowntimeMonitorIdentifier): {\n monitorId: number | null\n monitorTags: string[]\n} {\n if (!mi) return { monitorId: null, monitorTags: [] }\n\n // Check if it's a DowntimeMonitorIdentifierId (has monitorId property)\n if ('monitorId' in mi && typeof mi.monitorId === 'number') {\n return { monitorId: mi.monitorId, monitorTags: [] }\n }\n\n // Check if it's a DowntimeMonitorIdentifierTags (has monitorTags property)\n if ('monitorTags' in mi && Array.isArray(mi.monitorTags)) {\n return { monitorId: null, monitorTags: mi.monitorTags }\n }\n\n return { monitorId: null, monitorTags: [] }\n}\n\nexport function formatDowntime(d: v2.DowntimeResponseData): DowntimeSummary {\n const attrs = d.attributes\n const status = attrs?.status\n return {\n id: d.id ?? '',\n displayTimezone: attrs?.displayTimezone ?? 'UTC',\n message: attrs?.message ?? null,\n monitorIdentifier: extractMonitorIdentifier(attrs?.monitorIdentifier),\n scope: attrs?.scope ?? '',\n status: typeof status === 'string' ? status : 'unknown',\n schedule: attrs?.schedule ?? null,\n createdAt: attrs?.created ? new Date(attrs.created).toISOString() : '',\n modifiedAt: attrs?.modified ? new Date(attrs.modified).toISOString() : ''\n }\n}\n\nexport async function listDowntimes(\n api: v2.DowntimesApi,\n params: { currentOnly?: boolean; limit?: number },\n limits: LimitsConfig\n) {\n const effectiveLimit = Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n\n const response = await api.listDowntimes({\n currentOnly: params.currentOnly\n })\n\n const downtimes = (response.data ?? []).slice(0, effectiveLimit).map(formatDowntime)\n\n return {\n downtimes,\n total: response.data?.length ?? 0\n }\n}\n\nexport async function getDowntime(api: v2.DowntimesApi, id: string) {\n const response = await api.getDowntime({ downtimeId: id })\n return {\n downtime: response.data ? formatDowntime(response.data) : null\n }\n}\n\n/**\n * Normalize downtime config to handle property name conversion and date formatting\n * - Converts snake_case user input to camelCase for SDK compatibility\n * - One-time schedules: convert ISO strings to Date objects\n * - Recurring schedules: keep dates as strings\n */\nexport function normalizeDowntimeConfig(config: Record<string, unknown>): Record<string, unknown> {\n // Step 1: Convert top-level snake_case keys to camelCase\n // SDK expects camelCase internally and converts to snake_case for HTTP API\n const keyMapping: Record<string, string> = {\n monitor_identifier: 'monitorIdentifier',\n display_timezone: 'displayTimezone',\n mute_first_recovery_notification: 'muteFirstRecoveryNotification',\n notify_end_states: 'notifyEndStates',\n notify_end_types: 'notifyEndTypes'\n }\n\n const normalized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(config)) {\n const newKey = keyMapping[key] || key\n normalized[newKey] = value\n }\n\n // Step 2: Handle nested monitorIdentifier conversion (monitor_id → monitorId, monitor_tags → monitorTags)\n if (normalized.monitorIdentifier && typeof normalized.monitorIdentifier === 'object') {\n const mi = { ...(normalized.monitorIdentifier as Record<string, unknown>) }\n if ('monitor_id' in mi) {\n mi.monitorId = mi.monitor_id\n delete mi.monitor_id\n }\n if ('monitor_tags' in mi) {\n mi.monitorTags = mi.monitor_tags\n delete mi.monitor_tags\n }\n normalized.monitorIdentifier = mi\n }\n\n // Step 3: Handle schedule date conversions and timezone\n if (normalized.schedule && typeof normalized.schedule === 'object') {\n const schedule = { ...(normalized.schedule as Record<string, unknown>) }\n\n // Detect schedule type:\n // - Recurring if it has 'duration' and 'rrule' fields\n // - One-time otherwise\n const isRecurring = 'duration' in schedule && 'rrule' in schedule\n\n if (!isRecurring) {\n // One-time schedule: convert ISO string dates to Date objects\n if (schedule.start && typeof schedule.start === 'string') {\n schedule.start = new Date(schedule.start)\n }\n if (schedule.end && typeof schedule.end === 'string') {\n schedule.end = new Date(schedule.end)\n }\n\n // Move timezone to displayTimezone at top level if present in schedule\n if (schedule.timezone && !normalized.displayTimezone) {\n normalized.displayTimezone = schedule.timezone\n }\n // Remove timezone from one-time schedule (not a valid field)\n delete schedule.timezone\n }\n // For recurring schedules, keep dates as strings (no conversion needed)\n\n normalized.schedule = schedule\n }\n\n return normalized\n}\n\nexport async function createDowntime(api: v2.DowntimesApi, config: Record<string, unknown>) {\n const normalizedConfig = normalizeDowntimeConfig(config)\n const body = {\n data: {\n type: 'downtime' as const,\n attributes: normalizedConfig\n }\n } as unknown as v2.DowntimeCreateRequest\n\n const response = await api.createDowntime({ body })\n return {\n success: true,\n downtime: response.data ? formatDowntime(response.data) : null\n }\n}\n\nexport async function updateDowntime(\n api: v2.DowntimesApi,\n id: string,\n config: Record<string, unknown>\n) {\n const normalizedConfig = normalizeDowntimeConfig(config)\n const body = {\n data: {\n type: 'downtime' as const,\n id,\n attributes: normalizedConfig\n }\n } as unknown as v2.DowntimeUpdateRequest\n\n const response = await api.updateDowntime({ downtimeId: id, body })\n return {\n success: true,\n downtime: response.data ? formatDowntime(response.data) : null\n }\n}\n\nexport async function cancelDowntime(api: v2.DowntimesApi, id: string) {\n await api.cancelDowntime({ downtimeId: id })\n return {\n success: true,\n message: `Downtime ${id} cancelled`\n }\n}\n\ninterface MonitorDowntimeSummary {\n id: string\n scope: string | null\n start: string | null\n end: string | null\n}\n\nexport function formatMonitorDowntime(\n d: v2.MonitorDowntimeMatchResponseData\n): MonitorDowntimeSummary {\n const attrs = d.attributes\n return {\n id: d.id ?? '',\n scope: attrs?.scope ?? null,\n start: attrs?.start ? new Date(attrs.start).toISOString() : null,\n end: attrs?.end ? new Date(attrs.end).toISOString() : null\n }\n}\n\nexport async function listMonitorDowntimes(\n api: v2.DowntimesApi,\n monitorId: number,\n limits: LimitsConfig\n) {\n const response = await api.listMonitorDowntimes({ monitorId })\n const downtimes = (response.data ?? []).slice(0, limits.maxResults).map(formatMonitorDowntime)\n\n return {\n downtimes,\n monitorId,\n total: response.data?.length ?? 0\n }\n}\n\nexport function registerDowntimesTool(\n server: McpServer,\n api: v2.DowntimesApi,\n limits: LimitsConfig,\n readOnly: boolean = false\n): void {\n server.tool(\n 'downtimes',\n 'Manage Datadog scheduled downtimes for maintenance windows. Actions: list, get, create, update, cancel, listByMonitor. Use for: scheduling maintenance, preventing false alerts during deployments, managing recurring maintenance windows.',\n InputSchema,\n async ({ action, id, monitorId, currentOnly, limit, config }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listDowntimes(api, { currentOnly, limit }, limits))\n\n case 'get': {\n const downtimeId = requireParam(id, 'id', 'get')\n return toolResult(await getDowntime(api, downtimeId))\n }\n\n case 'create': {\n const downtimeConfig = requireParam(config, 'config', 'create')\n return toolResult(await createDowntime(api, downtimeConfig))\n }\n\n case 'update': {\n const downtimeId = requireParam(id, 'id', 'update')\n const downtimeConfig = requireParam(config, 'config', 'update')\n return toolResult(await updateDowntime(api, downtimeId, downtimeConfig))\n }\n\n case 'cancel': {\n const downtimeId = requireParam(id, 'id', 'cancel')\n return toolResult(await cancelDowntime(api, downtimeId))\n }\n\n case 'listByMonitor': {\n const monitor = requireParam(monitorId, 'monitorId', 'listByMonitor')\n return toolResult(await listMonitorDowntimes(api, monitor, limits))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime } from '../utils/time.js'\nimport { buildRumUrl, buildRumSessionUrl } from '../utils/urls.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['applications', 'events', 'aggregate', 'performance', 'waterfall'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n query: z\n .string()\n .optional()\n .describe('RUM query string (e.g., \"@type:view @application.id:abc\")'),\n from: z\n .string()\n .optional()\n .describe('Start time (ISO 8601, relative like \"1h\", \"7d\", or precise like \"1d@10:00\")'),\n to: z\n .string()\n .optional()\n .describe('End time (ISO 8601, relative like \"now\", or precise timestamp)'),\n type: z\n .enum(['all', 'view', 'action', 'error', 'long_task', 'resource'])\n .optional()\n .describe('RUM event type filter'),\n sort: z.enum(['timestamp', '-timestamp']).optional().describe('Sort order for events'),\n limit: z.number().optional().describe('Maximum number of events to return'),\n groupBy: z\n .array(z.string())\n .optional()\n .describe('Fields to group by for aggregation (e.g., [\"@view.url_path\", \"@session.type\"])'),\n compute: z\n .object({\n aggregation: z\n .enum(['count', 'cardinality', 'avg', 'sum', 'min', 'max', 'percentile'])\n .optional(),\n metric: z.string().optional(),\n interval: z.string().optional()\n })\n .optional()\n .describe('Compute configuration for aggregation'),\n // Performance action parameters\n metrics: z\n .array(z.enum(['lcp', 'fcp', 'cls', 'fid', 'inp', 'loading_time']))\n .optional()\n .describe(\n 'Core Web Vitals metrics to retrieve (default: all). lcp=Largest Contentful Paint, fcp=First Contentful Paint, cls=Cumulative Layout Shift, fid=First Input Delay, inp=Interaction to Next Paint, loading_time=View loading time'\n ),\n // Waterfall action parameters\n applicationId: z.string().optional().describe('Application ID for waterfall action'),\n sessionId: z.string().optional().describe('Session ID for waterfall action'),\n viewId: z\n .string()\n .optional()\n .describe('View ID for waterfall action (optional, filters to specific view)')\n}\n\ninterface RumApplicationSummary {\n id: string\n name: string\n type: string\n orgId: number\n hash: string | null\n createdAt: string\n updatedAt: string\n}\n\ninterface RumEventSummary {\n id: string\n type: string\n timestamp: string\n attributes: {\n application: {\n id: string | null\n name: string | null\n }\n session: {\n id: string | null\n type: string | null\n }\n view: {\n id: string | null\n url: string | null\n urlPath: string | null\n name: string | null\n }\n user: {\n id: string | null\n email: string | null\n name: string | null\n }\n action?: {\n id: string | null\n type: string | null\n name: string | null\n }\n error?: {\n message: string | null\n source: string | null\n stack: string | null\n }\n resource?: {\n url: string | null\n type: string | null\n duration: number | null\n }\n }\n}\n\nexport function formatApplication(app: v2.RUMApplicationList): RumApplicationSummary {\n const attrs = app.attributes ?? {}\n\n return {\n id: app.id ?? '',\n name: attrs.name ?? '',\n type: String(attrs.type ?? ''),\n orgId: attrs.orgId ?? 0,\n hash: attrs.hash ?? null,\n createdAt: attrs.createdAt ? new Date(attrs.createdAt).toISOString() : '',\n updatedAt: attrs.updatedAt ? new Date(attrs.updatedAt).toISOString() : ''\n }\n}\n\nexport function formatEvent(event: v2.RUMEvent): RumEventSummary {\n const attrs = event.attributes ?? {}\n const appAttrs = (attrs.attributes ?? {}) as Record<string, unknown>\n\n // Extract nested attributes safely\n const application = (appAttrs['application'] ?? {}) as Record<string, unknown>\n const session = (appAttrs['session'] ?? {}) as Record<string, unknown>\n const view = (appAttrs['view'] ?? {}) as Record<string, unknown>\n const usr = (appAttrs['usr'] ?? {}) as Record<string, unknown>\n const action = (appAttrs['action'] ?? {}) as Record<string, unknown>\n const error = (appAttrs['error'] ?? {}) as Record<string, unknown>\n const resource = (appAttrs['resource'] ?? {}) as Record<string, unknown>\n\n return {\n id: event.id ?? '',\n type: String(event.type ?? ''),\n timestamp: attrs.timestamp?.toISOString() ?? '',\n attributes: {\n application: {\n id: (application['id'] as string) ?? null,\n name: (application['name'] as string) ?? null\n },\n session: {\n id: (session['id'] as string) ?? null,\n type: (session['type'] as string) ?? null\n },\n view: {\n id: (view['id'] as string) ?? null,\n url: (view['url'] as string) ?? null,\n urlPath: (view['url_path'] as string) ?? null,\n name: (view['name'] as string) ?? null\n },\n user: {\n id: (usr['id'] as string) ?? null,\n email: (usr['email'] as string) ?? null,\n name: (usr['name'] as string) ?? null\n },\n action: action['id']\n ? {\n id: (action['id'] as string) ?? null,\n type: (action['type'] as string) ?? null,\n name: (action['name'] as string) ?? null\n }\n : undefined,\n error: error['message']\n ? {\n message: (error['message'] as string) ?? null,\n source: (error['source'] as string) ?? null,\n stack: (error['stack'] as string) ?? null\n }\n : undefined,\n resource: resource['url']\n ? {\n url: (resource['url'] as string) ?? null,\n type: (resource['type'] as string) ?? null,\n duration: (resource['duration'] as number) ?? null\n }\n : undefined\n }\n }\n}\n\nexport async function listApplications(api: v2.RUMApi) {\n const response = await api.getRUMApplications()\n const applications = (response.data ?? []).map(formatApplication)\n\n return {\n applications,\n totalCount: applications.length\n }\n}\n\nexport async function searchEvents(\n api: v2.RUMApi,\n params: {\n query?: string\n from?: string\n to?: string\n type?: string\n sort?: 'timestamp' | '-timestamp'\n limit?: number\n },\n limits: LimitsConfig,\n site: string\n) {\n // Build query with type filter\n let queryString = params.query ?? '*'\n if (params.type && params.type !== 'all') {\n queryString = `@type:${params.type} ${queryString}`.trim()\n }\n\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 15 * 60 * 1000 // Default 15 minutes\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n const response = await api.listRUMEvents({\n filterQuery: queryString,\n filterFrom: new Date(fromTime * 1000),\n filterTo: new Date(toTime * 1000),\n sort: params.sort === 'timestamp' ? 'timestamp' : '-timestamp',\n pageLimit: Math.min(params.limit ?? limits.maxResults, limits.maxResults)\n })\n\n const events = (response.data ?? []).map(formatEvent)\n\n return {\n events,\n meta: {\n totalCount: events.length,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n datadog_url: buildRumUrl(queryString, fromTime, toTime, site)\n }\n }\n}\n\nexport async function aggregateEvents(\n api: v2.RUMApi,\n params: {\n query?: string\n from?: string\n to?: string\n groupBy?: string[]\n compute?: {\n aggregation?: string\n metric?: string\n interval?: string\n }\n },\n _limits: LimitsConfig,\n site: string\n) {\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 60 * 60 * 1000 // Default 1 hour\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n // Build group by configurations\n const groupByConfigs: v2.RUMGroupBy[] = (params.groupBy ?? []).map((field) => ({\n facet: field,\n limit: 10,\n sort: {\n type: 'measure' as const,\n aggregation: 'count' as v2.RUMAggregationFunction,\n order: 'desc' as const\n }\n }))\n\n // Build compute configuration - only include defined properties\n // Note: 'type' should only be set when metric is present, otherwise API rejects it\n const computeConfig: v2.RUMCompute = {\n aggregation: (params.compute?.aggregation ?? 'count') as v2.RUMAggregationFunction\n }\n if (params.compute?.metric) {\n computeConfig.metric = params.compute.metric\n computeConfig.type = 'total'\n }\n if (params.compute?.interval) {\n computeConfig.interval = params.compute.interval\n computeConfig.type = 'timeseries'\n }\n const computeConfigs: v2.RUMCompute[] = [computeConfig]\n\n const queryString = params.query ?? '*'\n const response = await api.aggregateRUMEvents({\n body: {\n filter: {\n query: queryString,\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n groupBy: groupByConfigs.length > 0 ? groupByConfigs : undefined,\n compute: computeConfigs\n }\n })\n\n // Format buckets from response\n const buckets = (response.data?.buckets ?? []).map((bucket) => ({\n by: bucket.by ?? {},\n computes: bucket.computes ?? {}\n }))\n\n return {\n buckets,\n meta: {\n elapsed: response.meta?.elapsed ?? 0,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n datadog_url: buildRumUrl(queryString, fromTime, toTime, site)\n }\n }\n}\n\n// Core Web Vitals metric configurations\nconst METRIC_CONFIGS: Record<string, { field: string; aggregations: v2.RUMAggregationFunction[] }> =\n {\n lcp: {\n field: '@view.largest_contentful_paint',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n fcp: {\n field: '@view.first_contentful_paint',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n cls: {\n field: '@view.cumulative_layout_shift',\n aggregations: ['avg', 'pc75']\n },\n fid: {\n field: '@view.first_input_delay',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n inp: {\n field: '@view.interaction_to_next_paint',\n aggregations: ['avg', 'pc75', 'pc90']\n },\n loading_time: {\n field: '@view.loading_time',\n aggregations: ['avg', 'pc75', 'pc90']\n }\n }\n\nexport async function getPerformanceMetrics(\n api: v2.RUMApi,\n params: {\n query?: string\n from?: string\n to?: string\n groupBy?: string[]\n metrics?: string[]\n },\n _limits: LimitsConfig,\n site: string\n) {\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 60 * 60 * 1000 // Default 1 hour\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n // Determine which metrics to query (default to 3 most important to stay under 10 computes limit)\n const requestedMetrics = params.metrics ?? ['lcp', 'fcp', 'cls']\n\n // Build compute configurations for all requested metrics\n const computeConfigs: v2.RUMCompute[] = []\n for (const metricName of requestedMetrics) {\n const config = METRIC_CONFIGS[metricName]\n if (!config) continue\n\n for (const aggregation of config.aggregations) {\n computeConfigs.push({\n aggregation,\n metric: config.field,\n type: 'total'\n })\n }\n }\n\n // Build group by configurations\n const groupByConfigs: v2.RUMGroupBy[] = (params.groupBy ?? []).map((field) => ({\n facet: field,\n limit: 10,\n sort: {\n type: 'measure' as const,\n aggregation: 'count' as v2.RUMAggregationFunction,\n order: 'desc' as const\n }\n }))\n\n // Query must filter to view events only\n const viewQuery = params.query ? `@type:view ${params.query}` : '@type:view'\n\n const response = await api.aggregateRUMEvents({\n body: {\n filter: {\n query: viewQuery,\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n groupBy: groupByConfigs.length > 0 ? groupByConfigs : undefined,\n compute: computeConfigs\n }\n })\n\n // Format response into structured metrics\n const buckets = (response.data?.buckets ?? []).map((bucket) => {\n const computes = (bucket.computes as Record<string, { value?: number }>) ?? {}\n const metrics: Record<string, Record<string, number | null>> = {}\n\n // Organize computes by metric name\n for (const metricName of requestedMetrics) {\n const config = METRIC_CONFIGS[metricName]\n if (!config) continue\n\n metrics[metricName] = {}\n for (const aggregation of config.aggregations) {\n // The key format in response is like \"c0\", \"c1\", etc. based on order\n // We need to find the matching compute by index\n const computeIndex = computeConfigs.findIndex(\n (c) => c.metric === config.field && c.aggregation === aggregation\n )\n const key = `c${computeIndex}`\n const value = computes[key]?.value\n metrics[metricName][String(aggregation)] = value ?? null\n }\n }\n\n return {\n by: bucket.by ?? {},\n metrics\n }\n })\n\n return {\n buckets,\n meta: {\n metrics: requestedMetrics,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n },\n datadog_url: buildRumUrl(viewQuery, fromTime, toTime, site)\n }\n }\n}\n\ninterface WaterfallEvent {\n id: string\n type: string\n timestamp: string\n duration: number | null\n view: {\n id: string | null\n url: string | null\n name: string | null\n }\n resource?: {\n url: string | null\n type: string | null\n duration: number | null\n size: number | null\n statusCode: number | null\n }\n action?: {\n id: string | null\n type: string | null\n name: string | null\n target: string | null\n }\n error?: {\n message: string | null\n source: string | null\n type: string | null\n }\n longTask?: {\n duration: number | null\n }\n}\n\nexport function formatWaterfallEvent(event: v2.RUMEvent): WaterfallEvent {\n const attrs = event.attributes ?? {}\n const appAttrs = (attrs.attributes ?? {}) as Record<string, unknown>\n\n const view = (appAttrs['view'] ?? {}) as Record<string, unknown>\n const resource = (appAttrs['resource'] ?? {}) as Record<string, unknown>\n const action = (appAttrs['action'] ?? {}) as Record<string, unknown>\n const error = (appAttrs['error'] ?? {}) as Record<string, unknown>\n const longTask = (appAttrs['long_task'] ?? {}) as Record<string, unknown>\n\n // Event type is in nested attributes, not at top level\n const eventType = (appAttrs['type'] as string) ?? 'unknown'\n\n return {\n id: event.id ?? '',\n type: eventType,\n timestamp: attrs.timestamp?.toISOString() ?? '',\n duration: (view['loading_time'] as number) ?? (resource['duration'] as number) ?? null,\n view: {\n id: (view['id'] as string) ?? null,\n url: (view['url'] as string) ?? null,\n name: (view['name'] as string) ?? null\n },\n resource: resource['url']\n ? {\n url: (resource['url'] as string) ?? null,\n type: (resource['type'] as string) ?? null,\n duration: (resource['duration'] as number) ?? null,\n size: (resource['size'] as number) ?? null,\n statusCode: (resource['status_code'] as number) ?? null\n }\n : undefined,\n action: action['id']\n ? {\n id: (action['id'] as string) ?? null,\n type: (action['type'] as string) ?? null,\n name: (action['name'] as string) ?? null,\n target: (action['target'] as string) ?? null\n }\n : undefined,\n error: error['message']\n ? {\n message: (error['message'] as string) ?? null,\n source: (error['source'] as string) ?? null,\n type: (error['type'] as string) ?? null\n }\n : undefined,\n longTask: longTask['duration']\n ? {\n duration: (longTask['duration'] as number) ?? null\n }\n : undefined\n }\n}\n\nexport async function getSessionWaterfall(\n api: v2.RUMApi,\n params: {\n applicationId: string\n sessionId: string\n viewId?: string\n },\n limits: LimitsConfig,\n site: string\n) {\n // Build query for specific session\n const queryParts = [`@application.id:${params.applicationId}`, `@session.id:${params.sessionId}`]\n if (params.viewId) {\n queryParts.push(`@view.id:${params.viewId}`)\n }\n\n const response = await api.listRUMEvents({\n filterQuery: queryParts.join(' '),\n sort: 'timestamp',\n pageLimit: Math.min(limits.maxResults, 1000)\n })\n\n const events = (response.data ?? []).map(formatWaterfallEvent)\n\n // Group events by type for summary\n const summary = {\n views: events.filter((e) => e.type === 'view').length,\n resources: events.filter((e) => e.type === 'resource').length,\n actions: events.filter((e) => e.type === 'action').length,\n errors: events.filter((e) => e.type === 'error').length,\n longTasks: events.filter((e) => e.type === 'long_task').length\n }\n\n return {\n events,\n summary,\n meta: {\n totalCount: events.length,\n applicationId: params.applicationId,\n sessionId: params.sessionId,\n viewId: params.viewId ?? null,\n datadog_url: buildRumSessionUrl(params.applicationId, params.sessionId, site)\n }\n }\n}\n\nexport function registerRumTool(\n server: McpServer,\n api: v2.RUMApi,\n limits: LimitsConfig,\n site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'rum',\n 'Query Datadog Real User Monitoring (RUM) data. Actions: applications (list RUM apps), events (search RUM events), aggregate (group and count events), performance (Core Web Vitals: LCP, FCP, CLS, FID, INP), waterfall (session timeline with resources/actions/errors). Use for: frontend performance, user sessions, page views, errors, resource loading.',\n InputSchema,\n async ({\n action,\n query,\n from,\n to,\n type,\n sort,\n limit,\n groupBy,\n compute,\n metrics,\n applicationId,\n sessionId,\n viewId\n }) => {\n try {\n switch (action) {\n case 'applications':\n return toolResult(await listApplications(api))\n\n case 'events':\n return toolResult(\n await searchEvents(api, { query, from, to, type, sort, limit }, limits, site)\n )\n\n case 'aggregate':\n return toolResult(\n await aggregateEvents(api, { query, from, to, groupBy, compute }, limits, site)\n )\n\n case 'performance':\n return toolResult(\n await getPerformanceMetrics(api, { query, from, to, groupBy, metrics }, limits, site)\n )\n\n case 'waterfall':\n if (!applicationId || !sessionId) {\n throw new Error('waterfall action requires applicationId and sessionId parameters')\n }\n return toolResult(\n await getSessionWaterfall(api, { applicationId, sessionId, viewId }, limits, site)\n )\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime } from '../utils/time.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['rules', 'signals', 'findings'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Rule or signal ID (for specific lookups)'),\n query: z.string().optional().describe('Search query for signals or findings'),\n from: z.string().optional().describe('Start time (ISO 8601, relative like \"1h\", \"7d\")'),\n to: z.string().optional().describe('End time (ISO 8601, relative like \"now\")'),\n severity: z\n .enum(['info', 'low', 'medium', 'high', 'critical'])\n .optional()\n .describe('Filter by severity'),\n status: z\n .enum(['open', 'under_review', 'archived'])\n .optional()\n .describe('Filter signals by status'),\n pageSize: z.number().optional().describe('Number of results to return'),\n pageCursor: z.string().optional().describe('Cursor for pagination')\n}\n\ninterface SecurityRuleSummary {\n id: string\n name: string\n type: string\n isEnabled: boolean\n hasExtendedTitle: boolean\n message: string | null\n tags: string[]\n createdAt: string\n updatedAt: string\n creationAuthorId: number | null\n isDefault: boolean\n isDeleted: boolean\n filters: Array<{\n action: string\n query: string\n }>\n}\n\ninterface SecuritySignalSummary {\n id: string\n type: string\n timestamp: string\n attributes: {\n message: string | null\n status: string | null\n severity: string | null\n tags: string[]\n custom: Record<string, unknown>\n }\n}\n\nexport function formatRule(rule: v2.SecurityMonitoringRuleResponse): SecurityRuleSummary {\n // Handle union type - SecurityMonitoringRuleResponse can be various rule types\n const ruleData = rule as Record<string, unknown>\n\n return {\n id: (ruleData['id'] as string) ?? '',\n name: (ruleData['name'] as string) ?? '',\n type: (ruleData['type'] as string) ?? '',\n isEnabled: (ruleData['isEnabled'] as boolean) ?? false,\n hasExtendedTitle: (ruleData['hasExtendedTitle'] as boolean) ?? false,\n message: (ruleData['message'] as string) ?? null,\n tags: (ruleData['tags'] as string[]) ?? [],\n createdAt: ruleData['createdAt'] ? new Date(ruleData['createdAt'] as number).toISOString() : '',\n updatedAt: ruleData['updatedAt'] ? new Date(ruleData['updatedAt'] as number).toISOString() : '',\n creationAuthorId: (ruleData['creationAuthorId'] as number) ?? null,\n isDefault: (ruleData['isDefault'] as boolean) ?? false,\n isDeleted: (ruleData['isDeleted'] as boolean) ?? false,\n filters: ((ruleData['filters'] as Array<{ action: string; query: string }>) ?? []).map((f) => ({\n action: f.action ?? '',\n query: f.query ?? ''\n }))\n }\n}\n\nexport function formatSignal(signal: v2.SecurityMonitoringSignal): SecuritySignalSummary {\n const attrs = signal.attributes ?? {}\n // Custom attributes are in the additionalProperties\n const customAttrs = attrs as Record<string, unknown>\n\n return {\n id: signal.id ?? '',\n type: String(signal.type ?? ''),\n timestamp: attrs.timestamp?.toISOString() ?? '',\n attributes: {\n message: attrs.message ?? null,\n status: (customAttrs['status'] as string) ?? null,\n severity: (customAttrs['severity'] as string) ?? null,\n tags: attrs.tags ?? [],\n custom: attrs.custom ?? {}\n }\n }\n}\n\nexport async function listRules(\n api: v2.SecurityMonitoringApi,\n params: {\n pageSize?: number\n pageCursor?: string\n },\n limits: LimitsConfig\n) {\n const response = await api.listSecurityMonitoringRules({\n pageSize: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n pageNumber: 0\n })\n\n const rules = (response.data ?? []).map(formatRule)\n\n return {\n rules,\n meta: {\n totalCount: rules.length\n }\n }\n}\n\nexport async function getRule(api: v2.SecurityMonitoringApi, ruleId: string) {\n const response = await api.getSecurityMonitoringRule({ ruleId })\n\n return {\n rule: formatRule(response)\n }\n}\n\nexport async function searchSignals(\n api: v2.SecurityMonitoringApi,\n params: {\n query?: string\n from?: string\n to?: string\n severity?: string\n status?: string\n pageSize?: number\n pageCursor?: string\n },\n limits: LimitsConfig\n) {\n // Parse time range\n const nowMs = Date.now()\n const defaultFromMs = nowMs - 24 * 60 * 60 * 1000 // Default 24 hours\n const fromTime = parseTime(params.from, Math.floor(defaultFromMs / 1000))\n const toTime = parseTime(params.to, Math.floor(nowMs / 1000))\n\n // Build query with filters\n let queryString = params.query ?? '*'\n if (params.severity) {\n queryString = `severity:${params.severity} ${queryString}`.trim()\n }\n if (params.status) {\n queryString = `status:${params.status} ${queryString}`.trim()\n }\n\n const response = await api.searchSecurityMonitoringSignals({\n body: {\n filter: {\n query: queryString,\n from: new Date(fromTime * 1000),\n to: new Date(toTime * 1000)\n },\n page: {\n limit: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n cursor: params.pageCursor\n },\n sort: 'timestamp' as v2.SecurityMonitoringSignalsSort\n }\n })\n\n const signals = (response.data ?? []).map(formatSignal)\n\n return {\n signals,\n meta: {\n nextCursor: response.meta?.page?.after ?? null,\n totalCount: signals.length,\n timeRange: {\n from: new Date(fromTime * 1000).toISOString(),\n to: new Date(toTime * 1000).toISOString()\n }\n }\n }\n}\n\nexport async function listFindings(\n api: v2.SecurityMonitoringApi,\n params: {\n query?: string\n pageSize?: number\n pageCursor?: string\n },\n limits: LimitsConfig\n) {\n // Note: Findings API may require specific permissions\n // Using the signals search as a fallback for security findings\n const response = await api.searchSecurityMonitoringSignals({\n body: {\n filter: {\n query:\n params.query ??\n '@workflow.rule.type:workload_security OR @workflow.rule.type:cloud_configuration',\n from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last 7 days\n to: new Date()\n },\n page: {\n limit: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n cursor: params.pageCursor\n }\n }\n })\n\n const findings = (response.data ?? []).map(formatSignal)\n\n return {\n findings,\n meta: {\n nextCursor: response.meta?.page?.after ?? null,\n totalCount: findings.length\n }\n }\n}\n\nexport function registerSecurityTool(\n server: McpServer,\n api: v2.SecurityMonitoringApi,\n limits: LimitsConfig\n): void {\n server.tool(\n 'security',\n 'Query Datadog Security Monitoring. Actions: rules (list detection rules), signals (search security signals), findings (list security findings). Use for: threat detection, compliance, security posture, incident investigation.',\n InputSchema,\n async ({ action, id, query, from, to, severity, status, pageSize, pageCursor }) => {\n try {\n switch (action) {\n case 'rules':\n if (id) {\n return toolResult(await getRule(api, id))\n }\n return toolResult(await listRules(api, { pageSize, pageCursor }, limits))\n\n case 'signals':\n return toolResult(\n await searchSignals(\n api,\n { query, from, to, severity, status, pageSize, pageCursor },\n limits\n )\n )\n\n case 'findings':\n return toolResult(await listFindings(api, { query, pageSize, pageCursor }, limits))\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'create', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.number().optional().describe('Notebook ID (required for get/update/delete actions)'),\n query: z.string().optional().describe('Search query for notebooks'),\n authorHandle: z.string().optional().describe('Filter by author handle (email)'),\n excludeAuthorHandle: z.string().optional().describe('Exclude notebooks by author handle'),\n includeCells: z\n .boolean()\n .optional()\n .describe('Include cell content in response (default: true for get)'),\n name: z.string().optional().describe('Notebook name (for create/update)'),\n cells: z\n .array(\n z.object({\n type: z.enum([\n 'markdown',\n 'timeseries',\n 'toplist',\n 'heatmap',\n 'distribution',\n 'log_stream'\n ]),\n content: z.unknown()\n })\n )\n .optional()\n .describe('Notebook cells (for create/update)'),\n time: z\n .object({\n liveSpan: z.string().optional(),\n start: z.number().optional(),\n end: z.number().optional()\n })\n .optional()\n .describe('Time configuration for notebook'),\n status: z.enum(['published']).optional().describe('Notebook status'),\n pageSize: z.number().optional().describe('Number of notebooks to return'),\n pageNumber: z.number().optional().describe('Page number for pagination')\n}\n\ninterface NotebookSummary {\n id: number\n name: string\n author: {\n handle: string | null\n name: string | null\n }\n status: string\n cellCount: number\n created: string\n modified: string\n metadata: {\n isTemplate: boolean | null\n takeSnapshots: boolean | null\n }\n}\n\ninterface NotebookDetail extends NotebookSummary {\n cells: Array<{\n id: string\n type: string\n attributes: unknown\n }>\n time: {\n liveSpan: string | null\n }\n}\n\nexport function formatNotebookSummary(nb: v1.NotebooksResponseData): NotebookSummary {\n const attrs = nb.attributes ?? {}\n\n return {\n id: nb.id ?? 0,\n name: attrs.name ?? '',\n author: {\n handle: attrs.author?.handle ?? null,\n name: attrs.author?.name ?? null\n },\n status: String(attrs.status ?? ''),\n cellCount: attrs.cells?.length ?? 0,\n created: attrs.created?.toISOString() ?? '',\n modified: attrs.modified?.toISOString() ?? '',\n metadata: {\n isTemplate: attrs.metadata?.isTemplate ?? null,\n takeSnapshots: attrs.metadata?.takeSnapshots ?? null\n }\n }\n}\n\nexport function formatNotebookDetail(nb: v1.NotebookResponseData): NotebookDetail {\n const attrs = nb.attributes ?? {}\n\n return {\n id: nb.id ?? 0,\n name: attrs.name ?? '',\n author: {\n handle: attrs.author?.handle ?? null,\n name: attrs.author?.name ?? null\n },\n status: String(attrs.status ?? ''),\n cellCount: attrs.cells?.length ?? 0,\n created: attrs.created?.toISOString() ?? '',\n modified: attrs.modified?.toISOString() ?? '',\n metadata: {\n isTemplate: attrs.metadata?.isTemplate ?? null,\n takeSnapshots: attrs.metadata?.takeSnapshots ?? null\n },\n cells: (attrs.cells ?? []).map((cell) => ({\n id: String(cell.id ?? ''),\n type: String(cell.type ?? ''),\n attributes: cell.attributes ?? {}\n })),\n time: {\n liveSpan: attrs.time\n ? String((attrs.time as unknown as Record<string, unknown>)['liveSpan'] ?? '')\n : null\n }\n }\n}\n\nexport async function listNotebooks(\n api: v1.NotebooksApi,\n params: {\n query?: string\n authorHandle?: string\n excludeAuthorHandle?: string\n includeCells?: boolean\n pageSize?: number\n pageNumber?: number\n },\n limits: LimitsConfig\n) {\n const response = await api.listNotebooks({\n query: params.query,\n authorHandle: params.authorHandle,\n excludeAuthorHandle: params.excludeAuthorHandle,\n includeCells: params.includeCells ?? false,\n count: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n start: (params.pageNumber ?? 0) * (params.pageSize ?? limits.maxResults)\n })\n\n const notebooks = (response.data ?? []).map(formatNotebookSummary)\n\n return {\n notebooks,\n meta: {\n totalCount: response.meta?.page?.totalCount ?? notebooks.length,\n totalFilteredCount: response.meta?.page?.totalFilteredCount ?? notebooks.length\n }\n }\n}\n\nexport async function getNotebook(api: v1.NotebooksApi, notebookId: number) {\n const response = await api.getNotebook({ notebookId })\n\n if (!response.data) {\n throw new Error(`Notebook ${notebookId} not found`)\n }\n\n return {\n notebook: formatNotebookDetail(response.data)\n }\n}\n\nexport async function createNotebook(\n api: v1.NotebooksApi,\n params: {\n name: string\n cells?: Array<{ type: string; content: unknown }>\n time?: { liveSpan?: string; start?: number; end?: number }\n status?: string\n }\n) {\n // Build cells for the notebook\n const cells: v1.NotebookCellCreateRequest[] = (params.cells ?? []).map((cell) => {\n // Default to markdown cell if no specific type handling\n if (cell.type === 'markdown') {\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: {\n type: 'markdown' as const,\n text: String(cell.content ?? '')\n }\n } as v1.NotebookCellCreateRequestAttributes\n }\n }\n // For other cell types, pass through the content as definition\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: cell.content\n } as v1.NotebookCellCreateRequestAttributes\n }\n })\n\n // If no cells provided, create a default markdown cell\n if (cells.length === 0) {\n cells.push({\n type: 'notebook_cells' as const,\n attributes: {\n definition: {\n type: 'markdown' as const,\n text: '# New Notebook\\n\\nStart adding content here.'\n }\n } as v1.NotebookCellCreateRequestAttributes\n })\n }\n\n // Build time configuration - use type assertion for union type\n const timeConfig = (\n params.time?.liveSpan\n ? { liveSpan: params.time.liveSpan as v1.NotebookRelativeTime['liveSpan'] }\n : { liveSpan: '1h' as v1.NotebookRelativeTime['liveSpan'] }\n ) as v1.NotebookGlobalTime\n\n const response = await api.createNotebook({\n body: {\n data: {\n type: 'notebooks',\n attributes: {\n name: params.name,\n cells,\n time: timeConfig,\n status: (params.status as v1.NotebookStatus) ?? 'published'\n }\n }\n }\n })\n\n if (!response.data) {\n throw new Error('Failed to create notebook')\n }\n\n return {\n success: true,\n notebook: formatNotebookDetail(response.data),\n message: `Notebook \"${params.name}\" created successfully`\n }\n}\n\nexport async function updateNotebook(\n api: v1.NotebooksApi,\n notebookId: number,\n params: {\n name?: string\n cells?: Array<{ type: string; content: unknown }>\n time?: { liveSpan?: string; start?: number; end?: number }\n status?: string\n }\n) {\n // First get the existing notebook to preserve fields\n const existing = await api.getNotebook({ notebookId })\n if (!existing.data) {\n throw new Error(`Notebook ${notebookId} not found`)\n }\n\n const existingAttrs = existing.data.attributes ?? {}\n\n // Build cells if provided\n let cells: v1.NotebookUpdateCell[] | undefined\n if (params.cells) {\n cells = params.cells.map((cell) => {\n if (cell.type === 'markdown') {\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: {\n type: 'markdown' as const,\n text: String(cell.content ?? '')\n }\n } as v1.NotebookCellUpdateRequestAttributes\n }\n }\n return {\n type: 'notebook_cells' as const,\n attributes: {\n definition: cell.content\n } as v1.NotebookCellUpdateRequestAttributes\n }\n })\n }\n\n // Build time configuration - use type assertion for union type\n const timeConfig: v1.NotebookGlobalTime | undefined = params.time?.liveSpan\n ? ({\n liveSpan: params.time.liveSpan as v1.NotebookRelativeTime['liveSpan']\n } as v1.NotebookGlobalTime)\n : undefined\n\n const response = await api.updateNotebook({\n notebookId,\n body: {\n data: {\n type: 'notebooks',\n attributes: {\n name: params.name ?? existingAttrs.name ?? '',\n cells:\n cells ??\n existingAttrs.cells?.map((c) => ({\n id: c.id,\n type: 'notebook_cells' as const,\n attributes: c.attributes as v1.NotebookCellUpdateRequestAttributes\n })) ??\n [],\n time: timeConfig ?? existingAttrs.time ?? { liveSpan: '1h' as const },\n status: (params.status ?? existingAttrs.status) as v1.NotebookStatus\n }\n }\n }\n })\n\n if (!response.data) {\n throw new Error('Failed to update notebook')\n }\n\n return {\n success: true,\n notebook: formatNotebookDetail(response.data),\n message: `Notebook ${notebookId} updated successfully`\n }\n}\n\nexport async function deleteNotebook(api: v1.NotebooksApi, notebookId: number) {\n await api.deleteNotebook({ notebookId })\n\n return {\n success: true,\n message: `Notebook ${notebookId} deleted successfully`\n }\n}\n\nexport function registerNotebooksTool(\n server: McpServer,\n api: v1.NotebooksApi,\n limits: LimitsConfig,\n readOnly: boolean = false,\n _site: string = 'datadoghq.com'\n): void {\n server.tool(\n 'notebooks',\n 'Manage Datadog Notebooks. Actions: list (search notebooks), get (by ID with cells), create (new notebook), update (modify notebook), delete (remove notebook). Use for: runbooks, incident documentation, investigation notes, dashboards as code.',\n InputSchema,\n async ({\n action,\n id,\n query,\n authorHandle,\n excludeAuthorHandle,\n includeCells,\n name,\n cells,\n time,\n status,\n pageSize,\n pageNumber\n }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(\n await listNotebooks(\n api,\n { query, authorHandle, excludeAuthorHandle, includeCells, pageSize, pageNumber },\n limits\n )\n )\n\n case 'get': {\n const notebookId = requireParam(id, 'id', 'get')\n return toolResult(await getNotebook(api, notebookId))\n }\n\n case 'create': {\n const notebookName = requireParam(name, 'name', 'create')\n return toolResult(\n await createNotebook(api, {\n name: notebookName,\n cells: cells as Array<{ type: string; content: unknown }>,\n time,\n status\n })\n )\n }\n\n case 'update': {\n const notebookId = requireParam(id, 'id', 'update')\n return toolResult(\n await updateNotebook(api, notebookId, {\n name,\n cells: cells as Array<{ type: string; content: unknown }>,\n time,\n status\n })\n )\n }\n\n case 'delete': {\n const notebookId = requireParam(id, 'id', 'delete')\n return toolResult(await deleteNotebook(api, notebookId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('User ID (required for get action)'),\n filter: z.string().optional().describe('Filter users by name or email'),\n status: z.enum(['Active', 'Pending', 'Disabled']).optional().describe('Filter by user status'),\n pageSize: z.number().optional().describe('Number of users to return per page'),\n pageNumber: z.number().optional().describe('Page number for pagination')\n}\n\ninterface UserSummary {\n id: string\n email: string\n name: string\n status: string\n title: string | null\n verified: boolean\n disabled: boolean\n createdAt: string\n modifiedAt: string\n relationships: {\n roles: string[]\n org: string | null\n }\n}\n\nexport function formatUser(user: v2.User): UserSummary {\n const attrs = user.attributes ?? {}\n const relationships = user.relationships ?? {}\n\n // Extract role names from relationships\n const roles = (relationships.roles?.data ?? []).map((r) => r.id ?? '')\n const orgId = relationships.org?.data?.id ?? null\n\n return {\n id: user.id ?? '',\n email: attrs.email ?? '',\n name: attrs.name ?? '',\n status: attrs.status ?? '',\n title: attrs.title ?? null,\n verified: attrs.verified ?? false,\n disabled: attrs.disabled ?? false,\n createdAt: attrs.createdAt?.toISOString() ?? '',\n modifiedAt: attrs.modifiedAt?.toISOString() ?? '',\n relationships: {\n roles,\n org: orgId\n }\n }\n}\n\nexport async function listUsers(\n api: v2.UsersApi,\n params: {\n filter?: string\n status?: string\n pageSize?: number\n pageNumber?: number\n },\n limits: LimitsConfig\n) {\n const response = await api.listUsers({\n filter: params.filter,\n filterStatus: params.status,\n pageSize: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n pageNumber: params.pageNumber ?? 0\n })\n\n const users = (response.data ?? []).map(formatUser)\n\n return {\n users,\n meta: {\n page: response.meta?.page ?? {},\n totalCount: users.length\n }\n }\n}\n\nexport async function getUser(api: v2.UsersApi, userId: string) {\n const response = await api.getUser({ userId })\n\n if (!response.data) {\n throw new Error(`User ${userId} not found`)\n }\n\n return {\n user: formatUser(response.data)\n }\n}\n\nexport function registerUsersTool(server: McpServer, api: v2.UsersApi, limits: LimitsConfig): void {\n server.tool(\n 'users',\n 'Manage Datadog users. Actions: list (with filters), get (by ID). Use for: access management, user auditing, team organization.',\n InputSchema,\n async ({ action, id, filter, status, pageSize, pageNumber }) => {\n try {\n switch (action) {\n case 'list':\n return toolResult(\n await listUsers(api, { filter, status, pageSize, pageNumber }, limits)\n )\n\n case 'get': {\n const userId = requireParam(id, 'id', 'get')\n return toolResult(await getUser(api, userId))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v2 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'members'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n id: z.string().optional().describe('Team ID (required for get/members actions)'),\n filter: z.string().optional().describe('Filter teams by name'),\n pageSize: z.number().optional().describe('Number of teams to return per page'),\n pageNumber: z.number().optional().describe('Page number for pagination')\n}\n\ninterface TeamSummary {\n id: string\n name: string\n handle: string\n description: string | null\n summary: string | null\n linkCount: number\n userCount: number\n createdAt: string\n modifiedAt: string\n}\n\ninterface TeamMemberSummary {\n id: string\n type: string\n attributes: {\n role: string\n }\n relationships: {\n userId: string | null\n }\n}\n\nexport function formatTeam(team: v2.Team): TeamSummary {\n const attrs = team.attributes ?? {}\n\n return {\n id: team.id ?? '',\n name: attrs.name ?? '',\n handle: attrs.handle ?? '',\n description: attrs.description ?? null,\n summary: attrs.summary ?? null,\n linkCount: attrs.linkCount ?? 0,\n userCount: attrs.userCount ?? 0,\n createdAt: attrs.createdAt?.toISOString() ?? '',\n modifiedAt: attrs.modifiedAt?.toISOString() ?? ''\n }\n}\n\nexport function formatTeamMember(member: v2.UserTeam): TeamMemberSummary {\n const attrs = member.attributes ?? {}\n const relationships = member.relationships ?? {}\n\n return {\n id: member.id ?? '',\n type: String(member.type ?? ''),\n attributes: {\n role: String(attrs.role ?? '')\n },\n relationships: {\n userId: relationships.user?.data?.id ?? null\n }\n }\n}\n\nexport async function listTeams(\n api: v2.TeamsApi,\n params: {\n filter?: string\n pageSize?: number\n pageNumber?: number\n },\n limits: LimitsConfig\n) {\n const response = await api.listTeams({\n filterKeyword: params.filter,\n pageSize: Math.min(params.pageSize ?? limits.maxResults, limits.maxResults),\n pageNumber: params.pageNumber ?? 0\n })\n\n const teams = (response.data ?? []).map(formatTeam)\n\n return {\n teams,\n meta: {\n totalCount: teams.length\n }\n }\n}\n\nexport async function getTeam(api: v2.TeamsApi, teamId: string) {\n const response = await api.getTeam({ teamId })\n\n if (!response.data) {\n throw new Error(`Team ${teamId} not found`)\n }\n\n return {\n team: formatTeam(response.data)\n }\n}\n\nexport async function getTeamMembers(api: v2.TeamsApi, teamId: string, limits: LimitsConfig) {\n const response = await api.getTeamMemberships({\n teamId,\n pageSize: limits.maxResults\n })\n\n const members = (response.data ?? []).map(formatTeamMember)\n\n return {\n members,\n meta: {\n totalCount: members.length\n }\n }\n}\n\nexport function registerTeamsTool(server: McpServer, api: v2.TeamsApi, limits: LimitsConfig): void {\n server.tool(\n 'teams',\n 'Manage Datadog teams. Actions: list (with filters), get (by ID), members (list team members). Use for: team organization, access management, collaboration.',\n InputSchema,\n async ({ action, id, filter, pageSize, pageNumber }) => {\n try {\n switch (action) {\n case 'list':\n return toolResult(await listTeams(api, { filter, pageSize, pageNumber }, limits))\n\n case 'get': {\n const teamId = requireParam(id, 'id', 'get')\n return toolResult(await getTeam(api, teamId))\n }\n\n case 'members': {\n const teamId = requireParam(id, 'id', 'members')\n return toolResult(await getTeamMembers(api, teamId, limits))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError, requireParam, checkReadOnly } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum(['list', 'get', 'add', 'update', 'delete'])\n\nconst InputSchema = {\n action: ActionSchema.describe('Action to perform'),\n hostName: z\n .string()\n .optional()\n .describe('Host name (required for get/add/update/delete actions)'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags to add or set (for add/update actions). Format: \"key:value\"'),\n source: z\n .string()\n .optional()\n .describe('Source of the tags (e.g., \"users\", \"datadog\"). Defaults to \"users\"')\n}\n\ninterface HostTagsSummary {\n hostName: string\n tags: string[]\n source: string | null\n}\n\ninterface AllTagsSummary {\n hosts: { [key: string]: string[] }\n totalHosts: number\n}\n\nexport async function listAllTags(api: v1.TagsApi, source?: string): Promise<AllTagsSummary> {\n const response = await api.listHostTags({\n source\n })\n\n const tags = response.tags ?? {}\n\n return {\n hosts: tags,\n totalHosts: Object.keys(tags).length\n }\n}\n\nexport async function getHostTags(\n api: v1.TagsApi,\n hostName: string,\n source?: string\n): Promise<HostTagsSummary> {\n const response = await api.getHostTags({\n hostName,\n source\n })\n\n return {\n hostName,\n tags: response.tags ?? [],\n source: source ?? null\n }\n}\n\nexport async function addHostTags(\n api: v1.TagsApi,\n hostName: string,\n tags: string[],\n source?: string\n) {\n const response = await api.createHostTags({\n hostName,\n body: {\n host: hostName,\n tags\n },\n source\n })\n\n return {\n success: true,\n hostName,\n tags: response.tags ?? tags,\n message: `Tags added to host ${hostName}`\n }\n}\n\nexport async function updateHostTags(\n api: v1.TagsApi,\n hostName: string,\n tags: string[],\n source?: string\n) {\n const response = await api.updateHostTags({\n hostName,\n body: {\n host: hostName,\n tags\n },\n source\n })\n\n return {\n success: true,\n hostName,\n tags: response.tags ?? tags,\n message: `Tags updated for host ${hostName}`\n }\n}\n\nexport async function deleteHostTags(api: v1.TagsApi, hostName: string, source?: string) {\n await api.deleteHostTags({\n hostName,\n source\n })\n\n return {\n success: true,\n hostName,\n message: `Tags deleted from host ${hostName}`\n }\n}\n\nexport function registerTagsTool(\n server: McpServer,\n api: v1.TagsApi,\n _limits: LimitsConfig,\n readOnly: boolean = false\n): void {\n server.tool(\n 'tags',\n 'Manage Datadog host tags. Actions: list (all host tags), get (tags for specific host), add (create tags), update (replace tags), delete (remove all tags). Use for: infrastructure organization, filtering, grouping.',\n InputSchema,\n async ({ action, hostName, tags, source }) => {\n try {\n checkReadOnly(action, readOnly)\n switch (action) {\n case 'list':\n return toolResult(await listAllTags(api, source))\n\n case 'get': {\n const host = requireParam(hostName, 'hostName', 'get')\n return toolResult(await getHostTags(api, host, source))\n }\n\n case 'add': {\n const host = requireParam(hostName, 'hostName', 'add')\n const tagList = requireParam(tags, 'tags', 'add')\n return toolResult(await addHostTags(api, host, tagList, source))\n }\n\n case 'update': {\n const host = requireParam(hostName, 'hostName', 'update')\n const tagList = requireParam(tags, 'tags', 'update')\n return toolResult(await updateHostTags(api, host, tagList, source))\n }\n\n case 'delete': {\n const host = requireParam(hostName, 'hostName', 'delete')\n return toolResult(await deleteHostTags(api, host, source))\n }\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { z } from 'zod'\nimport { v1 } from '@datadog/datadog-api-client'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\nimport { parseTime } from '../utils/time.js'\nimport type { LimitsConfig } from '../config/schema.js'\n\nconst ActionSchema = z.enum([\n 'summary',\n 'hosts',\n 'logs',\n 'custom_metrics',\n 'indexed_spans',\n 'ingested_spans'\n])\n\nconst InputSchema = {\n action: ActionSchema.describe(\n 'Action to perform: summary (overall usage), hosts, logs, custom_metrics, indexed_spans, ingested_spans'\n ),\n from: z\n .string()\n .optional()\n .describe('Start time (ISO 8601 date like \"2024-01-01\", or relative like \"30d\")'),\n to: z\n .string()\n .optional()\n .describe('End time (ISO 8601 date like \"2024-01-31\", or relative like \"now\")'),\n includeOrgDetails: z\n .boolean()\n .optional()\n .describe('Include usage breakdown by organization (for multi-org accounts)')\n}\n\ninterface UsageSummary {\n startDate: string\n endDate: string\n aggsTotal: Record<string, number | null>\n usage: Array<{\n date: string\n orgName: string | null\n apmHostTop99pSum: number | null\n infraHostTop99pSum: number | null\n logsIndexedLogsUsageSum: number | null\n ingestedEventsBytesSum: number | null\n customMetricsAvgPerHour: number | null\n }>\n}\n\ninterface HostUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n agentHostTop99p: number | null\n awsHostTop99p: number | null\n azureHostTop99p: number | null\n gcpHostTop99p: number | null\n infraHostTop99p: number | null\n containerTop99p: number | null\n }>\n}\n\ninterface LogsUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n logsIndexedLogsUsageSum: number | null\n logsLiveIndexedLogsUsageSum: number | null\n logsRehydratedIndexedLogsUsageSum: number | null\n }>\n}\n\ninterface CustomMetricsUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n avgMetricsCount: number | null\n maxMetricsCount: number | null\n }>\n}\n\ninterface SpansUsage {\n startDate: string\n endDate: string\n usage: Array<{\n date: string\n indexedSpansCount: number | null\n ingestedSpansBytes: number | null\n }>\n}\n\nexport function parseDate(dateStr: string | undefined, defaultDate: Date): Date {\n if (!dateStr) return defaultDate\n\n // Check if it's a relative date\n if (dateStr.match(/^\\d+[hdwmy]$/)) {\n const seconds = parseTime(dateStr, Math.floor(Date.now() / 1000))\n return new Date(seconds * 1000)\n }\n\n // Try ISO date parsing\n const parsed = new Date(dateStr)\n if (!Number.isNaN(parsed.getTime())) {\n return parsed\n }\n\n return defaultDate\n}\n\nexport async function getUsageSummary(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n includeOrgDetails?: boolean\n }\n): Promise<UsageSummary> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageSummary({\n startMonth: startDate,\n endMonth: endDate,\n includeOrgDetails: params.includeOrgDetails\n })\n\n return {\n startDate: response.startDate?.toISOString() ?? startDate.toISOString(),\n endDate: response.endDate?.toISOString() ?? endDate.toISOString(),\n aggsTotal: {\n apmHostTop99p: response.apmHostTop99PSum ?? null,\n infraHostTop99p: response.infraHostTop99PSum ?? null\n },\n usage: (response.usage ?? []).map((u) => ({\n date: u.date?.toISOString() ?? '',\n orgName: ((u as Record<string, unknown>)['orgName'] as string) ?? null,\n apmHostTop99pSum: u.apmHostTop99P ?? null,\n infraHostTop99pSum: u.infraHostTop99P ?? null,\n logsIndexedLogsUsageSum: u.indexedEventsCountSum ?? null,\n ingestedEventsBytesSum: u.ingestedEventsBytesSum ?? null,\n customMetricsAvgPerHour: null // Not in summary\n }))\n }\n}\n\nexport async function getHostsUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<HostUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageHosts({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n agentHostTop99p: u.agentHostCount ?? null,\n awsHostTop99p: u.awsHostCount ?? null,\n azureHostTop99p: u.azureHostCount ?? null,\n gcpHostTop99p: u.gcpHostCount ?? null,\n infraHostTop99p: u.hostCount ?? null,\n containerTop99p: u.containerCount ?? null\n }))\n }\n}\n\nexport async function getLogsUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<LogsUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageLogs({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n logsIndexedLogsUsageSum: u.indexedEventsCount ?? null,\n logsLiveIndexedLogsUsageSum: u.indexedEventsCount ?? null,\n logsRehydratedIndexedLogsUsageSum:\n ((u as Record<string, unknown>)['logsRehydratedIndexedCount'] as number) ?? null\n }))\n }\n}\n\nexport async function getCustomMetricsUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<CustomMetricsUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageTimeseries({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n avgMetricsCount: u.numCustomTimeseries ?? null,\n maxMetricsCount: null // Not directly available\n }))\n }\n}\n\nexport async function getIndexedSpansUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<SpansUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getUsageIndexedSpans({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n indexedSpansCount: u.indexedEventsCount ?? null,\n ingestedSpansBytes: null\n }))\n }\n}\n\nexport async function getIngestedSpansUsage(\n api: v1.UsageMeteringApi,\n params: {\n from?: string\n to?: string\n }\n): Promise<SpansUsage> {\n const endDate = parseDate(params.to, new Date())\n const startDate = parseDate(params.from, new Date(endDate.getTime() - 30 * 24 * 60 * 60 * 1000))\n\n const response = await api.getIngestedSpans({\n startHr: startDate,\n endHr: endDate\n })\n\n return {\n startDate: startDate.toISOString(),\n endDate: endDate.toISOString(),\n usage: (response.usage ?? []).map((u) => ({\n date: u.hour?.toISOString() ?? '',\n indexedSpansCount: null,\n ingestedSpansBytes: ((u as Record<string, unknown>)['ingestedTracesBytes'] as number) ?? null\n }))\n }\n}\n\nexport function registerUsageTool(\n server: McpServer,\n api: v1.UsageMeteringApi,\n _limits: LimitsConfig\n): void {\n server.tool(\n 'usage',\n 'Query Datadog usage metering data. Actions: summary (overall usage), hosts (infrastructure), logs, custom_metrics, indexed_spans, ingested_spans. Use for: cost management, capacity planning, usage tracking, billing analysis.',\n InputSchema,\n async ({ action, from, to, includeOrgDetails }) => {\n try {\n switch (action) {\n case 'summary':\n return toolResult(await getUsageSummary(api, { from, to, includeOrgDetails }))\n\n case 'hosts':\n return toolResult(await getHostsUsage(api, { from, to }))\n\n case 'logs':\n return toolResult(await getLogsUsage(api, { from, to }))\n\n case 'custom_metrics':\n return toolResult(await getCustomMetricsUsage(api, { from, to }))\n\n case 'indexed_spans':\n return toolResult(await getIndexedSpansUsage(api, { from, to }))\n\n case 'ingested_spans':\n return toolResult(await getIngestedSpansUsage(api, { from, to }))\n\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n","/**\n * Authentication tool for validating Datadog API credentials\n */\nimport { z } from 'zod'\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { DatadogClients } from '../config/datadog.js'\nimport { handleDatadogError } from '../errors/datadog.js'\nimport { toolResult } from '../utils/format.js'\n\nconst ActionSchema = z.enum(['validate'])\n\nconst InputSchema = {\n action: ActionSchema.describe(\n 'Action to perform: validate - test if API key and App key are valid'\n )\n}\n\nexport function registerAuthTool(server: McpServer, clients: DatadogClients): void {\n server.tool(\n 'auth',\n 'Validate Datadog API credentials. Use this to verify that the API key and App key are correctly configured before performing other operations.',\n InputSchema,\n async ({ action }) => {\n try {\n switch (action) {\n case 'validate':\n return toolResult(await validateCredentials(clients))\n default:\n throw new Error(`Unknown action: ${action}`)\n }\n } catch (error) {\n handleDatadogError(error)\n }\n }\n )\n}\n\nexport async function validateCredentials(clients: DatadogClients) {\n // Step 1: Validate API key using the official Authentication API\n const apiKeyResult = await clients.auth.validate()\n\n if (!apiKeyResult.valid) {\n return {\n valid: false,\n apiKeyValid: false,\n appKeyValid: false,\n error: 'API key is invalid',\n suggestion: 'Check that your DD_API_KEY environment variable is correct'\n }\n }\n\n // Step 2: Validate App key by making a lightweight API call that requires it\n // The Authentication API only validates API key, so we need to test App key separately\n try {\n // Use a minimal call - list users with page size 1 requires both keys\n await clients.users.listUsers({ pageSize: 1 })\n\n return {\n valid: true,\n apiKeyValid: true,\n appKeyValid: true,\n message: 'Both API key and App key are valid and working',\n permissions: 'Credentials have sufficient permissions to access the Datadog API'\n }\n } catch (appKeyError) {\n // API key is valid but App key might be invalid or have insufficient permissions\n const errorMessage = appKeyError instanceof Error ? appKeyError.message : String(appKeyError)\n\n // Check if it's an auth error or just a permission issue\n const isAuthError =\n errorMessage.includes('401') ||\n errorMessage.includes('403') ||\n errorMessage.includes('Forbidden')\n\n return {\n valid: !isAuthError,\n apiKeyValid: true,\n appKeyValid: !isAuthError,\n warning: isAuthError\n ? 'App key may be invalid or have insufficient permissions'\n : 'API key is valid. App key validation inconclusive.',\n error: errorMessage,\n suggestion: isAuthError\n ? 'Check that your DD_APP_KEY environment variable is correct and has appropriate scopes'\n : 'Credentials appear valid but encountered an issue during validation'\n }\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { DatadogClients } from '../config/datadog.js'\nimport type { LimitsConfig, FeaturesConfig } from '../config/schema.js'\n\nimport { registerMonitorsTool } from './monitors.js'\nimport { registerDashboardsTool } from './dashboards.js'\nimport { registerLogsTool } from './logs.js'\nimport { registerMetricsTool } from './metrics.js'\nimport { registerTracesTool } from './traces.js'\nimport { registerEventsTool } from './events.js'\nimport { registerIncidentsTool } from './incidents.js'\nimport { registerSlosTool } from './slos.js'\nimport { registerSyntheticsTool } from './synthetics.js'\nimport { registerHostsTool } from './hosts.js'\nimport { registerDowntimesTool } from './downtimes.js'\nimport { registerRumTool } from './rum.js'\nimport { registerSecurityTool } from './security.js'\nimport { registerNotebooksTool } from './notebooks.js'\nimport { registerUsersTool } from './users.js'\nimport { registerTeamsTool } from './teams.js'\nimport { registerTagsTool } from './tags.js'\nimport { registerUsageTool } from './usage.js'\nimport { registerAuthTool } from './auth.js'\n\nexport function registerAllTools(\n server: McpServer,\n clients: DatadogClients,\n limits: LimitsConfig,\n features: FeaturesConfig,\n site: string = 'datadoghq.com'\n): void {\n const { readOnly, disabledTools } = features\n const enabled = (tool: string) => !disabledTools.includes(tool)\n\n if (enabled('monitors')) registerMonitorsTool(server, clients.monitors, limits, readOnly, site)\n if (enabled('dashboards'))\n registerDashboardsTool(server, clients.dashboards, limits, readOnly, site)\n if (enabled('logs')) registerLogsTool(server, clients.logs, limits, site)\n if (enabled('metrics'))\n registerMetricsTool(server, clients.metricsV1, clients.metricsV2, limits, site)\n if (enabled('traces')) registerTracesTool(server, clients.spans, clients.services, limits, site)\n if (enabled('events'))\n registerEventsTool(\n server,\n clients.eventsV1,\n clients.eventsV2,\n clients.monitors,\n limits,\n readOnly,\n site\n )\n if (enabled('incidents')) registerIncidentsTool(server, clients.incidents, limits, readOnly, site)\n if (enabled('slos')) registerSlosTool(server, clients.slo, limits, readOnly, site)\n if (enabled('synthetics'))\n registerSyntheticsTool(server, clients.synthetics, limits, readOnly, site)\n if (enabled('hosts')) registerHostsTool(server, clients.hosts, limits, readOnly)\n if (enabled('downtimes')) registerDowntimesTool(server, clients.downtimes, limits, readOnly)\n if (enabled('rum')) registerRumTool(server, clients.rum, limits, site)\n if (enabled('security')) registerSecurityTool(server, clients.security, limits)\n if (enabled('notebooks')) registerNotebooksTool(server, clients.notebooks, limits, readOnly, site)\n if (enabled('users')) registerUsersTool(server, clients.users, limits)\n if (enabled('teams')) registerTeamsTool(server, clients.teams, limits)\n if (enabled('tags')) registerTagsTool(server, clients.tags, limits, readOnly)\n if (enabled('usage')) registerUsageTool(server, clients.usage, limits)\n if (enabled('auth')) registerAuthTool(server, clients)\n}\n","import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport async function connectStdio(server: McpServer): Promise<void> {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n console.error('[MCP] Datadog MCP server running on stdio')\n}\n","/**\n * HTTP/StreamableHTTP transport for MCP server\n * Allows running the server over HTTP with configurable port\n */\nimport express, { Request, Response } from 'express'\nimport { randomUUID } from 'node:crypto'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js'\nimport type { ServerConfig } from '../config/schema.js'\n\n// Store active transports by session ID\nconst transports: Record<string, StreamableHTTPServerTransport> = {}\n\n/**\n * Creates and configures an Express app for MCP server\n * Exported for testing purposes\n */\nexport function createExpressApp(server: McpServer, config: ServerConfig): express.Application {\n const app = express()\n app.disable('x-powered-by')\n app.use(express.json())\n\n // Health check endpoint\n app.get('/health', (_req: Request, res: Response) => {\n res.json({ status: 'ok', name: config.name, version: config.version })\n })\n\n // MCP endpoint - handles POST, GET, DELETE\n app.post('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n let transport: StreamableHTTPServerTransport\n\n if (sessionId && transports[sessionId]) {\n // Reuse existing session\n transport = transports[sessionId]\n } else if (!sessionId && isInitializeRequest(req.body)) {\n // New session initialization\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (id) => {\n transports[id] = transport\n console.error(`[MCP] Session initialized: ${id}`)\n }\n })\n\n transport.onclose = () => {\n if (transport.sessionId) {\n delete transports[transport.sessionId]\n console.error(`[MCP] Session closed: ${transport.sessionId}`)\n }\n }\n\n await server.connect(transport)\n } else {\n res.status(400).json({\n jsonrpc: '2.0',\n error: { code: -32000, message: 'Invalid session' },\n id: null\n })\n return\n }\n\n await transport.handleRequest(req, res, req.body)\n })\n\n app.get('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string\n const transport = transports[sessionId]\n if (transport) {\n await transport.handleRequest(req, res)\n } else {\n res.status(400).json({ error: 'Invalid session' })\n }\n })\n\n app.delete('/mcp', async (req: Request, res: Response) => {\n const sessionId = req.headers['mcp-session-id'] as string\n const transport = transports[sessionId]\n if (transport) {\n await transport.handleRequest(req, res)\n } else {\n res.status(400).json({ error: 'Invalid session' })\n }\n })\n\n return app\n}\n\nexport async function connectHttp(server: McpServer, config: ServerConfig): Promise<void> {\n const app = createExpressApp(server, config)\n\n // Start server\n app.listen(config.port, config.host, () => {\n console.error(`[MCP] Datadog MCP server running on http://${config.host}:${config.port}/mcp`)\n console.error(`[MCP] Health check available at http://${config.host}:${config.port}/health`)\n })\n}\n","import { loadConfig } from './config/index.js'\nimport { createServer } from './server.js'\nimport { connectStdio, connectHttp } from './transport/index.js'\n\ntry {\n const config = loadConfig()\n const server = createServer(config)\n\n if (config.server.transport === 'http') {\n await connectHttp(server, config.server)\n } else {\n await connectStdio(server)\n }\n} catch (error) {\n console.error('[MCP] Failed to start server:', error)\n process.exit(1)\n}\n"],"mappings":"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","names":["z","z","z","ActionSchema","z","InputSchema","z","date","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","snakeToCamel","normalizeConfigKeys","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema","z","ActionSchema","z","InputSchema"]}