datadog-mcp 5.7.0 → 5.8.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 +1 -1
- package/dist/index.js +72 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -158,7 +158,7 @@ When running with `--transport=http`:
|
|
|
158
158
|
| `events` | get | Events | Get event by ID | `events_read` |
|
|
159
159
|
| `events` | create | Events | Create an event | `events_read` |
|
|
160
160
|
| `events` | search | Events | Search events with v2 API and cursor pagination. Optional `transitionType` filter (e.g. `["alert","alert recovery"]`) restricts to monitor state-transition events — without it, `source:alert` includes renotifies. For monitor-specific fires use `monitors action=history`. Optional `timezone` adds `*Local` ISO 8601 siblings to every timestamp. Zero-result responses include a `diagnostics` array hinting at the cause (`UNINDEXED_TAG_PREFIX`, `NARROW_TIME_RANGE`, `RESTRICTIVE_SOURCE_FILTER`). | `events_read` |
|
|
161
|
-
| `events` | histogram | Events | Server-side bucketing of events by `hour_of_day`, `day_of_week`, or `day_of_month` in an IANA `timezone` (DST-safe via `Intl.DateTimeFormat`). Cursor-paginates the underlying search; cap at `limits.maxEventsForHistogram` (default 5000, `MCP_MAX_EVENTS_HISTOGRAM` env var). When the cap is hit, returns `bucketCountIncomplete: true` and `nextCursor` for continuation. | `events_read` |
|
|
161
|
+
| `events` | histogram | Events | Server-side bucketing of events by `hour_of_day`, `day_of_week`, or `day_of_month` in an IANA `timezone` (DST-safe via `Intl.DateTimeFormat`). Accepts the same `transitionType` filter as `search` so monitor histograms can exclude renotifies. Cursor-paginates the underlying search; cap at `limits.maxEventsForHistogram` (default 5000, `MCP_MAX_EVENTS_HISTOGRAM` env var). When the cap is hit, returns `bucketCountIncomplete: true` and `nextCursor` for continuation. | `events_read` |
|
|
162
162
|
| `events` | aggregate | Events | Client-side aggregation by monitor_name, source, etc. | `events_read` |
|
|
163
163
|
| `events` | top | Events | Top N event groups by count with generic groupBy support (deployments, configs, alerts, etc.). Groups without context tags are included as "no_context" | `events_read` |
|
|
164
164
|
| `events` | timeseries | Events | Time-bucketed alert trends (hourly/daily counts) | `events_read` |
|
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();
|
|
@@ -303585,7 +303622,8 @@ async function histogramEventsV2(api, params, limits, site) {
|
|
|
303585
303622
|
const fullQuery = buildEventQuery({
|
|
303586
303623
|
query: params.query,
|
|
303587
303624
|
sources: params.sources,
|
|
303588
|
-
tags: params.tags
|
|
303625
|
+
tags: params.tags,
|
|
303626
|
+
transitionType: params.transitionType
|
|
303589
303627
|
});
|
|
303590
303628
|
const cap = limits.maxEventsForHistogram;
|
|
303591
303629
|
const perPage = Math.max(1, Math.min(1e3, cap));
|
|
@@ -304185,7 +304223,8 @@ histogram: Bucket events by local hour_of_day / day_of_week / day_of_month in th
|
|
|
304185
304223
|
maxEvents,
|
|
304186
304224
|
transitionType,
|
|
304187
304225
|
bucket_by,
|
|
304188
|
-
timezone
|
|
304226
|
+
timezone,
|
|
304227
|
+
fields
|
|
304189
304228
|
}) => {
|
|
304190
304229
|
try {
|
|
304191
304230
|
checkReadOnly(action, readOnly);
|
|
@@ -304243,9 +304282,11 @@ histogram: Bucket events by local hour_of_day / day_of_week / day_of_month in th
|
|
|
304243
304282
|
);
|
|
304244
304283
|
if (enrich && result.events.length > 0) {
|
|
304245
304284
|
const enrichedEvents = await enrichWithMonitorMetadata(result.events, monitorsApi);
|
|
304246
|
-
|
|
304285
|
+
const projected = fields?.length ? enrichedEvents.map((e) => pickEventFields(e, fields)) : enrichedEvents;
|
|
304286
|
+
return toolResult({ ...result, events: projected });
|
|
304247
304287
|
}
|
|
304248
|
-
|
|
304288
|
+
const projectedEvents = fields?.length ? result.events.map((e) => pickEventFields(e, fields)) : result.events;
|
|
304289
|
+
return toolResult({ ...result, events: projectedEvents });
|
|
304249
304290
|
}
|
|
304250
304291
|
case "aggregate":
|
|
304251
304292
|
return toolResult(
|
|
@@ -304354,7 +304395,8 @@ histogram: Bucket events by local hour_of_day / day_of_week / day_of_month in th
|
|
|
304354
304395
|
tags,
|
|
304355
304396
|
bucket_by: histogramBucketBy,
|
|
304356
304397
|
timezone,
|
|
304357
|
-
cursor
|
|
304398
|
+
cursor,
|
|
304399
|
+
transitionType
|
|
304358
304400
|
},
|
|
304359
304401
|
limits,
|
|
304360
304402
|
site
|
|
@@ -306797,10 +306839,11 @@ var InputSchema8 = {
|
|
|
306797
306839
|
from: external_exports.string().optional().describe('Start time for history (ISO 8601 or relative like "7d", "1w")'),
|
|
306798
306840
|
to: external_exports.string().optional().describe("End time for history (ISO 8601 or relative, default: now)")
|
|
306799
306841
|
};
|
|
306800
|
-
function formatSlo(s) {
|
|
306842
|
+
function formatSlo(s, site = "datadoghq.com") {
|
|
306801
306843
|
const primaryThreshold = s.thresholds?.[0];
|
|
306844
|
+
const id = s.id ?? "";
|
|
306802
306845
|
const summary = {
|
|
306803
|
-
id
|
|
306846
|
+
id,
|
|
306804
306847
|
name: s.name ?? "",
|
|
306805
306848
|
description: s.description ?? null,
|
|
306806
306849
|
type: String(s.type ?? "unknown"),
|
|
@@ -306815,7 +306858,8 @@ function formatSlo(s) {
|
|
|
306815
306858
|
},
|
|
306816
306859
|
overallStatus: [],
|
|
306817
306860
|
createdAt: s.createdAt ? new Date(s.createdAt * 1e3).toISOString() : "",
|
|
306818
|
-
modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1e3).toISOString() : ""
|
|
306861
|
+
modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1e3).toISOString() : "",
|
|
306862
|
+
url: id ? buildSloUrl(id, site) : ""
|
|
306819
306863
|
};
|
|
306820
306864
|
if (s.query?.numerator && s.query.denominator) {
|
|
306821
306865
|
summary.query = { numerator: s.query.numerator, denominator: s.query.denominator };
|
|
@@ -306831,11 +306875,12 @@ function formatSlo(s) {
|
|
|
306831
306875
|
}
|
|
306832
306876
|
return summary;
|
|
306833
306877
|
}
|
|
306834
|
-
function formatSearchSlo(slo) {
|
|
306878
|
+
function formatSearchSlo(slo, site = "datadoghq.com") {
|
|
306835
306879
|
const attrs = slo.data?.attributes;
|
|
306836
306880
|
const primaryThreshold = attrs?.thresholds?.[0];
|
|
306881
|
+
const id = slo.data?.id ?? "";
|
|
306837
306882
|
const summary = {
|
|
306838
|
-
id
|
|
306883
|
+
id,
|
|
306839
306884
|
name: attrs?.name ?? "",
|
|
306840
306885
|
description: attrs?.description ?? null,
|
|
306841
306886
|
type: String(attrs?.sloType ?? "unknown"),
|
|
@@ -306856,7 +306901,8 @@ function formatSearchSlo(slo) {
|
|
|
306856
306901
|
timeframe: String(os.timeframe ?? "")
|
|
306857
306902
|
})),
|
|
306858
306903
|
createdAt: attrs?.createdAt ? new Date(attrs.createdAt * 1e3).toISOString() : "",
|
|
306859
|
-
modifiedAt: attrs?.modifiedAt ? new Date(attrs.modifiedAt * 1e3).toISOString() : ""
|
|
306904
|
+
modifiedAt: attrs?.modifiedAt ? new Date(attrs.modifiedAt * 1e3).toISOString() : "",
|
|
306905
|
+
url: id ? buildSloUrl(id, site) : ""
|
|
306860
306906
|
};
|
|
306861
306907
|
if (attrs?.query?.numerator && attrs.query.denominator) {
|
|
306862
306908
|
summary.query = { numerator: attrs.query.numerator, denominator: attrs.query.denominator };
|
|
@@ -306875,14 +306921,14 @@ function buildSearchQuery(query, tags) {
|
|
|
306875
306921
|
if (tags?.length) parts.push(...tags);
|
|
306876
306922
|
return parts.join(" ");
|
|
306877
306923
|
}
|
|
306878
|
-
async function listSlos(api, params, limits) {
|
|
306924
|
+
async function listSlos(api, params, limits, site = "datadoghq.com") {
|
|
306879
306925
|
const effectiveLimit = params.limit ?? limits.defaultLimit;
|
|
306880
306926
|
if (params.ids?.length) {
|
|
306881
306927
|
const response2 = await api.listSLOs({
|
|
306882
306928
|
ids: params.ids.join(","),
|
|
306883
306929
|
limit: effectiveLimit
|
|
306884
306930
|
});
|
|
306885
|
-
const slos3 = (response2.data ?? []).map(formatSlo);
|
|
306931
|
+
const slos3 = (response2.data ?? []).map((s) => formatSlo(s, site));
|
|
306886
306932
|
return { slos: slos3, total: slos3.length };
|
|
306887
306933
|
}
|
|
306888
306934
|
const searchQuery = buildSearchQuery(params.query, params.tags);
|
|
@@ -306891,16 +306937,16 @@ async function listSlos(api, params, limits) {
|
|
|
306891
306937
|
pageSize: effectiveLimit
|
|
306892
306938
|
});
|
|
306893
306939
|
const searchSlos = response.data?.attributes?.slos ?? [];
|
|
306894
|
-
const slos2 = searchSlos.map(formatSearchSlo);
|
|
306940
|
+
const slos2 = searchSlos.map((s) => formatSearchSlo(s, site));
|
|
306895
306941
|
return {
|
|
306896
306942
|
slos: slos2,
|
|
306897
306943
|
total: slos2.length
|
|
306898
306944
|
};
|
|
306899
306945
|
}
|
|
306900
|
-
async function getSlo(api, id) {
|
|
306946
|
+
async function getSlo(api, id, site = "datadoghq.com") {
|
|
306901
306947
|
const response = await api.getSLO({ sloId: id });
|
|
306902
306948
|
return {
|
|
306903
|
-
slo: response.data ? formatSlo(response.data) : null
|
|
306949
|
+
slo: response.data ? formatSlo(response.data, site) : null
|
|
306904
306950
|
};
|
|
306905
306951
|
}
|
|
306906
306952
|
function normalizeSloConfig(config2) {
|
|
@@ -306916,20 +306962,20 @@ function normalizeSloConfig(config2) {
|
|
|
306916
306962
|
}
|
|
306917
306963
|
return normalized;
|
|
306918
306964
|
}
|
|
306919
|
-
async function createSlo(api, config2) {
|
|
306965
|
+
async function createSlo(api, config2, site = "datadoghq.com") {
|
|
306920
306966
|
const body = normalizeSloConfig(config2);
|
|
306921
306967
|
const response = await api.createSLO({ body });
|
|
306922
306968
|
return {
|
|
306923
306969
|
success: true,
|
|
306924
|
-
slo: response.data?.[0] ? formatSlo(response.data[0]) : null
|
|
306970
|
+
slo: response.data?.[0] ? formatSlo(response.data[0], site) : null
|
|
306925
306971
|
};
|
|
306926
306972
|
}
|
|
306927
|
-
async function updateSlo(api, id, config2) {
|
|
306973
|
+
async function updateSlo(api, id, config2, site = "datadoghq.com") {
|
|
306928
306974
|
const body = normalizeConfigKeys(config2);
|
|
306929
306975
|
const response = await api.updateSLO({ sloId: id, body });
|
|
306930
306976
|
return {
|
|
306931
306977
|
success: true,
|
|
306932
|
-
slo: response.data?.[0] ? formatSlo(response.data[0]) : null
|
|
306978
|
+
slo: response.data?.[0] ? formatSlo(response.data[0], site) : null
|
|
306933
306979
|
};
|
|
306934
306980
|
}
|
|
306935
306981
|
async function deleteSlo(api, id) {
|
|
@@ -306969,29 +307015,29 @@ async function getSloHistory(api, id, params) {
|
|
|
306969
307015
|
}
|
|
306970
307016
|
};
|
|
306971
307017
|
}
|
|
306972
|
-
function registerSlosTool(server, api, limits, readOnly = false,
|
|
307018
|
+
function registerSlosTool(server, api, limits, readOnly = false, site = "datadoghq.com") {
|
|
306973
307019
|
server.tool(
|
|
306974
307020
|
"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.",
|
|
307021
|
+
"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
307022
|
InputSchema8,
|
|
306977
307023
|
async ({ action, id, ids, query, tags, limit, config: config2, from, to }) => {
|
|
306978
307024
|
try {
|
|
306979
307025
|
checkReadOnly(action, readOnly);
|
|
306980
307026
|
switch (action) {
|
|
306981
307027
|
case "list":
|
|
306982
|
-
return toolResult(await listSlos(api, { ids, query, tags, limit }, limits));
|
|
307028
|
+
return toolResult(await listSlos(api, { ids, query, tags, limit }, limits, site));
|
|
306983
307029
|
case "get": {
|
|
306984
307030
|
const sloId = requireParam(id, "id", "get");
|
|
306985
|
-
return toolResult(await getSlo(api, sloId));
|
|
307031
|
+
return toolResult(await getSlo(api, sloId, site));
|
|
306986
307032
|
}
|
|
306987
307033
|
case "create": {
|
|
306988
307034
|
const sloConfig = requireParam(config2, "config", "create");
|
|
306989
|
-
return toolResult(await createSlo(api, sloConfig));
|
|
307035
|
+
return toolResult(await createSlo(api, sloConfig, site));
|
|
306990
307036
|
}
|
|
306991
307037
|
case "update": {
|
|
306992
307038
|
const sloId = requireParam(id, "id", "update");
|
|
306993
307039
|
const sloConfig = requireParam(config2, "config", "update");
|
|
306994
|
-
return toolResult(await updateSlo(api, sloId, sloConfig));
|
|
307040
|
+
return toolResult(await updateSlo(api, sloId, sloConfig, site));
|
|
306995
307041
|
}
|
|
306996
307042
|
case "delete": {
|
|
306997
307043
|
const sloId = requireParam(id, "id", "delete");
|