datadog-mcp 5.3.4 → 5.5.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/README.md +11 -2
- package/dist/index.js +704 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -134929,7 +134929,7 @@ var require_InputSchema = __commonJS({
|
|
|
134929
134929
|
"use strict";
|
|
134930
134930
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
134931
134931
|
exports.InputSchema = void 0;
|
|
134932
|
-
var
|
|
134932
|
+
var InputSchema24 = class _InputSchema {
|
|
134933
134933
|
constructor() {
|
|
134934
134934
|
}
|
|
134935
134935
|
/**
|
|
@@ -134939,8 +134939,8 @@ var require_InputSchema = __commonJS({
|
|
|
134939
134939
|
return _InputSchema.attributeTypeMap;
|
|
134940
134940
|
}
|
|
134941
134941
|
};
|
|
134942
|
-
exports.InputSchema =
|
|
134943
|
-
|
|
134942
|
+
exports.InputSchema = InputSchema24;
|
|
134943
|
+
InputSchema24.attributeTypeMap = {
|
|
134944
134944
|
parameters: {
|
|
134945
134945
|
baseName: "parameters",
|
|
134946
134946
|
type: "Array<InputSchemaParameters>"
|
|
@@ -281731,10 +281731,10 @@ var require_object_inspect = __commonJS({
|
|
|
281731
281731
|
}
|
|
281732
281732
|
if (!isDate(obj) && !isRegExp(obj)) {
|
|
281733
281733
|
var ys = arrObjKeys(obj, inspect);
|
|
281734
|
-
var
|
|
281734
|
+
var isPlainObject4 = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
|
|
281735
281735
|
var protoTag = obj instanceof Object ? "" : "null prototype";
|
|
281736
|
-
var stringTag = !
|
|
281737
|
-
var constructorTag =
|
|
281736
|
+
var stringTag = !isPlainObject4 && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : "";
|
|
281737
|
+
var constructorTag = isPlainObject4 || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : "";
|
|
281738
281738
|
var tag = constructorTag + (stringTag || protoTag ? "[" + $join.call($concat.call([], stringTag || [], protoTag || []), ": ") + "] " : "");
|
|
281739
281739
|
if (ys.length === 0) {
|
|
281740
281740
|
return tag + "{}";
|
|
@@ -302583,7 +302583,10 @@ function createDatadogClients(config2) {
|
|
|
302583
302583
|
usage: new import_datadog_api_client.v1.UsageMeteringApi(configuration),
|
|
302584
302584
|
spans: new import_datadog_api_client.v2.SpansApi(configuration),
|
|
302585
302585
|
services: new import_datadog_api_client.v2.ServiceDefinitionApi(configuration),
|
|
302586
|
-
auth: new import_datadog_api_client.v1.AuthenticationApi(configuration)
|
|
302586
|
+
auth: new import_datadog_api_client.v1.AuthenticationApi(configuration),
|
|
302587
|
+
logsPipelines: new import_datadog_api_client.v1.LogsPipelinesApi(configuration),
|
|
302588
|
+
logsIndexes: new import_datadog_api_client.v1.LogsIndexesApi(configuration),
|
|
302589
|
+
logsArchives: new import_datadog_api_client.v2.LogsArchivesApi(configuration)
|
|
302587
302590
|
};
|
|
302588
302591
|
}
|
|
302589
302592
|
|
|
@@ -302661,7 +302664,8 @@ var WRITE_ACTIONS = /* @__PURE__ */ new Set([
|
|
|
302661
302664
|
"unmute",
|
|
302662
302665
|
"cancel",
|
|
302663
302666
|
"add",
|
|
302664
|
-
"trigger"
|
|
302667
|
+
"trigger",
|
|
302668
|
+
"reorder"
|
|
302665
302669
|
]);
|
|
302666
302670
|
function checkReadOnly(action, readOnly) {
|
|
302667
302671
|
if (readOnly && WRITE_ACTIONS.has(action)) {
|
|
@@ -303905,6 +303909,98 @@ var InputSchema2 = {
|
|
|
303905
303909
|
),
|
|
303906
303910
|
maxEvents: external_exports.number().min(1).max(5e3).optional().describe("Maximum events to fetch for top action (default: 5000, max: 5000)")
|
|
303907
303911
|
};
|
|
303912
|
+
var MonitorThresholdsSchema = external_exports.object({
|
|
303913
|
+
critical: external_exports.number().optional(),
|
|
303914
|
+
warning: external_exports.number().optional(),
|
|
303915
|
+
ok: external_exports.number().optional(),
|
|
303916
|
+
criticalRecovery: external_exports.number().optional(),
|
|
303917
|
+
warningRecovery: external_exports.number().optional(),
|
|
303918
|
+
unknown: external_exports.number().optional()
|
|
303919
|
+
}).passthrough();
|
|
303920
|
+
var MonitorThresholdWindowsSchema = external_exports.object({
|
|
303921
|
+
triggerWindow: external_exports.string().optional(),
|
|
303922
|
+
recoveryWindow: external_exports.string().optional()
|
|
303923
|
+
}).passthrough();
|
|
303924
|
+
var SchedulingOptionsSchema = external_exports.object({
|
|
303925
|
+
evaluationWindow: external_exports.record(external_exports.unknown()).optional(),
|
|
303926
|
+
customSchedule: external_exports.record(external_exports.unknown()).optional()
|
|
303927
|
+
}).passthrough();
|
|
303928
|
+
var MonitorOptionsSchema = external_exports.object({
|
|
303929
|
+
// Notification
|
|
303930
|
+
notifyNoData: external_exports.boolean().optional(),
|
|
303931
|
+
noDataTimeframe: external_exports.number().optional(),
|
|
303932
|
+
notifyAudit: external_exports.boolean().optional(),
|
|
303933
|
+
notificationPresetName: external_exports.string().optional(),
|
|
303934
|
+
// Evaluation / delay
|
|
303935
|
+
newHostDelay: external_exports.number().optional(),
|
|
303936
|
+
newGroupDelay: external_exports.number().optional(),
|
|
303937
|
+
evaluationDelay: external_exports.number().optional(),
|
|
303938
|
+
requireFullWindow: external_exports.boolean().optional(),
|
|
303939
|
+
onMissingData: external_exports.string().optional(),
|
|
303940
|
+
// Renotification
|
|
303941
|
+
renotifyInterval: external_exports.number().nullable().optional(),
|
|
303942
|
+
renotifyOccurrences: external_exports.number().optional(),
|
|
303943
|
+
renotifyStatuses: external_exports.array(external_exports.string()).optional(),
|
|
303944
|
+
escalationMessage: external_exports.string().optional(),
|
|
303945
|
+
// Lifecycle
|
|
303946
|
+
timeoutH: external_exports.number().nullable().optional(),
|
|
303947
|
+
includeTags: external_exports.boolean().optional(),
|
|
303948
|
+
locked: external_exports.boolean().optional(),
|
|
303949
|
+
silenced: external_exports.record(external_exports.number().nullable()).optional(),
|
|
303950
|
+
groupRetentionDuration: external_exports.string().optional(),
|
|
303951
|
+
// Thresholds & scheduling
|
|
303952
|
+
thresholds: MonitorThresholdsSchema.optional(),
|
|
303953
|
+
thresholdWindows: MonitorThresholdWindowsSchema.optional(),
|
|
303954
|
+
schedulingOptions: SchedulingOptionsSchema.optional()
|
|
303955
|
+
}).passthrough();
|
|
303956
|
+
var MonitorConfigSchema = external_exports.object({
|
|
303957
|
+
name: external_exports.string().optional(),
|
|
303958
|
+
type: external_exports.string().optional(),
|
|
303959
|
+
query: external_exports.string().optional(),
|
|
303960
|
+
message: external_exports.string().optional(),
|
|
303961
|
+
tags: external_exports.array(external_exports.string()).optional(),
|
|
303962
|
+
priority: external_exports.number().int().min(1).max(5).nullable().optional(),
|
|
303963
|
+
restrictedRoles: external_exports.array(external_exports.string()).nullable().optional(),
|
|
303964
|
+
multi: external_exports.boolean().optional(),
|
|
303965
|
+
options: MonitorOptionsSchema.optional()
|
|
303966
|
+
}).passthrough();
|
|
303967
|
+
var KNOWN_TOP_LEVEL_KEYS = new Set(
|
|
303968
|
+
Object.keys(MonitorConfigSchema.shape).filter((key) => key !== "options")
|
|
303969
|
+
);
|
|
303970
|
+
var KNOWN_OPTIONS_KEYS = new Set(
|
|
303971
|
+
Object.keys(MonitorOptionsSchema.shape)
|
|
303972
|
+
);
|
|
303973
|
+
function collectUnknownKeyWarnings(config2) {
|
|
303974
|
+
const warnings = [];
|
|
303975
|
+
for (const key of Object.keys(config2)) {
|
|
303976
|
+
if (!KNOWN_TOP_LEVEL_KEYS.has(key) && key !== "options") {
|
|
303977
|
+
warnings.push(`unknown top-level key '${key}' under config forwarded without validation`);
|
|
303978
|
+
}
|
|
303979
|
+
}
|
|
303980
|
+
const options = config2.options;
|
|
303981
|
+
if (isPlainObject3(options)) {
|
|
303982
|
+
for (const key of Object.keys(options)) {
|
|
303983
|
+
if (!KNOWN_OPTIONS_KEYS.has(key)) {
|
|
303984
|
+
warnings.push(
|
|
303985
|
+
`unknown option key '${key}' under config.options forwarded without validation`
|
|
303986
|
+
);
|
|
303987
|
+
}
|
|
303988
|
+
}
|
|
303989
|
+
}
|
|
303990
|
+
return warnings;
|
|
303991
|
+
}
|
|
303992
|
+
function isPlainObject3(value) {
|
|
303993
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
303994
|
+
}
|
|
303995
|
+
function summarizeZodIssue(error2) {
|
|
303996
|
+
const issue2 = error2.issues[0];
|
|
303997
|
+
if (!issue2) {
|
|
303998
|
+
return "validation failed";
|
|
303999
|
+
}
|
|
304000
|
+
const path = issue2.path.length > 0 ? issue2.path.join(".") : "<root>";
|
|
304001
|
+
const expected = issue2.code === "invalid_type" && "expected" in issue2 ? `expected ${String(issue2.expected)}` : issue2.message;
|
|
304002
|
+
return `${path}: ${expected}`;
|
|
304003
|
+
}
|
|
303908
304004
|
function formatMonitor(m, site = "datadoghq.com") {
|
|
303909
304005
|
const monitorId = m.id ?? 0;
|
|
303910
304006
|
return {
|
|
@@ -303920,6 +304016,22 @@ function formatMonitor(m, site = "datadoghq.com") {
|
|
|
303920
304016
|
url: buildMonitorUrl(monitorId, site)
|
|
303921
304017
|
};
|
|
303922
304018
|
}
|
|
304019
|
+
function formatMonitorDetail(m, site = "datadoghq.com") {
|
|
304020
|
+
const detail = { ...formatMonitor(m, site) };
|
|
304021
|
+
if (m.options != null) {
|
|
304022
|
+
detail.options = m.options;
|
|
304023
|
+
}
|
|
304024
|
+
if (m.multi != null) {
|
|
304025
|
+
detail.multi = m.multi;
|
|
304026
|
+
}
|
|
304027
|
+
if (m.priority != null) {
|
|
304028
|
+
detail.priority = m.priority;
|
|
304029
|
+
}
|
|
304030
|
+
if (m.restrictedRoles != null) {
|
|
304031
|
+
detail.restrictedRoles = m.restrictedRoles;
|
|
304032
|
+
}
|
|
304033
|
+
return detail;
|
|
304034
|
+
}
|
|
303923
304035
|
async function listMonitors(api, params, limits, site) {
|
|
303924
304036
|
const effectiveLimit = params.limit ?? limits.defaultLimit;
|
|
303925
304037
|
const response = await api.listMonitors({
|
|
@@ -303951,7 +304063,7 @@ async function getMonitor(api, id, site) {
|
|
|
303951
304063
|
}
|
|
303952
304064
|
const monitor = await api.getMonitor({ monitorId });
|
|
303953
304065
|
return {
|
|
303954
|
-
monitor:
|
|
304066
|
+
monitor: formatMonitorDetail(monitor, site),
|
|
303955
304067
|
datadog_url: buildMonitorUrl(monitorId, site)
|
|
303956
304068
|
};
|
|
303957
304069
|
}
|
|
@@ -303996,6 +304108,11 @@ function normalizeMonitorConfig(config2, isUpdate = false) {
|
|
|
303996
304108
|
["include_tags", "includeTags"],
|
|
303997
304109
|
["require_full_window", "requireFullWindow"],
|
|
303998
304110
|
["escalation_message", "escalationMessage"],
|
|
304111
|
+
["notification_preset_name", "notificationPresetName"],
|
|
304112
|
+
["on_missing_data", "onMissingData"],
|
|
304113
|
+
["group_retention_duration", "groupRetentionDuration"],
|
|
304114
|
+
["threshold_windows", "thresholdWindows"],
|
|
304115
|
+
["scheduling_options", "schedulingOptions"],
|
|
303999
304116
|
["locked", "locked"],
|
|
304000
304117
|
["silenced", "silenced"]
|
|
304001
304118
|
];
|
|
@@ -304027,21 +304144,49 @@ function normalizeMonitorConfig(config2, isUpdate = false) {
|
|
|
304027
304144
|
return normalized;
|
|
304028
304145
|
}
|
|
304029
304146
|
async function createMonitor(api, config2, site = "datadoghq.com") {
|
|
304030
|
-
const
|
|
304147
|
+
const normalized = normalizeMonitorConfig(config2);
|
|
304148
|
+
try {
|
|
304149
|
+
MonitorConfigSchema.parse(normalized);
|
|
304150
|
+
} catch (error2) {
|
|
304151
|
+
if (error2 instanceof external_exports.ZodError) {
|
|
304152
|
+
throw new Error(`EINVALID_MONITOR_CONFIG: ${summarizeZodIssue(error2)}`);
|
|
304153
|
+
}
|
|
304154
|
+
throw error2;
|
|
304155
|
+
}
|
|
304156
|
+
const warnings = collectUnknownKeyWarnings(normalized);
|
|
304157
|
+
const body = normalized;
|
|
304031
304158
|
const monitor = await api.createMonitor({ body });
|
|
304032
|
-
|
|
304159
|
+
const result = {
|
|
304033
304160
|
success: true,
|
|
304034
|
-
monitor:
|
|
304161
|
+
monitor: formatMonitorDetail(monitor, site)
|
|
304035
304162
|
};
|
|
304163
|
+
if (warnings.length > 0) {
|
|
304164
|
+
result.warnings = warnings;
|
|
304165
|
+
}
|
|
304166
|
+
return result;
|
|
304036
304167
|
}
|
|
304037
304168
|
async function updateMonitor(api, id, config2, site = "datadoghq.com") {
|
|
304038
304169
|
const monitorId = Number.parseInt(id, 10);
|
|
304039
|
-
const
|
|
304170
|
+
const normalized = normalizeMonitorConfig(config2, true);
|
|
304171
|
+
try {
|
|
304172
|
+
MonitorConfigSchema.parse(normalized);
|
|
304173
|
+
} catch (error2) {
|
|
304174
|
+
if (error2 instanceof external_exports.ZodError) {
|
|
304175
|
+
throw new Error(`EINVALID_MONITOR_CONFIG: ${summarizeZodIssue(error2)}`);
|
|
304176
|
+
}
|
|
304177
|
+
throw error2;
|
|
304178
|
+
}
|
|
304179
|
+
const warnings = collectUnknownKeyWarnings(normalized);
|
|
304180
|
+
const body = normalized;
|
|
304040
304181
|
const monitor = await api.updateMonitor({ monitorId, body });
|
|
304041
|
-
|
|
304182
|
+
const result = {
|
|
304042
304183
|
success: true,
|
|
304043
|
-
monitor:
|
|
304184
|
+
monitor: formatMonitorDetail(monitor, site)
|
|
304044
304185
|
};
|
|
304186
|
+
if (warnings.length > 0) {
|
|
304187
|
+
result.warnings = warnings;
|
|
304188
|
+
}
|
|
304189
|
+
return result;
|
|
304045
304190
|
}
|
|
304046
304191
|
async function deleteMonitor(api, id) {
|
|
304047
304192
|
const monitorId = Number.parseInt(id, 10);
|
|
@@ -304196,6 +304341,21 @@ function registerMonitorsTool(server, api, eventsApi, limits, readOnly = false,
|
|
|
304196
304341
|
"monitors",
|
|
304197
304342
|
`Manage Datadog monitors. Actions: list, get, search, create, update, delete, mute, unmute, top.
|
|
304198
304343
|
Filters: name, tags, groupStates (alert/warn/ok/no data).
|
|
304344
|
+
get/create/update return the full options object so callers can safely read-then-patch.
|
|
304345
|
+
|
|
304346
|
+
create/update accept a config object validated against a typed schema covering the documented Datadog Monitor fields:
|
|
304347
|
+
- Top-level: name, type, query, message, tags, priority (1-5, nullable), restrictedRoles, multi, options.
|
|
304348
|
+
- options.* validated keys grouped by category:
|
|
304349
|
+
- notification: notifyNoData, noDataTimeframe, notifyAudit, notificationPresetName.
|
|
304350
|
+
- evaluation/delay: newHostDelay, newGroupDelay, evaluationDelay, requireFullWindow, onMissingData.
|
|
304351
|
+
- renotification: renotifyInterval (nullable), renotifyOccurrences, renotifyStatuses, escalationMessage.
|
|
304352
|
+
- lifecycle: timeoutH (nullable), includeTags, locked, silenced (record of timestamps/null), groupRetentionDuration.
|
|
304353
|
+
- thresholds: thresholds (critical/warning/ok/criticalRecovery/warningRecovery/unknown), thresholdWindows.
|
|
304354
|
+
- scheduling: schedulingOptions.
|
|
304355
|
+
Unknown keys (top-level or under options) are forwarded to Datadog as-is and surfaced via an optional warnings array on the response, so the schema does not lag the API.
|
|
304356
|
+
snake_case aliases are accepted on input and normalized to camelCase before validation.
|
|
304357
|
+
Validation errors short-circuit before any HTTP call and surface as 'EINVALID_MONITOR_CONFIG: <path>: <expected>'.
|
|
304358
|
+
Reference: https://docs.datadoghq.com/api/latest/monitors/
|
|
304199
304359
|
|
|
304200
304360
|
top: Ranked monitors by alert frequency with real monitor names and context breakdown.
|
|
304201
304361
|
- Returns: {rank, monitor_id, name (with {{template.vars}}), message (template), total_count, by_context}
|
|
@@ -305567,6 +305727,22 @@ function registerIncidentsTool(server, api, limits, readOnly = false, _site = "d
|
|
|
305567
305727
|
);
|
|
305568
305728
|
}
|
|
305569
305729
|
|
|
305730
|
+
// src/utils/normalize.ts
|
|
305731
|
+
function snakeToCamel2(str) {
|
|
305732
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
305733
|
+
}
|
|
305734
|
+
function normalizeConfigKeys(obj) {
|
|
305735
|
+
if (obj === null || obj === void 0) return obj;
|
|
305736
|
+
if (Array.isArray(obj)) return obj.map(normalizeConfigKeys);
|
|
305737
|
+
if (typeof obj !== "object") return obj;
|
|
305738
|
+
const normalized = {};
|
|
305739
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
305740
|
+
const camelKey = snakeToCamel2(key);
|
|
305741
|
+
normalized[camelKey] = normalizeConfigKeys(value);
|
|
305742
|
+
}
|
|
305743
|
+
return normalized;
|
|
305744
|
+
}
|
|
305745
|
+
|
|
305570
305746
|
// src/tools/slos.ts
|
|
305571
305747
|
var ActionSchema8 = external_exports.enum(["list", "get", "create", "update", "delete", "history"]);
|
|
305572
305748
|
var InputSchema8 = {
|
|
@@ -305582,7 +305758,7 @@ var InputSchema8 = {
|
|
|
305582
305758
|
};
|
|
305583
305759
|
function formatSlo(s) {
|
|
305584
305760
|
const primaryThreshold = s.thresholds?.[0];
|
|
305585
|
-
|
|
305761
|
+
const summary = {
|
|
305586
305762
|
id: s.id ?? "",
|
|
305587
305763
|
name: s.name ?? "",
|
|
305588
305764
|
description: s.description ?? null,
|
|
@@ -305600,11 +305776,24 @@ function formatSlo(s) {
|
|
|
305600
305776
|
createdAt: s.createdAt ? new Date(s.createdAt * 1e3).toISOString() : "",
|
|
305601
305777
|
modifiedAt: s.modifiedAt ? new Date(s.modifiedAt * 1e3).toISOString() : ""
|
|
305602
305778
|
};
|
|
305779
|
+
if (s.query?.numerator && s.query.denominator) {
|
|
305780
|
+
summary.query = { numerator: s.query.numerator, denominator: s.query.denominator };
|
|
305781
|
+
}
|
|
305782
|
+
if (Array.isArray(s.monitorIds) && s.monitorIds.length > 0) {
|
|
305783
|
+
summary.monitorIds = s.monitorIds;
|
|
305784
|
+
}
|
|
305785
|
+
if (Array.isArray(s.monitorTags) && s.monitorTags.length > 0) {
|
|
305786
|
+
summary.monitorTags = s.monitorTags;
|
|
305787
|
+
}
|
|
305788
|
+
if (Array.isArray(s.groups) && s.groups.length > 0) {
|
|
305789
|
+
summary.groups = s.groups;
|
|
305790
|
+
}
|
|
305791
|
+
return summary;
|
|
305603
305792
|
}
|
|
305604
305793
|
function formatSearchSlo(slo) {
|
|
305605
305794
|
const attrs = slo.data?.attributes;
|
|
305606
305795
|
const primaryThreshold = attrs?.thresholds?.[0];
|
|
305607
|
-
|
|
305796
|
+
const summary = {
|
|
305608
305797
|
id: slo.data?.id ?? "",
|
|
305609
305798
|
name: attrs?.name ?? "",
|
|
305610
305799
|
description: attrs?.description ?? null,
|
|
@@ -305628,6 +305817,16 @@ function formatSearchSlo(slo) {
|
|
|
305628
305817
|
createdAt: attrs?.createdAt ? new Date(attrs.createdAt * 1e3).toISOString() : "",
|
|
305629
305818
|
modifiedAt: attrs?.modifiedAt ? new Date(attrs.modifiedAt * 1e3).toISOString() : ""
|
|
305630
305819
|
};
|
|
305820
|
+
if (attrs?.query?.numerator && attrs.query.denominator) {
|
|
305821
|
+
summary.query = { numerator: attrs.query.numerator, denominator: attrs.query.denominator };
|
|
305822
|
+
}
|
|
305823
|
+
if (Array.isArray(attrs?.monitorIds) && attrs.monitorIds.length > 0) {
|
|
305824
|
+
summary.monitorIds = attrs.monitorIds;
|
|
305825
|
+
}
|
|
305826
|
+
if (Array.isArray(attrs?.groups) && attrs.groups.length > 0) {
|
|
305827
|
+
summary.groups = attrs.groups;
|
|
305828
|
+
}
|
|
305829
|
+
return summary;
|
|
305631
305830
|
}
|
|
305632
305831
|
function buildSearchQuery(query, tags) {
|
|
305633
305832
|
const parts = [];
|
|
@@ -305663,20 +305862,6 @@ async function getSlo(api, id) {
|
|
|
305663
305862
|
slo: response.data ? formatSlo(response.data) : null
|
|
305664
305863
|
};
|
|
305665
305864
|
}
|
|
305666
|
-
function snakeToCamel2(str) {
|
|
305667
|
-
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
305668
|
-
}
|
|
305669
|
-
function normalizeConfigKeys(obj) {
|
|
305670
|
-
if (obj === null || obj === void 0) return obj;
|
|
305671
|
-
if (Array.isArray(obj)) return obj.map(normalizeConfigKeys);
|
|
305672
|
-
if (typeof obj !== "object") return obj;
|
|
305673
|
-
const normalized = {};
|
|
305674
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
305675
|
-
const camelKey = snakeToCamel2(key);
|
|
305676
|
-
normalized[camelKey] = normalizeConfigKeys(value);
|
|
305677
|
-
}
|
|
305678
|
-
return normalized;
|
|
305679
|
-
}
|
|
305680
305865
|
function normalizeSloConfig(config2) {
|
|
305681
305866
|
const normalized = normalizeConfigKeys(config2);
|
|
305682
305867
|
if (!normalized.name) {
|
|
@@ -307927,6 +308112,488 @@ function registerSchemaTool(server) {
|
|
|
307927
308112
|
);
|
|
307928
308113
|
}
|
|
307929
308114
|
|
|
308115
|
+
// src/tools/logs_pipelines.ts
|
|
308116
|
+
var ActionSchema20 = external_exports.enum(["list", "get", "create", "update", "delete", "reorder", "get_order"]);
|
|
308117
|
+
var InputSchema21 = {
|
|
308118
|
+
action: ActionSchema20.describe("Action to perform"),
|
|
308119
|
+
id: external_exports.string().optional().describe("Pipeline ID (required for get/update/delete)"),
|
|
308120
|
+
config: external_exports.record(external_exports.unknown()).optional().describe(
|
|
308121
|
+
"Pipeline configuration (for create/update). Requires name and filter.query. Processors are forwarded unchanged."
|
|
308122
|
+
),
|
|
308123
|
+
pipeline_ids: external_exports.array(external_exports.string()).optional().describe("Ordered pipeline ID list (required for reorder)"),
|
|
308124
|
+
verbose: external_exports.boolean().optional().describe("Return full SDK payload alongside summary (default false)")
|
|
308125
|
+
};
|
|
308126
|
+
function formatPipeline(p, verbose = false) {
|
|
308127
|
+
const summary = {
|
|
308128
|
+
id: p.id ?? "",
|
|
308129
|
+
name: p.name ?? "",
|
|
308130
|
+
filterQuery: p.filter?.query ?? null,
|
|
308131
|
+
isEnabled: p.isEnabled ?? false,
|
|
308132
|
+
isReadOnly: p.isReadOnly ?? false,
|
|
308133
|
+
type: p.type ?? null,
|
|
308134
|
+
processorsCount: p.processors?.length ?? 0
|
|
308135
|
+
};
|
|
308136
|
+
if (verbose && p.processors) {
|
|
308137
|
+
summary.processors = p.processors;
|
|
308138
|
+
}
|
|
308139
|
+
return summary;
|
|
308140
|
+
}
|
|
308141
|
+
function normalizePipelineConfig(config2) {
|
|
308142
|
+
const normalized = normalizeConfigKeys(config2);
|
|
308143
|
+
if (!normalized.name) {
|
|
308144
|
+
throw new Error("Pipeline config requires 'name' field");
|
|
308145
|
+
}
|
|
308146
|
+
const filter = normalized.filter;
|
|
308147
|
+
if (!filter || typeof filter.query !== "string" || filter.query.length === 0) {
|
|
308148
|
+
throw new Error("Pipeline config requires 'filter.query' field");
|
|
308149
|
+
}
|
|
308150
|
+
return normalized;
|
|
308151
|
+
}
|
|
308152
|
+
async function listPipelines(api, verbose = false) {
|
|
308153
|
+
const response = await api.listLogsPipelines();
|
|
308154
|
+
const pipelines = (response ?? []).map((p) => formatPipeline(p, verbose));
|
|
308155
|
+
const result = { pipelines, total: pipelines.length };
|
|
308156
|
+
if (verbose) {
|
|
308157
|
+
result.raw = response;
|
|
308158
|
+
}
|
|
308159
|
+
return result;
|
|
308160
|
+
}
|
|
308161
|
+
async function getPipeline(api, id, verbose = false) {
|
|
308162
|
+
const response = await api.getLogsPipeline({ pipelineId: id });
|
|
308163
|
+
const result = { pipeline: formatPipeline(response, verbose) };
|
|
308164
|
+
if (verbose) {
|
|
308165
|
+
result.raw = response;
|
|
308166
|
+
}
|
|
308167
|
+
return result;
|
|
308168
|
+
}
|
|
308169
|
+
async function createPipeline(api, config2, verbose = false) {
|
|
308170
|
+
const body = normalizePipelineConfig(config2);
|
|
308171
|
+
const response = await api.createLogsPipeline({ body });
|
|
308172
|
+
const result = {
|
|
308173
|
+
success: true,
|
|
308174
|
+
pipeline: formatPipeline(response, verbose)
|
|
308175
|
+
};
|
|
308176
|
+
if (verbose) {
|
|
308177
|
+
result.raw = response;
|
|
308178
|
+
}
|
|
308179
|
+
return result;
|
|
308180
|
+
}
|
|
308181
|
+
async function updatePipeline(api, id, config2, verbose = false) {
|
|
308182
|
+
const body = normalizePipelineConfig(config2);
|
|
308183
|
+
const response = await api.updateLogsPipeline({ pipelineId: id, body });
|
|
308184
|
+
const result = {
|
|
308185
|
+
success: true,
|
|
308186
|
+
pipeline: formatPipeline(response, verbose)
|
|
308187
|
+
};
|
|
308188
|
+
if (verbose) {
|
|
308189
|
+
result.raw = response;
|
|
308190
|
+
}
|
|
308191
|
+
return result;
|
|
308192
|
+
}
|
|
308193
|
+
async function deletePipeline(api, id) {
|
|
308194
|
+
await api.deleteLogsPipeline({ pipelineId: id });
|
|
308195
|
+
return {
|
|
308196
|
+
success: true,
|
|
308197
|
+
message: `Pipeline ${id} deleted`
|
|
308198
|
+
};
|
|
308199
|
+
}
|
|
308200
|
+
async function reorderPipelines(api, pipelineIds) {
|
|
308201
|
+
const body = { pipelineIds };
|
|
308202
|
+
const response = await api.updateLogsPipelineOrder({ body });
|
|
308203
|
+
return {
|
|
308204
|
+
success: true,
|
|
308205
|
+
order: {
|
|
308206
|
+
pipelineIds: response.pipelineIds ?? []
|
|
308207
|
+
}
|
|
308208
|
+
};
|
|
308209
|
+
}
|
|
308210
|
+
async function getPipelineOrder(api) {
|
|
308211
|
+
const response = await api.getLogsPipelineOrder();
|
|
308212
|
+
return {
|
|
308213
|
+
order: {
|
|
308214
|
+
pipelineIds: response.pipelineIds ?? []
|
|
308215
|
+
}
|
|
308216
|
+
};
|
|
308217
|
+
}
|
|
308218
|
+
function registerLogsPipelinesTool(server, api, _limits, readOnly = false, _site = "datadoghq.com") {
|
|
308219
|
+
server.tool(
|
|
308220
|
+
"logs_pipelines",
|
|
308221
|
+
"Manage Datadog Logs pipelines (parsing & processor chains). Actions: list, get, create, update, delete, reorder, get_order. Pipelines run sequentially on incoming logs; reorder changes the structure of downstream data. Mutations are blocked when the server is in read-only mode. Unknown processor types in 'config.processors' are forwarded to Datadog unchanged.",
|
|
308222
|
+
InputSchema21,
|
|
308223
|
+
async ({ action, id, config: config2, pipeline_ids, verbose }) => {
|
|
308224
|
+
try {
|
|
308225
|
+
checkReadOnly(action, readOnly);
|
|
308226
|
+
const isVerbose = verbose ?? false;
|
|
308227
|
+
switch (action) {
|
|
308228
|
+
case "list":
|
|
308229
|
+
return toolResult(await listPipelines(api, isVerbose));
|
|
308230
|
+
case "get": {
|
|
308231
|
+
const pipelineId = requireParam(id, "id", "get");
|
|
308232
|
+
return toolResult(await getPipeline(api, pipelineId, isVerbose));
|
|
308233
|
+
}
|
|
308234
|
+
case "create": {
|
|
308235
|
+
const pipelineConfig = requireParam(config2, "config", "create");
|
|
308236
|
+
return toolResult(await createPipeline(api, pipelineConfig, isVerbose));
|
|
308237
|
+
}
|
|
308238
|
+
case "update": {
|
|
308239
|
+
const pipelineId = requireParam(id, "id", "update");
|
|
308240
|
+
const pipelineConfig = requireParam(config2, "config", "update");
|
|
308241
|
+
return toolResult(await updatePipeline(api, pipelineId, pipelineConfig, isVerbose));
|
|
308242
|
+
}
|
|
308243
|
+
case "delete": {
|
|
308244
|
+
const pipelineId = requireParam(id, "id", "delete");
|
|
308245
|
+
return toolResult(await deletePipeline(api, pipelineId));
|
|
308246
|
+
}
|
|
308247
|
+
case "reorder": {
|
|
308248
|
+
const ids = requireParam(pipeline_ids, "pipeline_ids", "reorder");
|
|
308249
|
+
return toolResult(await reorderPipelines(api, ids));
|
|
308250
|
+
}
|
|
308251
|
+
case "get_order":
|
|
308252
|
+
return toolResult(await getPipelineOrder(api));
|
|
308253
|
+
default:
|
|
308254
|
+
throw new Error(`Unknown action: ${String(action)}`);
|
|
308255
|
+
}
|
|
308256
|
+
} catch (error2) {
|
|
308257
|
+
handleDatadogError(error2);
|
|
308258
|
+
}
|
|
308259
|
+
}
|
|
308260
|
+
);
|
|
308261
|
+
}
|
|
308262
|
+
|
|
308263
|
+
// src/tools/logs_indexes.ts
|
|
308264
|
+
var ActionSchema21 = external_exports.enum(["list", "get", "update", "reorder", "get_order"]);
|
|
308265
|
+
var InputSchema22 = {
|
|
308266
|
+
action: ActionSchema21.describe("Action to perform"),
|
|
308267
|
+
name: external_exports.string().optional().describe("Index name (required for get/update). Datadog identifies indexes by name, not id."),
|
|
308268
|
+
config: external_exports.record(external_exports.unknown()).optional().describe(
|
|
308269
|
+
"Index configuration (for update). Requires filter.query and numRetentionDays. Exclusion filters are forwarded unchanged."
|
|
308270
|
+
),
|
|
308271
|
+
index_names: external_exports.array(external_exports.string()).optional().describe("Ordered index name list (required for reorder)"),
|
|
308272
|
+
verbose: external_exports.boolean().optional().describe("Return full SDK payload alongside summary (default false)")
|
|
308273
|
+
};
|
|
308274
|
+
function formatIndex(idx, verbose = false) {
|
|
308275
|
+
const summary = {
|
|
308276
|
+
name: idx.name ?? "",
|
|
308277
|
+
filterQuery: idx.filter?.query ?? null,
|
|
308278
|
+
exclusionFiltersCount: idx.exclusionFilters?.length ?? 0,
|
|
308279
|
+
numRetentionDays: idx.numRetentionDays ?? null,
|
|
308280
|
+
numFlexLogsRetentionDays: idx.numFlexLogsRetentionDays ?? null,
|
|
308281
|
+
dailyLimit: idx.dailyLimit ?? null,
|
|
308282
|
+
isRateLimited: idx.isRateLimited ?? false
|
|
308283
|
+
};
|
|
308284
|
+
if (verbose && idx.exclusionFilters) {
|
|
308285
|
+
summary.exclusionFilters = idx.exclusionFilters;
|
|
308286
|
+
}
|
|
308287
|
+
return summary;
|
|
308288
|
+
}
|
|
308289
|
+
function normalizeIndexConfig(config2) {
|
|
308290
|
+
const normalized = normalizeConfigKeys(config2);
|
|
308291
|
+
const filter = normalized.filter;
|
|
308292
|
+
if (!filter || typeof filter.query !== "string" || filter.query.length === 0) {
|
|
308293
|
+
throw new Error("Index config requires 'filter.query' field");
|
|
308294
|
+
}
|
|
308295
|
+
if (typeof normalized.numRetentionDays !== "number") {
|
|
308296
|
+
throw new Error("Index config requires 'numRetentionDays' field");
|
|
308297
|
+
}
|
|
308298
|
+
return normalized;
|
|
308299
|
+
}
|
|
308300
|
+
async function listIndexes(api, verbose = false) {
|
|
308301
|
+
const response = await api.listLogIndexes();
|
|
308302
|
+
const indexes = (response.indexes ?? []).map((idx) => formatIndex(idx, verbose));
|
|
308303
|
+
const result = { indexes, total: indexes.length };
|
|
308304
|
+
if (verbose) {
|
|
308305
|
+
result.raw = response;
|
|
308306
|
+
}
|
|
308307
|
+
return result;
|
|
308308
|
+
}
|
|
308309
|
+
async function getIndex(api, name, verbose = false) {
|
|
308310
|
+
const response = await api.getLogsIndex({ name });
|
|
308311
|
+
const result = { index: formatIndex(response, verbose) };
|
|
308312
|
+
if (verbose) {
|
|
308313
|
+
result.raw = response;
|
|
308314
|
+
}
|
|
308315
|
+
return result;
|
|
308316
|
+
}
|
|
308317
|
+
async function updateIndex(api, name, config2, verbose = false) {
|
|
308318
|
+
const body = normalizeIndexConfig(config2);
|
|
308319
|
+
const response = await api.updateLogsIndex({ name, body });
|
|
308320
|
+
const result = {
|
|
308321
|
+
success: true,
|
|
308322
|
+
index: formatIndex(response, verbose)
|
|
308323
|
+
};
|
|
308324
|
+
if (verbose) {
|
|
308325
|
+
result.raw = response;
|
|
308326
|
+
}
|
|
308327
|
+
return result;
|
|
308328
|
+
}
|
|
308329
|
+
async function reorderIndexes(api, indexNames) {
|
|
308330
|
+
const body = { indexNames };
|
|
308331
|
+
const response = await api.updateLogsIndexOrder({ body });
|
|
308332
|
+
return {
|
|
308333
|
+
success: true,
|
|
308334
|
+
order: {
|
|
308335
|
+
indexNames: response.indexNames ?? []
|
|
308336
|
+
}
|
|
308337
|
+
};
|
|
308338
|
+
}
|
|
308339
|
+
async function getIndexOrder(api) {
|
|
308340
|
+
const response = await api.getLogsIndexOrder();
|
|
308341
|
+
return {
|
|
308342
|
+
order: {
|
|
308343
|
+
indexNames: response.indexNames ?? []
|
|
308344
|
+
}
|
|
308345
|
+
};
|
|
308346
|
+
}
|
|
308347
|
+
function registerLogsIndexesTool(server, api, _limits, readOnly = false, _site = "datadoghq.com") {
|
|
308348
|
+
server.tool(
|
|
308349
|
+
"logs_indexes",
|
|
308350
|
+
"Manage Datadog Logs indexes (filters, retention, exclusion filters, daily limits). Actions: list, get, update, reorder, get_order. Datadog identifies indexes by 'name', not 'id'. Note: create/delete are UI-only per Datadog and not supported through the API. Mutations (update, reorder) are blocked when the server is in read-only mode.",
|
|
308351
|
+
InputSchema22,
|
|
308352
|
+
async ({ action, name, config: config2, index_names, verbose }) => {
|
|
308353
|
+
try {
|
|
308354
|
+
checkReadOnly(action, readOnly);
|
|
308355
|
+
const isVerbose = verbose ?? false;
|
|
308356
|
+
switch (action) {
|
|
308357
|
+
case "list":
|
|
308358
|
+
return toolResult(await listIndexes(api, isVerbose));
|
|
308359
|
+
case "get": {
|
|
308360
|
+
const indexName = requireParam(name, "name", "get");
|
|
308361
|
+
return toolResult(await getIndex(api, indexName, isVerbose));
|
|
308362
|
+
}
|
|
308363
|
+
case "update": {
|
|
308364
|
+
const indexName = requireParam(name, "name", "update");
|
|
308365
|
+
const indexConfig = requireParam(config2, "config", "update");
|
|
308366
|
+
return toolResult(await updateIndex(api, indexName, indexConfig, isVerbose));
|
|
308367
|
+
}
|
|
308368
|
+
case "reorder": {
|
|
308369
|
+
const names = requireParam(index_names, "index_names", "reorder");
|
|
308370
|
+
return toolResult(await reorderIndexes(api, names));
|
|
308371
|
+
}
|
|
308372
|
+
case "get_order":
|
|
308373
|
+
return toolResult(await getIndexOrder(api));
|
|
308374
|
+
default:
|
|
308375
|
+
throw new Error(`Unknown action: ${String(action)}`);
|
|
308376
|
+
}
|
|
308377
|
+
} catch (error2) {
|
|
308378
|
+
handleDatadogError(error2);
|
|
308379
|
+
}
|
|
308380
|
+
}
|
|
308381
|
+
);
|
|
308382
|
+
}
|
|
308383
|
+
|
|
308384
|
+
// src/tools/logs_archives.ts
|
|
308385
|
+
var ActionSchema22 = external_exports.enum(["list", "get", "create", "update", "delete", "reorder", "get_order"]);
|
|
308386
|
+
var InputSchema23 = {
|
|
308387
|
+
action: ActionSchema22.describe("Action to perform"),
|
|
308388
|
+
id: external_exports.string().optional().describe("Archive ID (required for get/update/delete)"),
|
|
308389
|
+
config: external_exports.record(external_exports.unknown()).optional().describe(
|
|
308390
|
+
"Archive configuration (for create/update). Requires name, query, and destination with type \u2208 { s3, gcs, azure_storage }. Provider credential / integration fields are forwarded unchanged."
|
|
308391
|
+
),
|
|
308392
|
+
archive_ids: external_exports.array(external_exports.string()).optional().describe("Ordered archive ID list (required for reorder)"),
|
|
308393
|
+
verbose: external_exports.boolean().optional().describe("Return full SDK payload alongside summary (default false)")
|
|
308394
|
+
};
|
|
308395
|
+
var VALID_DESTINATION_TYPES = ["s3", "gcs", "azure_storage"];
|
|
308396
|
+
function extractDestinationContainer(destination) {
|
|
308397
|
+
if (!destination || typeof destination !== "object") return null;
|
|
308398
|
+
const dest = destination;
|
|
308399
|
+
if (typeof dest.bucket === "string") return dest.bucket;
|
|
308400
|
+
if (typeof dest.container === "string") return dest.container;
|
|
308401
|
+
return null;
|
|
308402
|
+
}
|
|
308403
|
+
function formatArchive(archive, verbose = false) {
|
|
308404
|
+
const attrs = archive.attributes;
|
|
308405
|
+
const destination = attrs?.destination ?? null;
|
|
308406
|
+
const destinationType = destination && typeof destination === "object" && "type" in destination ? String(destination.type ?? "") : "";
|
|
308407
|
+
const summary = {
|
|
308408
|
+
id: archive.id ?? "",
|
|
308409
|
+
name: attrs?.name ?? "",
|
|
308410
|
+
query: attrs?.query ?? null,
|
|
308411
|
+
destinationType,
|
|
308412
|
+
destinationContainer: extractDestinationContainer(destination),
|
|
308413
|
+
includeTags: attrs?.includeTags ?? false,
|
|
308414
|
+
rehydrationTags: attrs?.rehydrationTags ?? [],
|
|
308415
|
+
state: attrs?.state ?? null
|
|
308416
|
+
};
|
|
308417
|
+
if (verbose && destination) {
|
|
308418
|
+
summary.destination = destination;
|
|
308419
|
+
}
|
|
308420
|
+
return summary;
|
|
308421
|
+
}
|
|
308422
|
+
function normalizeArchiveConfig(config2) {
|
|
308423
|
+
const normalized = normalizeConfigKeys(config2);
|
|
308424
|
+
if (typeof normalized.name !== "string" || normalized.name.length === 0) {
|
|
308425
|
+
throw new Error("Archive config requires 'name' field");
|
|
308426
|
+
}
|
|
308427
|
+
if (typeof normalized.query !== "string" || normalized.query.length === 0) {
|
|
308428
|
+
throw new Error("Archive config requires 'query' field");
|
|
308429
|
+
}
|
|
308430
|
+
const destination = normalized.destination;
|
|
308431
|
+
if (!destination || typeof destination !== "object") {
|
|
308432
|
+
throw new Error("Archive config requires 'destination' object");
|
|
308433
|
+
}
|
|
308434
|
+
const destinationType = destination.type;
|
|
308435
|
+
if (typeof destinationType !== "string" || !VALID_DESTINATION_TYPES.includes(destinationType)) {
|
|
308436
|
+
throw new Error("destination.type must be one of: s3, gcs, azure_storage");
|
|
308437
|
+
}
|
|
308438
|
+
if (destinationType === "azure_storage") {
|
|
308439
|
+
;
|
|
308440
|
+
destination.type = "azure";
|
|
308441
|
+
}
|
|
308442
|
+
return normalized;
|
|
308443
|
+
}
|
|
308444
|
+
function buildArchiveRequestBody(normalizedConfig) {
|
|
308445
|
+
const { name, query, destination, includeTags, rehydrationTags, rehydrationMaxScanSizeInGb } = normalizedConfig;
|
|
308446
|
+
const attributes = {
|
|
308447
|
+
name,
|
|
308448
|
+
query,
|
|
308449
|
+
destination
|
|
308450
|
+
};
|
|
308451
|
+
if (includeTags !== void 0) attributes.includeTags = includeTags;
|
|
308452
|
+
if (rehydrationTags !== void 0) attributes.rehydrationTags = rehydrationTags;
|
|
308453
|
+
if (rehydrationMaxScanSizeInGb !== void 0) {
|
|
308454
|
+
attributes.rehydrationMaxScanSizeInGb = rehydrationMaxScanSizeInGb;
|
|
308455
|
+
}
|
|
308456
|
+
return {
|
|
308457
|
+
data: {
|
|
308458
|
+
type: "archives",
|
|
308459
|
+
attributes
|
|
308460
|
+
}
|
|
308461
|
+
};
|
|
308462
|
+
}
|
|
308463
|
+
async function listArchives(api, verbose = false) {
|
|
308464
|
+
const response = await api.listLogsArchives();
|
|
308465
|
+
const archives = (response.data ?? []).map((archive) => formatArchive(archive, verbose));
|
|
308466
|
+
const result = { archives, total: archives.length };
|
|
308467
|
+
if (verbose) {
|
|
308468
|
+
result.raw = response;
|
|
308469
|
+
}
|
|
308470
|
+
return result;
|
|
308471
|
+
}
|
|
308472
|
+
async function getArchive(api, id, verbose = false) {
|
|
308473
|
+
const response = await api.getLogsArchive({ archiveId: id });
|
|
308474
|
+
const archive = response.data;
|
|
308475
|
+
if (!archive) {
|
|
308476
|
+
throw new Error(`Archive ${id} returned an empty payload`);
|
|
308477
|
+
}
|
|
308478
|
+
const result = { archive: formatArchive(archive, verbose) };
|
|
308479
|
+
if (verbose) {
|
|
308480
|
+
result.raw = response;
|
|
308481
|
+
}
|
|
308482
|
+
return result;
|
|
308483
|
+
}
|
|
308484
|
+
async function createArchive(api, config2, verbose = false) {
|
|
308485
|
+
const normalized = normalizeArchiveConfig(config2);
|
|
308486
|
+
const body = buildArchiveRequestBody(normalized);
|
|
308487
|
+
const response = await api.createLogsArchive({ body });
|
|
308488
|
+
const archive = response.data;
|
|
308489
|
+
if (!archive) {
|
|
308490
|
+
throw new Error("Archive creation returned an empty payload");
|
|
308491
|
+
}
|
|
308492
|
+
const result = {
|
|
308493
|
+
success: true,
|
|
308494
|
+
archive: formatArchive(archive, verbose)
|
|
308495
|
+
};
|
|
308496
|
+
if (verbose) {
|
|
308497
|
+
result.raw = response;
|
|
308498
|
+
}
|
|
308499
|
+
return result;
|
|
308500
|
+
}
|
|
308501
|
+
async function updateArchive(api, id, config2, verbose = false) {
|
|
308502
|
+
const normalized = normalizeArchiveConfig(config2);
|
|
308503
|
+
const body = buildArchiveRequestBody(normalized);
|
|
308504
|
+
const response = await api.updateLogsArchive({ archiveId: id, body });
|
|
308505
|
+
const archive = response.data;
|
|
308506
|
+
if (!archive) {
|
|
308507
|
+
throw new Error(`Archive ${id} update returned an empty payload`);
|
|
308508
|
+
}
|
|
308509
|
+
const result = {
|
|
308510
|
+
success: true,
|
|
308511
|
+
archive: formatArchive(archive, verbose)
|
|
308512
|
+
};
|
|
308513
|
+
if (verbose) {
|
|
308514
|
+
result.raw = response;
|
|
308515
|
+
}
|
|
308516
|
+
return result;
|
|
308517
|
+
}
|
|
308518
|
+
async function deleteArchive(api, id) {
|
|
308519
|
+
await api.deleteLogsArchive({ archiveId: id });
|
|
308520
|
+
return {
|
|
308521
|
+
success: true,
|
|
308522
|
+
message: `Archive ${id} deleted`
|
|
308523
|
+
};
|
|
308524
|
+
}
|
|
308525
|
+
async function reorderArchives(api, archiveIds) {
|
|
308526
|
+
const body = {
|
|
308527
|
+
data: {
|
|
308528
|
+
type: "archive_order",
|
|
308529
|
+
attributes: {
|
|
308530
|
+
archiveIds
|
|
308531
|
+
}
|
|
308532
|
+
}
|
|
308533
|
+
};
|
|
308534
|
+
const response = await api.updateLogsArchiveOrder({ body });
|
|
308535
|
+
const resultIds = response.data?.attributes?.archiveIds ?? [];
|
|
308536
|
+
return {
|
|
308537
|
+
success: true,
|
|
308538
|
+
order: {
|
|
308539
|
+
archiveIds: resultIds
|
|
308540
|
+
}
|
|
308541
|
+
};
|
|
308542
|
+
}
|
|
308543
|
+
async function getArchiveOrder(api) {
|
|
308544
|
+
const response = await api.getLogsArchiveOrder();
|
|
308545
|
+
const resultIds = response.data?.attributes?.archiveIds ?? [];
|
|
308546
|
+
return {
|
|
308547
|
+
order: {
|
|
308548
|
+
archiveIds: resultIds
|
|
308549
|
+
}
|
|
308550
|
+
};
|
|
308551
|
+
}
|
|
308552
|
+
function registerLogsArchivesTool(server, api, _limits, readOnly = false, _site = "datadoghq.com") {
|
|
308553
|
+
server.tool(
|
|
308554
|
+
"logs_archives",
|
|
308555
|
+
"Manage Datadog Logs archives (long-term log retention to S3 / GCS / Azure Blob). Actions: list, get, create, update, delete, reorder, get_order. Archives accept destinations of type 's3', 'gcs', or 'azure_storage'; per-provider credential and integration fields (S3 IAM role ARN, GCS service account, Azure tenant/secret) are forwarded unchanged. Mutations (create, update, delete, reorder) are blocked when the server is in read-only mode.",
|
|
308556
|
+
InputSchema23,
|
|
308557
|
+
async ({ action, id, config: config2, archive_ids, verbose }) => {
|
|
308558
|
+
try {
|
|
308559
|
+
checkReadOnly(action, readOnly);
|
|
308560
|
+
const isVerbose = verbose ?? false;
|
|
308561
|
+
switch (action) {
|
|
308562
|
+
case "list":
|
|
308563
|
+
return toolResult(await listArchives(api, isVerbose));
|
|
308564
|
+
case "get": {
|
|
308565
|
+
const archiveId = requireParam(id, "id", "get");
|
|
308566
|
+
return toolResult(await getArchive(api, archiveId, isVerbose));
|
|
308567
|
+
}
|
|
308568
|
+
case "create": {
|
|
308569
|
+
const archiveConfig = requireParam(config2, "config", "create");
|
|
308570
|
+
return toolResult(await createArchive(api, archiveConfig, isVerbose));
|
|
308571
|
+
}
|
|
308572
|
+
case "update": {
|
|
308573
|
+
const archiveId = requireParam(id, "id", "update");
|
|
308574
|
+
const archiveConfig = requireParam(config2, "config", "update");
|
|
308575
|
+
return toolResult(await updateArchive(api, archiveId, archiveConfig, isVerbose));
|
|
308576
|
+
}
|
|
308577
|
+
case "delete": {
|
|
308578
|
+
const archiveId = requireParam(id, "id", "delete");
|
|
308579
|
+
return toolResult(await deleteArchive(api, archiveId));
|
|
308580
|
+
}
|
|
308581
|
+
case "reorder": {
|
|
308582
|
+
const ids = requireParam(archive_ids, "archive_ids", "reorder");
|
|
308583
|
+
return toolResult(await reorderArchives(api, ids));
|
|
308584
|
+
}
|
|
308585
|
+
case "get_order":
|
|
308586
|
+
return toolResult(await getArchiveOrder(api));
|
|
308587
|
+
default:
|
|
308588
|
+
throw new Error(`Unknown action: ${String(action)}`);
|
|
308589
|
+
}
|
|
308590
|
+
} catch (error2) {
|
|
308591
|
+
handleDatadogError(error2);
|
|
308592
|
+
}
|
|
308593
|
+
}
|
|
308594
|
+
);
|
|
308595
|
+
}
|
|
308596
|
+
|
|
307930
308597
|
// src/tools/index.ts
|
|
307931
308598
|
function registerAllTools(server, clients, limits, features, site = "datadoghq.com", datadogConfig) {
|
|
307932
308599
|
const { readOnly, disabledTools } = features;
|
|
@@ -307941,6 +308608,12 @@ function registerAllTools(server, clients, limits, features, site = "datadoghq.c
|
|
|
307941
308608
|
if (enabled("dashboards"))
|
|
307942
308609
|
registerDashboardsTool(server, clients.dashboards, limits, readOnly, credentials);
|
|
307943
308610
|
if (enabled("logs")) registerLogsTool(server, clients.logs, limits, site);
|
|
308611
|
+
if (enabled("logs_pipelines"))
|
|
308612
|
+
registerLogsPipelinesTool(server, clients.logsPipelines, limits, readOnly, site);
|
|
308613
|
+
if (enabled("logs_indexes"))
|
|
308614
|
+
registerLogsIndexesTool(server, clients.logsIndexes, limits, readOnly, site);
|
|
308615
|
+
if (enabled("logs_archives"))
|
|
308616
|
+
registerLogsArchivesTool(server, clients.logsArchives, limits, readOnly, site);
|
|
307944
308617
|
if (enabled("metrics"))
|
|
307945
308618
|
registerMetricsTool(server, clients.metricsV1, clients.metricsV2, limits, site);
|
|
307946
308619
|
if (enabled("traces")) registerTracesTool(server, clients.spans, clients.services, limits, site);
|