datadog-mcp 1.0.5 → 1.0.6

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 CHANGED
@@ -454,9 +454,9 @@ async function searchMonitors(api, query, limits, site) {
454
454
  datadog_url: buildMonitorsListUrl(query, site)
455
455
  };
456
456
  }
457
- function normalizeMonitorConfig(config) {
457
+ function normalizeMonitorConfig(config, isUpdate = false) {
458
458
  const normalized = { ...config };
459
- if (!normalized.name && !normalized.type && !normalized.query) {
459
+ if (!isUpdate && !normalized.name && !normalized.type && !normalized.query) {
460
460
  throw new Error("Monitor config requires at least 'name', 'type', and 'query' fields");
461
461
  }
462
462
  if (normalized.options && typeof normalized.options === "object") {
@@ -515,7 +515,7 @@ async function createMonitor(api, config) {
515
515
  }
516
516
  async function updateMonitor(api, id, config) {
517
517
  const monitorId = Number.parseInt(id, 10);
518
- const body = normalizeMonitorConfig(config);
518
+ const body = normalizeMonitorConfig(config, true);
519
519
  const monitor = await api.updateMonitor({ monitorId, body });
520
520
  return {
521
521
  success: true,
@@ -673,6 +673,17 @@ function normalizeDashboardConfig(config) {
673
673
  if (!normalized.layoutType) {
674
674
  throw new Error("Dashboard config requires 'layoutType' (e.g., 'ordered', 'free')");
675
675
  }
676
+ if (normalized.tags && Array.isArray(normalized.tags)) {
677
+ const invalidTags = normalized.tags.filter((tag) => {
678
+ if (typeof tag !== "string") return true;
679
+ return !tag.startsWith("team:");
680
+ });
681
+ if (invalidTags.length > 0) {
682
+ throw new Error(
683
+ `Dashboard tags must use 'team:' prefix. Invalid tags: ${invalidTags.join(", ")}. Example: ["team:operations", "team:frontend"]`
684
+ );
685
+ }
686
+ }
676
687
  return normalized;
677
688
  }
678
689
  async function createDashboard(api, config) {
@@ -706,7 +717,7 @@ async function deleteDashboard(api, id) {
706
717
  function registerDashboardsTool(server, api, limits, readOnly = false, _site = "datadoghq.com") {
707
718
  server.tool(
708
719
  "dashboards",
709
- "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.",
720
+ '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"]).',
710
721
  InputSchema2,
711
722
  async ({ action, id, name, tags, limit, config }) => {
712
723
  try {
@@ -3258,11 +3269,29 @@ async function getDowntime(api, id) {
3258
3269
  downtime: response.data ? formatDowntime(response.data) : null
3259
3270
  };
3260
3271
  }
3272
+ function normalizeDowntimeConfig(config) {
3273
+ const normalized = { ...config };
3274
+ if (normalized.schedule && typeof normalized.schedule === "object") {
3275
+ const schedule = { ...normalized.schedule };
3276
+ const isRecurring = "duration" in schedule && "rrule" in schedule;
3277
+ if (!isRecurring) {
3278
+ if (schedule.start && typeof schedule.start === "string") {
3279
+ schedule.start = new Date(schedule.start);
3280
+ }
3281
+ if (schedule.end && typeof schedule.end === "string") {
3282
+ schedule.end = new Date(schedule.end);
3283
+ }
3284
+ }
3285
+ normalized.schedule = schedule;
3286
+ }
3287
+ return normalized;
3288
+ }
3261
3289
  async function createDowntime(api, config) {
3290
+ const normalizedConfig = normalizeDowntimeConfig(config);
3262
3291
  const body = {
3263
3292
  data: {
3264
3293
  type: "downtime",
3265
- attributes: config
3294
+ attributes: normalizedConfig
3266
3295
  }
3267
3296
  };
3268
3297
  const response = await api.createDowntime({ body });
@@ -3272,11 +3301,12 @@ async function createDowntime(api, config) {
3272
3301
  };
3273
3302
  }
3274
3303
  async function updateDowntime(api, id, config) {
3304
+ const normalizedConfig = normalizeDowntimeConfig(config);
3275
3305
  const body = {
3276
3306
  data: {
3277
3307
  type: "downtime",
3278
3308
  id,
3279
- attributes: config
3309
+ attributes: normalizedConfig
3280
3310
  }
3281
3311
  };
3282
3312
  const response = await api.updateDowntime({ downtimeId: id, body });