datadog-mcp 5.3.0 → 5.3.2
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 +2 -1
- package/dist/index.js +67 -14
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -461,7 +461,8 @@ Note: Enrichment adds latency (fetches monitor list). Use for detailed investiga
|
|
|
461
461
|
1. **Find errors in logs**: `logs({ action: "search", status: "error", sample: "diverse" })`
|
|
462
462
|
2. **Extract trace_id** from log attributes (`dd.trace_id`)
|
|
463
463
|
3. **Get full trace**: `traces({ action: "search", query: "trace_id:<id>" })`
|
|
464
|
-
4. **Query APM metrics
|
|
464
|
+
4. **Query APM metrics** (avg): `metrics({ action: "query", query: "avg:trace.express.request.duration{service:my-service}" })`
|
|
465
|
+
5. **Query APM latency percentiles** (p95): `metrics({ action: "query", query: "p95:trace.express.request{service:my-service}" })` — note: use root metric without `.duration` suffix for percentiles
|
|
465
466
|
|
|
466
467
|
## Deep Links
|
|
467
468
|
|
package/dist/index.js
CHANGED
|
@@ -2572,10 +2572,21 @@ function registerMetricsTool(server, metricsV1Api, metricsV2Api, limits, site =
|
|
|
2572
2572
|
- metadata: Get metric details (unit, type, description)
|
|
2573
2573
|
|
|
2574
2574
|
APM METRICS (auto-generated from traces):
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2575
|
+
Keyed by OPERATION name (e.g. express.request, pg.query), NOT service name.
|
|
2576
|
+
Filter by service using tags: {service:my-service}
|
|
2577
|
+
|
|
2578
|
+
PERCENTILES (p50/p75/p90/p95/p99) \u2014 use the ROOT metric (distribution type):
|
|
2579
|
+
p95:trace.express.request{service:my-service}
|
|
2580
|
+
|
|
2581
|
+
AVG/SUM/MIN/MAX \u2014 use the .duration SUFFIX (pre-aggregated gauge):
|
|
2582
|
+
avg:trace.express.request.duration{service:my-service}
|
|
2583
|
+
|
|
2584
|
+
Other trace metrics (gauges):
|
|
2585
|
+
- trace.<operation>.hits - Request count
|
|
2586
|
+
- trace.<operation>.errors - Error count
|
|
2587
|
+
- trace.<operation>.apdex - Apdex score
|
|
2588
|
+
|
|
2589
|
+
To discover operation names for a service, use: traces tool with action "services"`,
|
|
2579
2590
|
InputSchema5,
|
|
2580
2591
|
async ({ action, query, from, to, metric, limit, pointLimit }) => {
|
|
2581
2592
|
try {
|
|
@@ -2923,7 +2934,7 @@ function registerTracesTool(server, spansApi, _servicesApi, limits, site = "data
|
|
|
2923
2934
|
server.tool(
|
|
2924
2935
|
"traces",
|
|
2925
2936
|
`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).
|
|
2926
|
-
APM METRICS: Traces auto-generate metrics in trace
|
|
2937
|
+
APM METRICS: Traces auto-generate metrics in trace.<operation>.* namespace (e.g. trace.express.request). Use metrics tool to query: avg:trace.express.request.duration{service:my-service}. For percentiles (p95), use the root metric WITHOUT .duration suffix: p95:trace.express.request{service:my-service}`,
|
|
2927
2938
|
InputSchema6,
|
|
2928
2939
|
async ({
|
|
2929
2940
|
action,
|
|
@@ -3186,27 +3197,69 @@ function formatSlo(s) {
|
|
|
3186
3197
|
timeframe: String(primaryThreshold?.timeframe ?? ""),
|
|
3187
3198
|
tags: s.tags ?? [],
|
|
3188
3199
|
status: {
|
|
3189
|
-
// Note: SLI status requires a separate API call to getSLOHistory
|
|
3190
3200
|
sli: null,
|
|
3191
3201
|
errorBudgetRemaining: null,
|
|
3192
3202
|
state: "unknown"
|
|
3193
3203
|
},
|
|
3204
|
+
overallStatus: [],
|
|
3194
3205
|
createdAt: s.createdAt ? new Date(s.createdAt * 1e3).toISOString() : "",
|
|
3195
3206
|
modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1e3).toISOString() : ""
|
|
3196
3207
|
};
|
|
3197
3208
|
}
|
|
3209
|
+
function formatSearchSlo(slo) {
|
|
3210
|
+
const attrs = slo.data?.attributes;
|
|
3211
|
+
const primaryThreshold = attrs?.thresholds?.[0];
|
|
3212
|
+
return {
|
|
3213
|
+
id: slo.data?.id ?? "",
|
|
3214
|
+
name: attrs?.name ?? "",
|
|
3215
|
+
description: attrs?.description ?? null,
|
|
3216
|
+
type: String(attrs?.sloType ?? "unknown"),
|
|
3217
|
+
targetThreshold: primaryThreshold?.target ?? 0,
|
|
3218
|
+
warningThreshold: primaryThreshold?.warning ?? null,
|
|
3219
|
+
timeframe: String(primaryThreshold?.timeframe ?? ""),
|
|
3220
|
+
tags: attrs?.allTags ?? [],
|
|
3221
|
+
status: {
|
|
3222
|
+
sli: attrs?.status?.sli ?? null,
|
|
3223
|
+
errorBudgetRemaining: attrs?.status?.errorBudgetRemaining ?? null,
|
|
3224
|
+
state: String(attrs?.status?.state ?? "unknown")
|
|
3225
|
+
},
|
|
3226
|
+
overallStatus: (attrs?.overallStatus ?? []).map((os) => ({
|
|
3227
|
+
sli: os.status ?? null,
|
|
3228
|
+
errorBudgetRemaining: os.errorBudgetRemaining ?? null,
|
|
3229
|
+
state: String(os.state ?? "unknown"),
|
|
3230
|
+
target: os.target ?? null,
|
|
3231
|
+
timeframe: String(os.timeframe ?? "")
|
|
3232
|
+
})),
|
|
3233
|
+
createdAt: attrs?.createdAt ? new Date(attrs.createdAt * 1e3).toISOString() : "",
|
|
3234
|
+
modifiedAt: attrs?.modifiedAt ? new Date(attrs.modifiedAt * 1e3).toISOString() : ""
|
|
3235
|
+
};
|
|
3236
|
+
}
|
|
3237
|
+
function buildSearchQuery(query, tags) {
|
|
3238
|
+
const parts = [];
|
|
3239
|
+
if (query) parts.push(query);
|
|
3240
|
+
if (tags?.length) parts.push(...tags);
|
|
3241
|
+
return parts.join(" ");
|
|
3242
|
+
}
|
|
3198
3243
|
async function listSlos(api, params, limits) {
|
|
3199
3244
|
const effectiveLimit = params.limit ?? limits.defaultLimit;
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3245
|
+
if (params.ids?.length) {
|
|
3246
|
+
const response2 = await api.listSLOs({
|
|
3247
|
+
ids: params.ids.join(","),
|
|
3248
|
+
limit: effectiveLimit
|
|
3249
|
+
});
|
|
3250
|
+
const slos3 = (response2.data ?? []).map(formatSlo);
|
|
3251
|
+
return { slos: slos3, total: slos3.length };
|
|
3252
|
+
}
|
|
3253
|
+
const searchQuery = buildSearchQuery(params.query, params.tags);
|
|
3254
|
+
const response = await api.searchSLO({
|
|
3255
|
+
query: searchQuery || void 0,
|
|
3256
|
+
pageSize: effectiveLimit
|
|
3205
3257
|
});
|
|
3206
|
-
const
|
|
3258
|
+
const searchSlos = response.data?.attributes?.slos ?? [];
|
|
3259
|
+
const slos2 = searchSlos.map(formatSearchSlo);
|
|
3207
3260
|
return {
|
|
3208
3261
|
slos: slos2,
|
|
3209
|
-
total:
|
|
3262
|
+
total: slos2.length
|
|
3210
3263
|
};
|
|
3211
3264
|
}
|
|
3212
3265
|
async function getSlo(api, id) {
|
|
@@ -3298,7 +3351,7 @@ async function getSloHistory(api, id, params) {
|
|
|
3298
3351
|
function registerSlosTool(server, api, limits, readOnly = false, _site = "datadoghq.com") {
|
|
3299
3352
|
server.tool(
|
|
3300
3353
|
"slos",
|
|
3301
|
-
"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.",
|
|
3354
|
+
"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.",
|
|
3302
3355
|
InputSchema8,
|
|
3303
3356
|
async ({ action, id, ids, query, tags, limit, config, from, to }) => {
|
|
3304
3357
|
try {
|