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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Datadog MCP Server
2
2
 
3
3
  [![Quality gate](https://sonarcloud.io/api/project_badges/quality_gate?project=TANTIOPE_datadog-mcp-server)](https://sonarcloud.io/summary/new_code?id=TANTIOPE_datadog-mcp-server)
4
- [![CI](https://github.com/tantiope/datadog-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/tantiope/datadog-mcp-server/actions/workflows/release.yml)
4
+ [![CI/Release](https://github.com/tantiope/datadog-mcp-server/actions/workflows/release.yml/badge.svg)](https://github.com/tantiope/datadog-mcp-server/actions/workflows/release.yml)
5
5
  [![npm](https://img.shields.io/npm/v/datadog-mcp)](https://www.npmjs.com/package/datadog-mcp)
6
6
  [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=TANTIOPE_datadog-mcp-server&metric=coverage)](https://sonarcloud.io/summary/new_code?id=TANTIOPE_datadog-mcp-server)
@@ -207,7 +207,7 @@ When running with `--transport=http`:
207
207
 
208
208
  ### Compact Mode (Logs)
209
209
 
210
- Use `compact: true` when searching logs to reduce payload size. Strips custom attributes and keeps only essential fields:
210
+ Use `compact: true` when searching logs to reduce token usage. Strips custom attributes and keeps only essential fields:
211
211
 
212
212
  ```
213
213
  logs({ action: "search", status: "error", compact: true })
package/dist/index.js CHANGED
@@ -345,13 +345,20 @@ function buildMonitorUrl(monitorId, site = "datadoghq.com") {
345
345
  const base = getAppBaseUrl(site);
346
346
  return `${base}/monitors/${monitorId}`;
347
347
  }
348
- function buildMonitorsListUrl(query, site = "datadoghq.com") {
348
+ function buildMonitorsListUrl(options, site = "datadoghq.com") {
349
349
  const base = getAppBaseUrl(site);
350
- if (query) {
351
- const params = new URLSearchParams({ query });
352
- return `${base}/monitors/manage?${params.toString()}`;
350
+ const params = new URLSearchParams();
351
+ if (options?.name) {
352
+ params.set("query", options.name);
353
353
  }
354
- return `${base}/monitors/manage`;
354
+ if (options?.tags && options.tags.length > 0) {
355
+ params.set("tags", options.tags.join(","));
356
+ }
357
+ if (options?.groupStates && options.groupStates.length > 0) {
358
+ params.set("group_states", options.groupStates.join(","));
359
+ }
360
+ const queryString = params.toString();
361
+ return queryString ? `${base}/monitors/manage?${queryString}` : `${base}/monitors/manage`;
355
362
  }
356
363
  function buildRumUrl(query, fromSec, toSec, site = "datadoghq.com") {
357
364
  const base = getAppBaseUrl(site);
@@ -392,9 +399,10 @@ var InputSchema = {
392
399
  message: z2.string().optional().describe("Mute message (for mute action)"),
393
400
  end: z2.number().optional().describe("Mute end timestamp (for mute action)")
394
401
  };
395
- function formatMonitor(m) {
402
+ function formatMonitor(m, site = "datadoghq.com") {
403
+ const monitorId = m.id ?? 0;
396
404
  return {
397
- id: m.id ?? 0,
405
+ id: monitorId,
398
406
  name: m.name ?? "",
399
407
  type: String(m.type ?? "unknown"),
400
408
  status: String(m.overallState ?? "unknown"),
@@ -402,7 +410,8 @@ function formatMonitor(m) {
402
410
  tags: m.tags ?? [],
403
411
  query: m.query ?? "",
404
412
  created: m.created ? new Date(m.created).toISOString() : "",
405
- modified: m.modified ? new Date(m.modified).toISOString() : ""
413
+ modified: m.modified ? new Date(m.modified).toISOString() : "",
414
+ url: buildMonitorUrl(monitorId, site)
406
415
  };
407
416
  }
408
417
  async function listMonitors(api, params, limits, site) {
@@ -412,7 +421,7 @@ async function listMonitors(api, params, limits, site) {
412
421
  tags: params.tags?.join(","),
413
422
  groupStates: params.groupStates?.join(",")
414
423
  });
415
- const monitors = response.slice(0, effectiveLimit).map(formatMonitor);
424
+ const monitors = response.slice(0, effectiveLimit).map((m) => formatMonitor(m, site));
416
425
  const statusCounts = {
417
426
  total: response.length,
418
427
  alert: response.filter((m) => m.overallState === "Alert").length,
@@ -423,7 +432,10 @@ async function listMonitors(api, params, limits, site) {
423
432
  return {
424
433
  monitors,
425
434
  summary: statusCounts,
426
- datadog_url: buildMonitorsListUrl(params.name, site)
435
+ datadog_url: buildMonitorsListUrl(
436
+ { name: params.name, tags: params.tags, groupStates: params.groupStates },
437
+ site
438
+ )
427
439
  };
428
440
  }
429
441
  async function getMonitor(api, id, site) {
@@ -433,7 +445,7 @@ async function getMonitor(api, id, site) {
433
445
  }
434
446
  const monitor = await api.getMonitor({ monitorId });
435
447
  return {
436
- monitor: formatMonitor(monitor),
448
+ monitor: formatMonitor(monitor, site),
437
449
  datadog_url: buildMonitorUrl(monitorId, site)
438
450
  };
439
451
  }
@@ -444,7 +456,8 @@ async function searchMonitors(api, query, limits, site) {
444
456
  name: m.name ?? "",
445
457
  status: String(m.status ?? "unknown"),
446
458
  type: m.type ?? "",
447
- tags: m.tags ?? []
459
+ tags: m.tags ?? [],
460
+ url: buildMonitorUrl(m.id ?? 0, site)
448
461
  }));
449
462
  return {
450
463
  monitors,
@@ -453,7 +466,7 @@ async function searchMonitors(api, query, limits, site) {
453
466
  pageCount: response.metadata?.pageCount ?? 1,
454
467
  page: response.metadata?.page ?? 0
455
468
  },
456
- datadog_url: buildMonitorsListUrl(query, site)
469
+ datadog_url: buildMonitorsListUrl({ name: query }, site)
457
470
  };
458
471
  }
459
472
  function normalizeMonitorConfig(config, isUpdate = false) {
@@ -507,21 +520,21 @@ function normalizeMonitorConfig(config, isUpdate = false) {
507
520
  }
508
521
  return normalized;
509
522
  }
510
- async function createMonitor(api, config) {
523
+ async function createMonitor(api, config, site = "datadoghq.com") {
511
524
  const body = normalizeMonitorConfig(config);
512
525
  const monitor = await api.createMonitor({ body });
513
526
  return {
514
527
  success: true,
515
- monitor: formatMonitor(monitor)
528
+ monitor: formatMonitor(monitor, site)
516
529
  };
517
530
  }
518
- async function updateMonitor(api, id, config) {
531
+ async function updateMonitor(api, id, config, site = "datadoghq.com") {
519
532
  const monitorId = Number.parseInt(id, 10);
520
533
  const body = normalizeMonitorConfig(config, true);
521
534
  const monitor = await api.updateMonitor({ monitorId, body });
522
535
  return {
523
536
  success: true,
524
- monitor: formatMonitor(monitor)
537
+ monitor: formatMonitor(monitor, site)
525
538
  };
526
539
  }
527
540
  async function deleteMonitor(api, id) {
@@ -582,12 +595,12 @@ TIP: For alert HISTORY (which monitors triggered), use the events tool with tags
582
595
  }
583
596
  case "create": {
584
597
  const monitorConfig = requireParam(config, "config", "create");
585
- return toolResult(await createMonitor(api, monitorConfig));
598
+ return toolResult(await createMonitor(api, monitorConfig, site));
586
599
  }
587
600
  case "update": {
588
601
  const monitorId = requireParam(id, "id", "update");
589
602
  const updateConfig = requireParam(config, "config", "update");
590
- return toolResult(await updateMonitor(api, monitorId, updateConfig));
603
+ return toolResult(await updateMonitor(api, monitorId, updateConfig, site));
591
604
  }
592
605
  case "delete": {
593
606
  const monitorId = requireParam(id, "id", "delete");