@debugbundle/mcp 0.1.5 → 0.1.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/README.md +1 -1
- package/dist/main.cjs +53 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ debugbundle-mcp
|
|
|
30
30
|
}
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The server uses stdio transport and exposes the same DebugBundle incident, incident-context, bundle, webhook, alert, token, project, member, billing, GitHub, probe, and diagnostic tools documented at https://debugbundle.com/docs/mcp. Hosted verification supports the active V1 proof path through `verify_cloud` with `trigger5xx: true`, incident triage can start with the one-call `get_incident_context` tool, and `doctor` accepts `privacy: true` to return the same deterministic redaction preview as `debugbundle doctor --privacy`.
|
|
33
|
+
The server uses stdio transport and exposes the same DebugBundle incident, incident-context, bundle, webhook, alert, token, project, member, billing, GitHub, probe, and diagnostic tools documented at https://debugbundle.com/docs/mcp. Hosted verification supports the active V1 proof path through `verify_cloud` with `trigger5xx: true` and the configured-client-error proof path with `trigger4xxStatus: 403`, incident triage can start with the one-call `get_incident_context` tool, and `doctor` accepts `privacy: true` to return the same deterministic redaction preview as `debugbundle doctor --privacy`.
|
|
34
34
|
|
|
35
35
|
## Authentication
|
|
36
36
|
|
package/dist/main.cjs
CHANGED
|
@@ -21125,7 +21125,7 @@ function formatResult(input, exitCode, checks, errors, incidentId) {
|
|
|
21125
21125
|
};
|
|
21126
21126
|
}
|
|
21127
21127
|
function buildCloudSuggestedActions(status, incidentId, mode = "passive_recent_incident") {
|
|
21128
|
-
if (status === "healthy" && incidentId !== void 0 && mode === "active_5xx") {
|
|
21128
|
+
if (status === "healthy" && incidentId !== void 0 && (mode === "active_5xx" || mode === "active_4xx")) {
|
|
21129
21129
|
return [
|
|
21130
21130
|
`Run debugbundle inspect ${incidentId} --source cloud to inspect why the incident fired.`,
|
|
21131
21131
|
`Run debugbundle bundle ${incidentId} --source cloud to fetch the generated debug bundle.`
|
|
@@ -21195,11 +21195,11 @@ function localFailureStepName(checks) {
|
|
|
21195
21195
|
function cloudVerificationRunId(now) {
|
|
21196
21196
|
return now.toISOString().replace(/[-:.TZ]/g, "").slice(0, 14);
|
|
21197
21197
|
}
|
|
21198
|
-
function requestFailureReason() {
|
|
21198
|
+
function requestFailureReason(responseStatus) {
|
|
21199
21199
|
const incidentReason = deriveIncidentReasonFromSignal({
|
|
21200
21200
|
event_type: "request_event",
|
|
21201
21201
|
event_class: "incident_signal",
|
|
21202
|
-
response_status:
|
|
21202
|
+
response_status: responseStatus
|
|
21203
21203
|
});
|
|
21204
21204
|
if (incidentReason === null) {
|
|
21205
21205
|
throw new Error("request_failure_reason_unavailable");
|
|
@@ -21208,6 +21208,9 @@ function requestFailureReason() {
|
|
|
21208
21208
|
}
|
|
21209
21209
|
function buildCloudVerificationEvent(input) {
|
|
21210
21210
|
const runId = cloudVerificationRunId(input.now);
|
|
21211
|
+
const is5xxVerification = input.responseStatus >= 500;
|
|
21212
|
+
const routeTemplate = is5xxVerification ? "/debugbundle/verify/cloud" : `/debugbundle/verify/cloud/client-error/${input.responseStatus}`;
|
|
21213
|
+
const verificationLabel = is5xxVerification ? "true" : `client-error-${input.responseStatus}`;
|
|
21211
21214
|
return createEventEnvelope({
|
|
21212
21215
|
event_type: "request_event",
|
|
21213
21216
|
sdk_name: "debugbundle-cli",
|
|
@@ -21221,28 +21224,39 @@ function buildCloudVerificationEvent(input) {
|
|
|
21221
21224
|
occurred_at: input.now.toISOString(),
|
|
21222
21225
|
payload: {
|
|
21223
21226
|
method: "GET",
|
|
21224
|
-
path:
|
|
21225
|
-
route_template:
|
|
21227
|
+
path: routeTemplate,
|
|
21228
|
+
route_template: routeTemplate,
|
|
21226
21229
|
query: {
|
|
21227
21230
|
debugbundle_verification: true,
|
|
21228
|
-
run_id: runId
|
|
21231
|
+
run_id: runId,
|
|
21232
|
+
synthetic_status: input.responseStatus
|
|
21229
21233
|
},
|
|
21230
21234
|
headers: {
|
|
21231
|
-
"x-debugbundle-verification":
|
|
21235
|
+
"x-debugbundle-verification": verificationLabel
|
|
21232
21236
|
},
|
|
21233
|
-
response_status:
|
|
21237
|
+
response_status: input.responseStatus,
|
|
21234
21238
|
duration_ms: 37,
|
|
21235
21239
|
response_headers: {
|
|
21236
|
-
"x-debugbundle-verification":
|
|
21240
|
+
"x-debugbundle-verification": verificationLabel
|
|
21237
21241
|
},
|
|
21238
21242
|
response_body: {
|
|
21239
|
-
error: "debugbundle_cloud_verification",
|
|
21243
|
+
error: is5xxVerification ? "debugbundle_cloud_verification" : "debugbundle_cloud_client_error_verification",
|
|
21240
21244
|
synthetic: true,
|
|
21241
|
-
run_id: runId
|
|
21245
|
+
run_id: runId,
|
|
21246
|
+
response_status: input.responseStatus
|
|
21242
21247
|
}
|
|
21243
21248
|
}
|
|
21244
21249
|
});
|
|
21245
21250
|
}
|
|
21251
|
+
function validateActiveCloudVerificationInput(input) {
|
|
21252
|
+
if (input.trigger5xx === true && input.trigger4xxStatus !== void 0) {
|
|
21253
|
+
return "Choose either --trigger-5xx or --trigger-4xx, not both.";
|
|
21254
|
+
}
|
|
21255
|
+
if (input.trigger4xxStatus !== void 0 && (input.trigger4xxStatus < 400 || input.trigger4xxStatus > 499)) {
|
|
21256
|
+
return "--trigger-4xx must be an integer status between 400 and 499.";
|
|
21257
|
+
}
|
|
21258
|
+
return null;
|
|
21259
|
+
}
|
|
21246
21260
|
async function sendEventsToApi(input, dependencies = {}) {
|
|
21247
21261
|
const fetchImpl = dependencies.fetchImpl ?? fetch;
|
|
21248
21262
|
const baseUrl = input.baseUrl.endsWith("/") ? input.baseUrl.slice(0, -1) : input.baseUrl;
|
|
@@ -21434,6 +21448,15 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21434
21448
|
const checks = [];
|
|
21435
21449
|
const environment = input.environment ?? "production";
|
|
21436
21450
|
const maxAgeMinutes = input.maxAgeMinutes ?? 15;
|
|
21451
|
+
const activeInputError = validateActiveCloudVerificationInput(input);
|
|
21452
|
+
if (activeInputError !== null) {
|
|
21453
|
+
checks.push({
|
|
21454
|
+
name: "trigger-input",
|
|
21455
|
+
status: "error",
|
|
21456
|
+
message: activeInputError
|
|
21457
|
+
});
|
|
21458
|
+
return formatCloudResult(input, 4, checks, [activeInputError]);
|
|
21459
|
+
}
|
|
21437
21460
|
const readAuthState = dependencies.readAuthState ?? readCliAuthState;
|
|
21438
21461
|
let authState;
|
|
21439
21462
|
try {
|
|
@@ -21466,7 +21489,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21466
21489
|
requestInput,
|
|
21467
21490
|
dependencies.fetchImpl === void 0 ? {} : { fetchImpl: dependencies.fetchImpl }
|
|
21468
21491
|
));
|
|
21469
|
-
if (input.trigger5xx === true) {
|
|
21492
|
+
if (input.trigger5xx === true || input.trigger4xxStatus !== void 0) {
|
|
21470
21493
|
const verificationStartedAt = now();
|
|
21471
21494
|
const runId = cloudVerificationRunId(verificationStartedAt);
|
|
21472
21495
|
const serviceName = input.service ?? `debugbundle-verify-cloud-${runId}`;
|
|
@@ -21474,16 +21497,20 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21474
21497
|
const pollAttempts = dependencies.pollAttempts ?? 6;
|
|
21475
21498
|
const pollIntervalMs = dependencies.pollIntervalMs ?? 2e3;
|
|
21476
21499
|
const sleep = dependencies.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)));
|
|
21500
|
+
const responseStatus = input.trigger4xxStatus ?? 503;
|
|
21501
|
+
const activeMode = input.trigger4xxStatus !== void 0 ? "active_4xx" : "active_5xx";
|
|
21502
|
+
const activeCheckName = input.trigger4xxStatus !== void 0 ? "active-4xx-event" : "active-5xx-event";
|
|
21503
|
+
const statusLabel = input.trigger4xxStatus !== void 0 ? `${responseStatus}` : "5xx";
|
|
21477
21504
|
const verification = {
|
|
21478
|
-
mode:
|
|
21505
|
+
mode: activeMode,
|
|
21479
21506
|
bundle_status: "unknown",
|
|
21480
|
-
classification_reason: requestFailureReason()
|
|
21507
|
+
classification_reason: requestFailureReason(responseStatus)
|
|
21481
21508
|
};
|
|
21482
21509
|
const errors = [];
|
|
21483
21510
|
let exitCode = 0;
|
|
21484
21511
|
let tokenId = null;
|
|
21485
21512
|
let incidentId;
|
|
21486
|
-
let activeStep =
|
|
21513
|
+
let activeStep = activeCheckName;
|
|
21487
21514
|
try {
|
|
21488
21515
|
const token = await createProjectToken({
|
|
21489
21516
|
bearerToken: authState.bearer_token,
|
|
@@ -21497,7 +21524,8 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21497
21524
|
const event = buildCloudVerificationEvent({
|
|
21498
21525
|
now: verificationStartedAt,
|
|
21499
21526
|
serviceName,
|
|
21500
|
-
environment
|
|
21527
|
+
environment,
|
|
21528
|
+
responseStatus
|
|
21501
21529
|
});
|
|
21502
21530
|
const ingestion = await sendEvents({
|
|
21503
21531
|
baseUrl: authState.base_url,
|
|
@@ -21506,12 +21534,12 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21506
21534
|
});
|
|
21507
21535
|
verification.accepted_event_count = ingestion.accepted;
|
|
21508
21536
|
if (ingestion.accepted < 1 || ingestion.rejected > 0 || ingestion.errors.length > 0) {
|
|
21509
|
-
throw new Error(`Synthetic
|
|
21537
|
+
throw new Error(`Synthetic ${statusLabel} ingestion was not fully accepted: accepted=${ingestion.accepted}, rejected=${ingestion.rejected}.`);
|
|
21510
21538
|
}
|
|
21511
21539
|
checks.push({
|
|
21512
|
-
name:
|
|
21540
|
+
name: activeCheckName,
|
|
21513
21541
|
status: "ok",
|
|
21514
|
-
message:
|
|
21542
|
+
message: `Sent synthetic ${statusLabel} request_event through cloud ingestion.`
|
|
21515
21543
|
});
|
|
21516
21544
|
activeStep = "incident-retrieval";
|
|
21517
21545
|
for (let attempt = 1; attempt <= pollAttempts; attempt += 1) {
|
|
@@ -21529,7 +21557,7 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21529
21557
|
if (candidate !== void 0) {
|
|
21530
21558
|
incidentId = candidate.incident_id;
|
|
21531
21559
|
verification.incident_id = candidate.incident_id;
|
|
21532
|
-
verification.classification_reason = candidate.incident_reason ?? requestFailureReason();
|
|
21560
|
+
verification.classification_reason = candidate.incident_reason ?? requestFailureReason(responseStatus);
|
|
21533
21561
|
break;
|
|
21534
21562
|
}
|
|
21535
21563
|
if (attempt < pollAttempts) {
|
|
@@ -21537,12 +21565,12 @@ async function verifyCloudCommand(input, dependencies = {}) {
|
|
|
21537
21565
|
}
|
|
21538
21566
|
}
|
|
21539
21567
|
if (incidentId === void 0) {
|
|
21540
|
-
throw new Error(
|
|
21568
|
+
throw new Error(`Synthetic ${statusLabel} request was accepted but no matching cloud incident was visible yet.`);
|
|
21541
21569
|
}
|
|
21542
21570
|
checks.push({
|
|
21543
21571
|
name: "incident-retrieval",
|
|
21544
21572
|
status: "ok",
|
|
21545
|
-
message: `Retrieved cloud incident ${incidentId} for the synthetic
|
|
21573
|
+
message: `Retrieved cloud incident ${incidentId} for the synthetic ${statusLabel} request.`
|
|
21546
21574
|
});
|
|
21547
21575
|
activeStep = "bundle-status";
|
|
21548
21576
|
const bundle = await getBundle({
|
|
@@ -23282,6 +23310,7 @@ function createSetupMcpTools(commands) {
|
|
|
23282
23310
|
...typeof input["environment"] === "string" ? { environment: input["environment"] } : {},
|
|
23283
23311
|
...typeof input["maxAgeMinutes"] === "number" ? { maxAgeMinutes: input["maxAgeMinutes"] } : {},
|
|
23284
23312
|
...input["trigger5xx"] === true ? { trigger5xx: true } : {},
|
|
23313
|
+
...typeof input["trigger4xxStatus"] === "number" ? { trigger4xxStatus: input["trigger4xxStatus"] } : {},
|
|
23285
23314
|
...typeof input["authFilePath"] === "string" ? { authFilePath: input["authFilePath"] } : {},
|
|
23286
23315
|
json: true
|
|
23287
23316
|
})
|
|
@@ -25054,13 +25083,14 @@ var MCP_TOOL_CATALOG = [
|
|
|
25054
25083
|
{
|
|
25055
25084
|
name: "verify_cloud",
|
|
25056
25085
|
group: "setup",
|
|
25057
|
-
description: "Verify
|
|
25086
|
+
description: "Verify hosted ingestion or actively prove hosted incident creation.",
|
|
25058
25087
|
inputSchema: external_exports.object({
|
|
25059
25088
|
projectId: external_exports.string(),
|
|
25060
25089
|
service: external_exports.string().optional(),
|
|
25061
25090
|
environment: external_exports.string().optional(),
|
|
25062
25091
|
maxAgeMinutes: external_exports.number().optional(),
|
|
25063
25092
|
trigger5xx: external_exports.boolean().optional(),
|
|
25093
|
+
trigger4xxStatus: external_exports.number().int().min(400).max(499).optional(),
|
|
25064
25094
|
authFilePath: external_exports.string().optional()
|
|
25065
25095
|
})
|
|
25066
25096
|
},
|