datadog-mcp 5.7.0 → 5.8.0

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
@@ -302786,6 +302786,10 @@ function buildRumSessionUrl(applicationId, sessionId, site = "datadoghq.com") {
302786
302786
  const base = getAppBaseUrl(site);
302787
302787
  return `${base}/rum/replay/sessions/${sessionId}?applicationId=${encodeURIComponent(applicationId)}`;
302788
302788
  }
302789
+ function buildSloUrl(sloId, site = "datadoghq.com") {
302790
+ const base = getAppBaseUrl(site);
302791
+ return `${base}/slo/${sloId}`;
302792
+ }
302789
302793
 
302790
302794
  // src/utils/time.ts
302791
302795
  function hoursAgo(hours) {
@@ -303150,8 +303154,41 @@ var InputSchema = {
303150
303154
  ),
303151
303155
  timezone: external_exports.string().optional().describe(
303152
303156
  'Optional IANA timezone (e.g. "UTC", "Europe/Paris"). DST-safe. For histogram: controls hour/day bucketing (default: UTC). For search/aggregate/top/incidents read actions: adds sibling *Local ISO 8601 strings (e.g. timestampLocal) next to existing timestamps. Omit for byte-identical legacy shape.'
303157
+ ),
303158
+ // Projection — applied to search action only. Reduces response payload
303159
+ // when callers only need a subset of fields. Unknown field names are silently ignored so
303160
+ // older clients are not broken when the EventSummary shape evolves.
303161
+ fields: external_exports.array(external_exports.string()).optional().describe(
303162
+ "Search action only: return only these event fields. Allowed values: id, title, message, timestamp, priority, source, tags, alertType, host, monitorId, monitorInfo, monitorMetadata (only populated when enrich=true). Default: full event."
303153
303163
  )
303154
303164
  };
303165
+ var ALLOWED_EVENT_FIELDS = /* @__PURE__ */ new Set([
303166
+ "id",
303167
+ "title",
303168
+ "message",
303169
+ "timestamp",
303170
+ "priority",
303171
+ "source",
303172
+ "tags",
303173
+ "alertType",
303174
+ "host",
303175
+ "monitorId",
303176
+ "monitorInfo",
303177
+ "monitorMetadata"
303178
+ ]);
303179
+ function pickEventFields(event, fields) {
303180
+ if (!fields || fields.length === 0) {
303181
+ return event;
303182
+ }
303183
+ const projection = {};
303184
+ for (const key of fields) {
303185
+ if (ALLOWED_EVENT_FIELDS.has(key)) {
303186
+ ;
303187
+ projection[key] = event[key];
303188
+ }
303189
+ }
303190
+ return projection;
303191
+ }
303155
303192
  function annotateEventTimezone(event, tz) {
303156
303193
  if (!event.timestamp) return event;
303157
303194
  const ms = new Date(event.timestamp).getTime();
@@ -304185,7 +304222,8 @@ histogram: Bucket events by local hour_of_day / day_of_week / day_of_month in th
304185
304222
  maxEvents,
304186
304223
  transitionType,
304187
304224
  bucket_by,
304188
- timezone
304225
+ timezone,
304226
+ fields
304189
304227
  }) => {
304190
304228
  try {
304191
304229
  checkReadOnly(action, readOnly);
@@ -304243,9 +304281,11 @@ histogram: Bucket events by local hour_of_day / day_of_week / day_of_month in th
304243
304281
  );
304244
304282
  if (enrich && result.events.length > 0) {
304245
304283
  const enrichedEvents = await enrichWithMonitorMetadata(result.events, monitorsApi);
304246
- return toolResult({ ...result, events: enrichedEvents });
304284
+ const projected = fields?.length ? enrichedEvents.map((e) => pickEventFields(e, fields)) : enrichedEvents;
304285
+ return toolResult({ ...result, events: projected });
304247
304286
  }
304248
- return toolResult(result);
304287
+ const projectedEvents = fields?.length ? result.events.map((e) => pickEventFields(e, fields)) : result.events;
304288
+ return toolResult({ ...result, events: projectedEvents });
304249
304289
  }
304250
304290
  case "aggregate":
304251
304291
  return toolResult(
@@ -306797,10 +306837,11 @@ var InputSchema8 = {
306797
306837
  from: external_exports.string().optional().describe('Start time for history (ISO 8601 or relative like "7d", "1w")'),
306798
306838
  to: external_exports.string().optional().describe("End time for history (ISO 8601 or relative, default: now)")
306799
306839
  };
306800
- function formatSlo(s) {
306840
+ function formatSlo(s, site = "datadoghq.com") {
306801
306841
  const primaryThreshold = s.thresholds?.[0];
306842
+ const id = s.id ?? "";
306802
306843
  const summary = {
306803
- id: s.id ?? "",
306844
+ id,
306804
306845
  name: s.name ?? "",
306805
306846
  description: s.description ?? null,
306806
306847
  type: String(s.type ?? "unknown"),
@@ -306815,7 +306856,8 @@ function formatSlo(s) {
306815
306856
  },
306816
306857
  overallStatus: [],
306817
306858
  createdAt: s.createdAt ? new Date(s.createdAt * 1e3).toISOString() : "",
306818
- modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1e3).toISOString() : ""
306859
+ modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1e3).toISOString() : "",
306860
+ url: id ? buildSloUrl(id, site) : ""
306819
306861
  };
306820
306862
  if (s.query?.numerator && s.query.denominator) {
306821
306863
  summary.query = { numerator: s.query.numerator, denominator: s.query.denominator };
@@ -306831,11 +306873,12 @@ function formatSlo(s) {
306831
306873
  }
306832
306874
  return summary;
306833
306875
  }
306834
- function formatSearchSlo(slo) {
306876
+ function formatSearchSlo(slo, site = "datadoghq.com") {
306835
306877
  const attrs = slo.data?.attributes;
306836
306878
  const primaryThreshold = attrs?.thresholds?.[0];
306879
+ const id = slo.data?.id ?? "";
306837
306880
  const summary = {
306838
- id: slo.data?.id ?? "",
306881
+ id,
306839
306882
  name: attrs?.name ?? "",
306840
306883
  description: attrs?.description ?? null,
306841
306884
  type: String(attrs?.sloType ?? "unknown"),
@@ -306856,7 +306899,8 @@ function formatSearchSlo(slo) {
306856
306899
  timeframe: String(os.timeframe ?? "")
306857
306900
  })),
306858
306901
  createdAt: attrs?.createdAt ? new Date(attrs.createdAt * 1e3).toISOString() : "",
306859
- modifiedAt: attrs?.modifiedAt ? new Date(attrs.modifiedAt * 1e3).toISOString() : ""
306902
+ modifiedAt: attrs?.modifiedAt ? new Date(attrs.modifiedAt * 1e3).toISOString() : "",
306903
+ url: id ? buildSloUrl(id, site) : ""
306860
306904
  };
306861
306905
  if (attrs?.query?.numerator && attrs.query.denominator) {
306862
306906
  summary.query = { numerator: attrs.query.numerator, denominator: attrs.query.denominator };
@@ -306875,14 +306919,14 @@ function buildSearchQuery(query, tags) {
306875
306919
  if (tags?.length) parts.push(...tags);
306876
306920
  return parts.join(" ");
306877
306921
  }
306878
- async function listSlos(api, params, limits) {
306922
+ async function listSlos(api, params, limits, site = "datadoghq.com") {
306879
306923
  const effectiveLimit = params.limit ?? limits.defaultLimit;
306880
306924
  if (params.ids?.length) {
306881
306925
  const response2 = await api.listSLOs({
306882
306926
  ids: params.ids.join(","),
306883
306927
  limit: effectiveLimit
306884
306928
  });
306885
- const slos3 = (response2.data ?? []).map(formatSlo);
306929
+ const slos3 = (response2.data ?? []).map((s) => formatSlo(s, site));
306886
306930
  return { slos: slos3, total: slos3.length };
306887
306931
  }
306888
306932
  const searchQuery = buildSearchQuery(params.query, params.tags);
@@ -306891,16 +306935,16 @@ async function listSlos(api, params, limits) {
306891
306935
  pageSize: effectiveLimit
306892
306936
  });
306893
306937
  const searchSlos = response.data?.attributes?.slos ?? [];
306894
- const slos2 = searchSlos.map(formatSearchSlo);
306938
+ const slos2 = searchSlos.map((s) => formatSearchSlo(s, site));
306895
306939
  return {
306896
306940
  slos: slos2,
306897
306941
  total: slos2.length
306898
306942
  };
306899
306943
  }
306900
- async function getSlo(api, id) {
306944
+ async function getSlo(api, id, site = "datadoghq.com") {
306901
306945
  const response = await api.getSLO({ sloId: id });
306902
306946
  return {
306903
- slo: response.data ? formatSlo(response.data) : null
306947
+ slo: response.data ? formatSlo(response.data, site) : null
306904
306948
  };
306905
306949
  }
306906
306950
  function normalizeSloConfig(config2) {
@@ -306916,20 +306960,20 @@ function normalizeSloConfig(config2) {
306916
306960
  }
306917
306961
  return normalized;
306918
306962
  }
306919
- async function createSlo(api, config2) {
306963
+ async function createSlo(api, config2, site = "datadoghq.com") {
306920
306964
  const body = normalizeSloConfig(config2);
306921
306965
  const response = await api.createSLO({ body });
306922
306966
  return {
306923
306967
  success: true,
306924
- slo: response.data?.[0] ? formatSlo(response.data[0]) : null
306968
+ slo: response.data?.[0] ? formatSlo(response.data[0], site) : null
306925
306969
  };
306926
306970
  }
306927
- async function updateSlo(api, id, config2) {
306971
+ async function updateSlo(api, id, config2, site = "datadoghq.com") {
306928
306972
  const body = normalizeConfigKeys(config2);
306929
306973
  const response = await api.updateSLO({ sloId: id, body });
306930
306974
  return {
306931
306975
  success: true,
306932
- slo: response.data?.[0] ? formatSlo(response.data[0]) : null
306976
+ slo: response.data?.[0] ? formatSlo(response.data[0], site) : null
306933
306977
  };
306934
306978
  }
306935
306979
  async function deleteSlo(api, id) {
@@ -306969,29 +307013,29 @@ async function getSloHistory(api, id, params) {
306969
307013
  }
306970
307014
  };
306971
307015
  }
306972
- function registerSlosTool(server, api, limits, readOnly = false, _site = "datadoghq.com") {
307016
+ function registerSlosTool(server, api, limits, readOnly = false, site = "datadoghq.com") {
306973
307017
  server.tool(
306974
307018
  "slos",
306975
- "Manage Datadog Service Level Objectives. Actions: list (with SLI status & error budget), get, create, update, delete, history. SLO types: metric-based, monitor-based. Use for: reliability tracking, error budgets, SLA compliance, performance targets.",
307019
+ "Manage Datadog Service Level Objectives. Actions: list (with SLI status & error budget), get, create, update, delete, history. SLO types: metric-based, monitor-based. Each list/get/create/update response includes a `url` field deep-linking to the Datadog UI. Use for: reliability tracking, error budgets, SLA compliance, performance targets.",
306976
307020
  InputSchema8,
306977
307021
  async ({ action, id, ids, query, tags, limit, config: config2, from, to }) => {
306978
307022
  try {
306979
307023
  checkReadOnly(action, readOnly);
306980
307024
  switch (action) {
306981
307025
  case "list":
306982
- return toolResult(await listSlos(api, { ids, query, tags, limit }, limits));
307026
+ return toolResult(await listSlos(api, { ids, query, tags, limit }, limits, site));
306983
307027
  case "get": {
306984
307028
  const sloId = requireParam(id, "id", "get");
306985
- return toolResult(await getSlo(api, sloId));
307029
+ return toolResult(await getSlo(api, sloId, site));
306986
307030
  }
306987
307031
  case "create": {
306988
307032
  const sloConfig = requireParam(config2, "config", "create");
306989
- return toolResult(await createSlo(api, sloConfig));
307033
+ return toolResult(await createSlo(api, sloConfig, site));
306990
307034
  }
306991
307035
  case "update": {
306992
307036
  const sloId = requireParam(id, "id", "update");
306993
307037
  const sloConfig = requireParam(config2, "config", "update");
306994
- return toolResult(await updateSlo(api, sloId, sloConfig));
307038
+ return toolResult(await updateSlo(api, sloId, sloConfig, site));
306995
307039
  }
306996
307040
  case "delete": {
306997
307041
  const sloId = requireParam(id, "id", "delete");