@belvador/mcp 0.5.0 → 0.6.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.
Files changed (2) hide show
  1. package/dist/cli.js +913 -412
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -182,7 +182,7 @@ function cleanUntrustedText(raw, maxBytes = MCP_LIMITS.untrustedStringMaxBytes)
182
182
  const { text, cut } = cutUtf8(escaped, maxBytes);
183
183
  return { text, cut, suspicious };
184
184
  }
185
- var MCP_TOOLS_VERSION = 5;
185
+ var MCP_TOOLS_VERSION = 6;
186
186
  var MCP_TOOLS = [
187
187
  { name: "get_workspace", toolset: "investigate", scope: "org:read", readOnly: true, destructive: false, idempotent: true },
188
188
  { name: "list_projects", toolset: "investigate", scope: "projects:read", readOnly: true, destructive: false, idempotent: true },
@@ -211,9 +211,7 @@ var MCP_TOOLS = [
211
211
  { name: "search_docs", toolset: "docs", scope: null, readOnly: true, destructive: false, idempotent: true },
212
212
  { name: "get_doc", toolset: "docs", scope: null, readOnly: true, destructive: false, idempotent: true }
213
213
  ];
214
- var MCP_TOOLS_PENDING = {
215
- release_health: "P15"
216
- };
214
+ var MCP_TOOLS_PENDING = {};
217
215
 
218
216
  // ../src/shared/mcp/docs.ts
219
217
  var DOCS_MAX_BYTES = 512 * 1024;
@@ -257,7 +255,7 @@ function docsFetcher(siteUrl, fetcher = fetch, now = () => Date.now()) {
257
255
  import { CLIENT_CAPABILITIES_META_KEY, inputRequired, McpServer } from "@modelcontextprotocol/server";
258
256
 
259
257
  // ../src/shared/contracts/mcp-tools.ts
260
- import { z as z29 } from "zod";
258
+ import { z as z31 } from "zod";
261
259
 
262
260
  // ../src/shared/contracts/api-ops/access.ts
263
261
  import { z as z3 } from "zod";
@@ -2182,6 +2180,48 @@ import { z as z16 } from "zod";
2182
2180
 
2183
2181
  // ../src/shared/contracts/signed-message.ts
2184
2182
  import { z as z15 } from "zod";
2183
+
2184
+ // ../src/shared/contracts/limits.ts
2185
+ var INGEST_LIMITS = {
2186
+ envelopeCompressedMaxBytes: 20 * 1024 * 1024,
2187
+ decompressedMaxBytes: 200 * 1024 * 1024,
2188
+ maxCompressionRatio: 50,
2189
+ eventItemMaxBytes: 1024 * 1024,
2190
+ attachmentMaxBytes: 5 * 1024 * 1024,
2191
+ jsonMaxDepth: 20,
2192
+ jsonMaxKeysPerObject: 1000,
2193
+ jsonMaxKeysTotal: 1e4,
2194
+ jsonHardMaxDepth: 128,
2195
+ stringMaxChars: 8192,
2196
+ framesMaxPerException: 250,
2197
+ exceptionsMax: 10,
2198
+ breadcrumbsMax: 100,
2199
+ tagsMax: 20,
2200
+ tagKeyMaxChars: 32,
2201
+ tagValueMaxChars: 200,
2202
+ sourceMapMaxBytes: 10 * 1024 * 1024,
2203
+ sourceMapSegmentMaxChars: 1024,
2204
+ envelopeItemsMax: 100
2205
+ };
2206
+ var BUFFER_LIMITS = {
2207
+ queueInlineMaxBytes: 100 * 1024,
2208
+ maxAgeDays: 14,
2209
+ nodeMaxBytes: 8 * 1024 ** 3,
2210
+ alertRatio: 0.8,
2211
+ alertInflowPerSecond: 5000
2212
+ };
2213
+ var RELAY_LIMITS = {
2214
+ chunkBytes: 512 * 1024,
2215
+ maxInflightMessages: 4,
2216
+ maxInflightBytes: 24 * 1024 * 1024,
2217
+ clockSkewSeconds: 60,
2218
+ nonceMemorySeconds: 600,
2219
+ ackTimeoutMs: 2000,
2220
+ heartbeatSeconds: 30,
2221
+ reconnectMaxSeconds: 30
2222
+ };
2223
+
2224
+ // ../src/shared/contracts/signed-message.ts
2185
2225
  var nodeIdSchema = z15.guid();
2186
2226
  var signedEnvelopeSchema = z15.object({
2187
2227
  node_id: nodeIdSchema,
@@ -3089,19 +3129,277 @@ var MONITOR_OPERATIONS = [
3089
3129
  ];
3090
3130
 
3091
3131
  // ../src/shared/contracts/api-ops/node-data.ts
3132
+ import { z as z22 } from "zod";
3133
+
3134
+ // ../src/shared/contracts/release-health.ts
3135
+ import { z as z21 } from "zod";
3136
+
3137
+ // ../src/shared/contracts/sourcemaps.ts
3092
3138
  import { z as z20 } from "zod";
3093
- var issueId = z20.number().int().positive();
3094
- var csv = z20.string().min(1).max(2000);
3095
- var name2 = z20.string().min(1).max(256);
3096
- var period = z20.enum(["1h", "24h", "7d", "14d", "30d"]);
3097
- var nodeCursor = z20.string().min(1).max(600).optional();
3139
+ var UPLOAD_LIMITS = {
3140
+ requestMaxBytes: RELAY_LIMITS.maxInflightBytes - 512 * 1024,
3141
+ tarMaxBytes: 64 * 1024 * 1024,
3142
+ fileMaxBytes: INGEST_LIMITS.sourceMapMaxBytes,
3143
+ filesMax: 1000,
3144
+ requestsPerHour: 60,
3145
+ retentionDays: 90
3146
+ };
3147
+ var UPLOAD_SCOPES = ["sourcemaps:write", "releases:write"];
3148
+ var UPLOAD_TOKEN_PATTERN = /^blv_sm_[A-Za-z0-9_-]{43}$/;
3149
+ var tokenHashSchema = z20.string().regex(/^[a-f0-9]{64}$/);
3150
+ var uploadTokenConfigSchema = z20.object({
3151
+ v: z20.literal(1),
3152
+ project_id: z20.number().int().positive(),
3153
+ project_public_id: z20.number().int().positive(),
3154
+ node_id: nodeIdSchema,
3155
+ workspace_id: z20.guid(),
3156
+ scopes: z20.array(z20.enum(UPLOAD_SCOPES)).min(1).max(4),
3157
+ expires_at: z20.string().datetime(),
3158
+ is_active: z20.boolean()
3159
+ });
3160
+ var releaseNameSchema = z20.string().min(1).max(200).regex(/^[^\s/\\\u0000-\u001f\u007f]+$/);
3161
+ var SENTRY_COMPAT = {
3162
+ apiRoot: "/api/0",
3163
+ chunkSize: 2 * 1024 * 1024,
3164
+ chunksPerRequest: 3,
3165
+ maxRequestSize: 7 * 1024 * 1024,
3166
+ maxFileSize: 64 * 1024 * 1024,
3167
+ maxBundleEntries: 4000,
3168
+ concurrency: 1,
3169
+ maxWaitSeconds: 60,
3170
+ chunkBytesPerHour: 1024 * 1024 * 1024,
3171
+ pendingBytesPerProject: 128 * 1024 * 1024,
3172
+ pendingTtlMs: 60 * 60 * 1000
3173
+ };
3174
+ var sha1HexSchema = z20.string().regex(/^[0-9a-f]{40}$/);
3175
+ var assembleRequestSchema = z20.object({
3176
+ checksum: sha1HexSchema,
3177
+ chunks: z20.array(sha1HexSchema).max(Math.ceil(SENTRY_COMPAT.maxFileSize / SENTRY_COMPAT.chunkSize)),
3178
+ projects: z20.array(z20.string().max(200)).max(50).optional(),
3179
+ version: releaseNameSchema.optional(),
3180
+ dist: z20.string().max(64).regex(/^[A-Za-z0-9._-]*$/).optional()
3181
+ });
3182
+ var assembleResponseSchema = z20.object({
3183
+ state: z20.enum(["ok", "created", "assembling", "not_found", "error"]),
3184
+ missingChunks: z20.array(sha1HexSchema),
3185
+ detail: z20.string().max(200).nullable()
3186
+ });
3187
+ var uploadHeaderSchema = z20.object({
3188
+ id: z20.string().regex(/^[A-Za-z0-9_-]{8,64}$/),
3189
+ project_id: z20.number().int().positive(),
3190
+ release: releaseNameSchema.optional(),
3191
+ dist: z20.string().max(64).regex(/^[A-Za-z0-9._-]*$/).optional(),
3192
+ token: z20.string().regex(UPLOAD_TOKEN_PATTERN),
3193
+ content_encoding: z20.enum(["identity", "gzip"]),
3194
+ op: z20.enum(["tar", "chunks", "assemble", "release"]).optional(),
3195
+ chunks: z20.array(z20.object({
3196
+ sha1: sha1HexSchema,
3197
+ size: z20.number().int().positive().max(SENTRY_COMPAT.chunkSize)
3198
+ })).max(SENTRY_COMPAT.chunksPerRequest).optional()
3199
+ });
3200
+ var uploadResultSchema = z20.object({
3201
+ accepted: z20.array(z20.object({ file: z20.string().max(200), debug_id: z20.guid(), size: z20.number().int() })).max(UPLOAD_LIMITS.filesMax),
3202
+ skipped: z20.array(z20.object({
3203
+ file: z20.string().max(200),
3204
+ reason: z20.enum([
3205
+ "not_a_map",
3206
+ "no_debug_id",
3207
+ "too_large",
3208
+ "invalid_json",
3209
+ "unsupported",
3210
+ "bad_name"
3211
+ ])
3212
+ })).max(UPLOAD_LIMITS.filesMax)
3213
+ });
3214
+
3215
+ // ../src/shared/contracts/release-health.ts
3216
+ var RELEASE_HEALTH = {
3217
+ verifyHours: 24,
3218
+ windowHours: 24,
3219
+ increaseFactor: 2,
3220
+ increaseMinEvents: 10,
3221
+ listMax: 50,
3222
+ candidatesMax: 500,
3223
+ releasesMax: 50,
3224
+ commitsMax: 1000,
3225
+ deploysMax: 50,
3226
+ memoryReleasesMax: 5000,
3227
+ memoryDeploysMax: 1e4,
3228
+ requestsPerHour: 600,
3229
+ bodyMaxBytes: 4 * 1024 * 1024,
3230
+ fixLookbackDays: 30
3231
+ };
3232
+ var FIX_STATUSES = ["fixed", "not_fixed", "unverified", "unknown"];
3233
+ var FIX_REASONS = [
3234
+ "verified",
3235
+ "event_in_release",
3236
+ "regressed",
3237
+ "order_unknown",
3238
+ "not_deployed",
3239
+ "no_deploy_marker",
3240
+ "not_running",
3241
+ "too_early"
3242
+ ];
3243
+ var RESOLUTION_MODES = ["now", "next_release", "in_release"];
3244
+ var RELEASE_SOURCES = ["cli", "api", "sdk"];
3245
+ var environmentNameSchema = z21.string().trim().regex(ENVIRONMENT_RE).refine((v) => !/[\s/]/.test(v));
3246
+ var isoTime = z21.string().datetime({ offset: true });
3247
+ var httpUrl = z21.string().max(500).refine((v) => /^https?:\/\/[^\s]+$/i.test(v), "http(s) URL");
3248
+ var DEPLOY_ID_RE = /^[A-Za-z0-9_.:-]{1,64}$/;
3249
+ var commitShaSchema = z21.string().regex(/^[0-9A-Za-z._-]{4,64}$/);
3250
+ var repoNameSchema = z21.string().min(1).max(200).regex(/^[^\u0000-\u001f\u007f]+$/);
3251
+ var deploymentInputSchema = z21.object({
3252
+ version: releaseNameSchema,
3253
+ environment: environmentNameSchema,
3254
+ name: z21.string().trim().min(1).max(200).optional(),
3255
+ url: httpUrl.optional(),
3256
+ started_at: isoTime.optional(),
3257
+ finished_at: isoTime.optional(),
3258
+ deploy_id: z21.string().regex(DEPLOY_ID_RE).optional()
3259
+ });
3260
+ var commitSchema = z21.object({ sha: commitShaSchema, repo: repoNameSchema.optional() });
3261
+ var releaseRelaySchema = z21.discriminatedUnion("action", [
3262
+ z21.object({
3263
+ action: z21.literal("create"),
3264
+ version: releaseNameSchema,
3265
+ date_released: isoTime.optional(),
3266
+ commits: z21.array(commitSchema).max(RELEASE_HEALTH.commitsMax).optional()
3267
+ }),
3268
+ z21.object({
3269
+ action: z21.literal("update"),
3270
+ version: releaseNameSchema,
3271
+ date_released: isoTime.optional(),
3272
+ commits: z21.array(commitSchema).max(RELEASE_HEALTH.commitsMax).optional()
3273
+ }),
3274
+ z21.object({ action: z21.literal("get"), version: releaseNameSchema }),
3275
+ z21.object({ action: z21.literal("list") }),
3276
+ z21.object({ action: z21.literal("previous"), version: releaseNameSchema }),
3277
+ z21.object({ action: z21.literal("deploy"), deploy: deploymentInputSchema }),
3278
+ z21.object({ action: z21.literal("deploys"), version: releaseNameSchema })
3279
+ ]);
3280
+ var cliCommit = z21.object({ id: z21.string().max(200), repository: z21.string().max(400).nullish() }).passthrough();
3281
+ var cliRef = z21.object({
3282
+ repository: z21.string().max(400),
3283
+ commit: z21.string().max(200),
3284
+ previousCommit: z21.string().max(200).nullish()
3285
+ }).passthrough();
3286
+ var cliReleaseCreateSchema = z21.object({
3287
+ version: releaseNameSchema,
3288
+ projects: z21.array(z21.string().max(200)).max(50).optional(),
3289
+ dateReleased: isoTime.nullish(),
3290
+ dateStarted: isoTime.nullish(),
3291
+ refs: z21.array(cliRef).max(100).optional(),
3292
+ commits: z21.array(cliCommit).max(1e4).optional()
3293
+ }).passthrough();
3294
+ var cliReleaseUpdateSchema = cliReleaseCreateSchema.omit({ version: true }).extend({ version: releaseNameSchema.optional() });
3295
+ var cliDeployCreateSchema = z21.object({
3296
+ environment: z21.string().max(64),
3297
+ name: z21.string().max(200).nullish(),
3298
+ url: z21.string().max(500).nullish(),
3299
+ dateStarted: isoTime.nullish(),
3300
+ dateFinished: isoTime.nullish()
3301
+ }).passthrough();
3302
+ var iso5 = z21.string();
3303
+ var releaseRowSchema = z21.object({
3304
+ version: z21.string(),
3305
+ source: z21.enum(RELEASE_SOURCES),
3306
+ environment: z21.string().nullable(),
3307
+ created_at: iso5.nullable(),
3308
+ date_released: iso5.nullable(),
3309
+ deployed_at: iso5.nullable(),
3310
+ last_deploy_at: iso5.nullable(),
3311
+ deploys: z21.number().int(),
3312
+ first_seen: iso5.nullable(),
3313
+ last_seen: iso5.nullable(),
3314
+ commit_count: z21.number().int(),
3315
+ events: z21.number().int(),
3316
+ events_per_hour: z21.number(),
3317
+ previous: z21.string().nullable(),
3318
+ previous_events_per_hour: z21.number().nullable(),
3319
+ new_issues: z21.number().int(),
3320
+ regressed_issues: z21.number().int(),
3321
+ increased_issues: z21.number().int()
3322
+ });
3323
+ var releaseListSchema = z21.object({
3324
+ releases: z21.array(releaseRowSchema),
3325
+ environments: z21.array(z21.string()),
3326
+ environment: z21.string().nullable(),
3327
+ has_deploy_markers: z21.boolean()
3328
+ });
3329
+ var healthIssueSchema = z21.object({
3330
+ issue_id: z21.number().int(),
3331
+ short_id: z21.string(),
3332
+ title: z21.string(),
3333
+ culprit: z21.string(),
3334
+ level: z21.string(),
3335
+ status: z21.string(),
3336
+ events: z21.number().int(),
3337
+ previous_events: z21.number().int(),
3338
+ first_seen: iso5.nullable(),
3339
+ sparkline: z21.array(z21.number().int())
3340
+ });
3341
+ var deploymentRowSchema = z21.object({
3342
+ deploy_id: z21.string(),
3343
+ version: z21.string(),
3344
+ environment: z21.string(),
3345
+ name: z21.string().nullable(),
3346
+ url: z21.string().nullable(),
3347
+ started_at: iso5,
3348
+ finished_at: iso5,
3349
+ source: z21.enum(RELEASE_SOURCES)
3350
+ });
3351
+ var releaseHealthSchema = z21.object({
3352
+ release: releaseRowSchema,
3353
+ compare: z21.string().nullable(),
3354
+ window: z21.object({
3355
+ start: iso5.nullable(),
3356
+ end: iso5.nullable(),
3357
+ hours: z21.number(),
3358
+ from_deploy: z21.boolean()
3359
+ }),
3360
+ new: z21.array(healthIssueSchema),
3361
+ regressed: z21.array(healthIssueSchema),
3362
+ increased: z21.array(healthIssueSchema),
3363
+ deploys: z21.array(deploymentRowSchema),
3364
+ commits: z21.array(commitSchema),
3365
+ truncated: z21.boolean()
3366
+ });
3367
+ var fixEnvSchema = z21.object({
3368
+ environment: z21.string(),
3369
+ status: z21.enum(FIX_STATUSES),
3370
+ reason: z21.enum(FIX_REASONS),
3371
+ target: z21.string().nullable(),
3372
+ target_deployed_at: iso5.nullable(),
3373
+ release: z21.string().nullable(),
3374
+ first_seen: iso5.nullable(),
3375
+ observed_hours: z21.number().nullable()
3376
+ });
3377
+ var fixStatusSchema = z21.object({
3378
+ issue_id: z21.number().int(),
3379
+ resolution: z21.object({
3380
+ mode: z21.enum(RESOLUTION_MODES),
3381
+ resolved_at: iso5,
3382
+ release: z21.string().nullable(),
3383
+ regressed: z21.boolean()
3384
+ }).nullable(),
3385
+ status: z21.enum(FIX_STATUSES).nullable(),
3386
+ environments: z21.array(fixEnvSchema),
3387
+ verify_hours: z21.number()
3388
+ });
3389
+
3390
+ // ../src/shared/contracts/api-ops/node-data.ts
3391
+ var issueId = z22.number().int().positive();
3392
+ var csv = z22.string().min(1).max(2000);
3393
+ var name2 = z22.string().min(1).max(256);
3394
+ var period = z22.enum(["1h", "24h", "7d", "14d", "30d"]);
3395
+ var nodeCursor = z22.string().min(1).max(600).optional();
3098
3396
  var windowFields = {
3099
- start: z20.string().max(40).optional(),
3100
- end: z20.string().max(40).optional()
3397
+ start: z22.string().max(40).optional(),
3398
+ end: z22.string().max(40).optional()
3101
3399
  };
3102
- var traceId = z20.string().regex(/^[0-9a-fA-F]{32}$/);
3103
- var spanId = z20.string().regex(/^[0-9a-fA-F]{16}$/);
3104
- var attrs = z20.string().max(2000).optional();
3400
+ var traceId = z22.string().regex(/^[0-9a-fA-F]{32}$/);
3401
+ var spanId = z22.string().regex(/^[0-9a-fA-F]{16}$/);
3402
+ var attrs = z22.string().max(2000).optional();
3105
3403
  var telemetryCommon = {
3106
3404
  ...windowFields,
3107
3405
  project: csv.optional(),
@@ -3109,134 +3407,167 @@ var telemetryCommon = {
3109
3407
  service: csv.optional(),
3110
3408
  attrs
3111
3409
  };
3112
- var issueChange = z20.union([
3113
- z20.object({ action: z20.literal("resolve"), inNextRelease: z20.boolean().optional() }),
3114
- z20.object({ action: z20.literal("unresolve") }),
3115
- z20.object({ action: z20.literal("archive"), mode: z20.enum(["until_escalating", "forever"]) }),
3116
- z20.object({
3117
- action: z20.literal("archive"),
3118
- mode: z20.literal("until_condition"),
3119
- events: z20.number().int().min(1).max(1e6).optional(),
3120
- users: z20.number().int().min(1).max(1e5).optional(),
3121
- until: z20.string().datetime().optional()
3122
- }),
3123
- z20.object({ action: z20.literal("assign"), userId: z20.guid().nullable() }),
3124
- z20.object({ action: z20.literal("priority"), priority: z20.enum(["low", "medium", "high"]) })
3410
+ var issueChange = z22.union([
3411
+ z22.object({
3412
+ action: z22.literal("resolve"),
3413
+ inNextRelease: z22.boolean().optional(),
3414
+ inRelease: releaseNameSchema.optional()
3415
+ }),
3416
+ z22.object({ action: z22.literal("unresolve") }),
3417
+ z22.object({ action: z22.literal("archive"), mode: z22.enum(["until_escalating", "forever"]) }),
3418
+ z22.object({
3419
+ action: z22.literal("archive"),
3420
+ mode: z22.literal("until_condition"),
3421
+ events: z22.number().int().min(1).max(1e6).optional(),
3422
+ users: z22.number().int().min(1).max(1e5).optional(),
3423
+ until: z22.string().datetime().optional()
3424
+ }),
3425
+ z22.object({ action: z22.literal("assign"), userId: z22.guid().nullable() }),
3426
+ z22.object({ action: z22.literal("priority"), priority: z22.enum(["low", "medium", "high"]) })
3125
3427
  ]);
3126
3428
  var NODE_INPUTS = {
3127
- issuesList: z20.object({
3429
+ issuesList: z22.object({
3128
3430
  project: csv.optional(),
3129
- status: z20.enum(["unresolved", "resolved", "archived", "all"]).optional(),
3431
+ status: z22.enum(["unresolved", "resolved", "archived", "all"]).optional(),
3130
3432
  level: csv.optional(),
3131
3433
  priority: csv.optional(),
3132
3434
  environment: csv.optional(),
3133
3435
  release: csv.optional(),
3134
- assignee: z20.string().max(64).optional(),
3436
+ assignee: z22.string().max(64).optional(),
3135
3437
  period: period.optional(),
3136
- q: z20.string().max(200).optional(),
3137
- sort: z20.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
3438
+ q: z22.string().max(200).optional(),
3439
+ sort: z22.enum(["last_seen", "first_seen", "events", "users", "priority"]).optional(),
3138
3440
  cursor: nodeCursor,
3139
- limit: z20.number().int().min(1).max(100).optional()
3441
+ limit: z22.number().int().min(1).max(100).optional()
3140
3442
  }),
3141
- issue: z20.object({ issueId }),
3142
- issueStats: z20.object({ issueId, range: z20.enum(["24h", "30d"]).optional() }),
3143
- issueEvents: z20.object({ issueId, cursor: nodeCursor }),
3144
- issueEvent: z20.object({
3443
+ issue: z22.object({ issueId }),
3444
+ issueStats: z22.object({ issueId, range: z22.enum(["24h", "30d"]).optional() }),
3445
+ issueEvents: z22.object({ issueId, cursor: nodeCursor }),
3446
+ issueEvent: z22.object({
3145
3447
  issueId,
3146
- eventId: z20.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
3448
+ eventId: z22.string().regex(/^([0-9a-f]{32}|latest|oldest)$/)
3147
3449
  }),
3148
- issueUpdate: z20.object({ issueId, change: issueChange }),
3149
- issuesBulk: z20.object({
3150
- issueIds: z20.array(issueId).min(1).max(100),
3450
+ issueUpdate: z22.object({ issueId, change: issueChange }),
3451
+ issuesBulk: z22.object({
3452
+ issueIds: z22.array(issueId).min(1).max(100),
3151
3453
  action: issueChange
3152
3454
  }),
3153
- spansList: z20.object({
3455
+ spansList: z22.object({
3154
3456
  ...telemetryCommon,
3155
- operation: z20.string().min(1).max(1024).optional(),
3156
- status: z20.enum(["unset", "ok", "error"]).optional(),
3157
- kind: z20.enum(["internal", "server", "client", "producer", "consumer"]).optional(),
3158
- minDurationMs: z20.number().min(0).max(86400000).optional(),
3159
- maxDurationMs: z20.number().min(0).max(86400000).optional(),
3160
- mode: z20.enum(["spans", "traces"]).optional(),
3457
+ operation: z22.string().min(1).max(1024).optional(),
3458
+ status: z22.enum(["unset", "ok", "error"]).optional(),
3459
+ kind: z22.enum(["internal", "server", "client", "producer", "consumer"]).optional(),
3460
+ minDurationMs: z22.number().min(0).max(86400000).optional(),
3461
+ maxDurationMs: z22.number().min(0).max(86400000).optional(),
3462
+ mode: z22.enum(["spans", "traces"]).optional(),
3161
3463
  cursor: nodeCursor
3162
3464
  }),
3163
- spansHistogram: z20.object({
3465
+ spansHistogram: z22.object({
3164
3466
  ...telemetryCommon,
3165
- operation: z20.string().min(1).max(1024).optional(),
3166
- status: z20.enum(["unset", "ok", "error"]).optional()
3467
+ operation: z22.string().min(1).max(1024).optional(),
3468
+ status: z22.enum(["unset", "ok", "error"]).optional()
3167
3469
  }),
3168
- trace: z20.object({ traceId }),
3169
- traceSpans: z20.object({ traceId, errorsOnly: z20.enum(["1"]).optional(), ...windowFields }),
3170
- span: z20.object({ traceId, spanId, ...windowFields }),
3171
- logsList: z20.object({
3470
+ trace: z22.object({ traceId }),
3471
+ traceSpans: z22.object({ traceId, errorsOnly: z22.enum(["1"]).optional(), ...windowFields }),
3472
+ span: z22.object({ traceId, spanId, ...windowFields }),
3473
+ logsList: z22.object({
3172
3474
  ...telemetryCommon,
3173
- severityMin: z20.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3475
+ severityMin: z22.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3174
3476
  traceId: traceId.optional(),
3175
3477
  spanId: spanId.optional(),
3176
- q: z20.string().max(500).optional(),
3177
- order: z20.enum(["asc", "desc"]).optional(),
3478
+ q: z22.string().max(500).optional(),
3479
+ order: z22.enum(["asc", "desc"]).optional(),
3178
3480
  cursor: nodeCursor
3179
3481
  }),
3180
- logsFacets: z20.object({
3482
+ logsFacets: z22.object({
3181
3483
  ...telemetryCommon,
3182
- severityMin: z20.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3183
- q: z20.string().max(500).optional()
3184
- }),
3185
- logAround: z20.object({
3186
- logId: name2,
3187
- at: z20.string().max(40),
3188
- same: z20.enum(["service", "trace"]).optional(),
3189
- before: z20.number().int().min(0).max(200).optional(),
3190
- after: z20.number().int().min(0).max(200).optional()
3191
- }),
3192
- metricsNames: z20.object({
3193
- project: z20.number().int().positive(),
3484
+ severityMin: z22.enum(["trace", "debug", "info", "warn", "error", "fatal"]).optional(),
3485
+ q: z22.string().max(500).optional()
3486
+ }),
3487
+ logAround: z22.object({
3488
+ logId: z22.guid(),
3489
+ at: z22.string().max(40),
3490
+ same: z22.enum(["service", "trace"]).optional(),
3491
+ before: z22.number().int().min(0).max(200).optional(),
3492
+ after: z22.number().int().min(0).max(200).optional()
3493
+ }),
3494
+ metricsNames: z22.object({
3495
+ project: z22.number().int().positive(),
3194
3496
  environment: csv.optional(),
3195
- q: z20.string().max(255).optional()
3497
+ q: z22.string().max(255).optional()
3196
3498
  }),
3197
- metricsSeries: z20.object({
3198
- project: z20.number().int().positive(),
3199
- name: z20.string().regex(METRIC_NAME_RE),
3499
+ metricsSeries: z22.object({
3500
+ project: z22.number().int().positive(),
3501
+ name: z22.string().regex(METRIC_NAME_RE),
3200
3502
  environment: csv.optional(),
3201
3503
  attrs,
3202
- cursor: z20.string().regex(/^[0-9a-f]{16}$/).optional()
3504
+ cursor: z22.string().regex(/^[0-9a-f]{16}$/).optional()
3203
3505
  }),
3204
- metricsQuery: z20.object({
3205
- project: z20.number().int().positive(),
3206
- name: z20.string().regex(METRIC_NAME_RE),
3207
- aggregation: z20.enum(METRIC_AGGREGATIONS),
3506
+ metricsQuery: z22.object({
3507
+ project: z22.number().int().positive(),
3508
+ name: z22.string().regex(METRIC_NAME_RE),
3509
+ aggregation: z22.enum(METRIC_AGGREGATIONS),
3208
3510
  ...windowFields,
3209
- step: z20.number().int().min(METRIC_QUERY.minStepSeconds).max(METRIC_QUERY.maxStepSeconds).multipleOf(60).optional(),
3511
+ step: z22.number().int().min(METRIC_QUERY.minStepSeconds).max(METRIC_QUERY.maxStepSeconds).multipleOf(60).optional(),
3210
3512
  attrs,
3211
- groupBy: z20.string().min(1).max(600).optional(),
3513
+ groupBy: z22.string().min(1).max(600).optional(),
3212
3514
  environment: csv.optional()
3213
3515
  }),
3214
- telemetryUsage: z20.object({ project: csv.optional(), days: z20.number().int().min(1).max(31).optional() }),
3215
- monitorSignal: z20.object({ monitorId: z20.guid(), hours: z20.number().int().min(1).max(24).optional() }),
3216
- monitorOccurrences: z20.object({
3217
- monitorId: z20.guid(),
3218
- state: z20.enum(["open", "finished", "all"]).optional(),
3219
- environment: z20.string().min(1).max(64).optional(),
3516
+ telemetryUsage: z22.object({
3517
+ project: csv.optional(),
3518
+ days: z22.number().int().min(1).max(31).optional()
3519
+ }),
3520
+ monitorSignal: z22.object({
3521
+ monitorId: z22.guid(),
3522
+ hours: z22.number().int().min(1).max(24).optional()
3523
+ }),
3524
+ monitorOccurrences: z22.object({
3525
+ monitorId: z22.guid(),
3526
+ state: z22.enum(["open", "finished", "all"]).optional(),
3527
+ environment: z22.string().min(1).max(64).optional(),
3220
3528
  cursor: nodeCursor
3221
3529
  }),
3222
- monitorBacktest: z20.object({ project: z20.number().int().positive(), settings: backtestSettingsSchema }),
3223
- occurrenceCreate: z20.object({
3224
- project: z20.number().int().positive(),
3530
+ monitorBacktest: z22.object({
3531
+ project: z22.number().int().positive(),
3532
+ settings: backtestSettingsSchema
3533
+ }),
3534
+ occurrenceCreate: z22.object({
3535
+ project: z22.number().int().positive(),
3225
3536
  monitorSlug: occurrenceInputSchema.shape.monitor_slug,
3226
3537
  occurrenceId: occurrenceInputSchema.shape.occurrence_id,
3227
3538
  dueAt: occurrenceInputSchema.shape.due_at,
3228
3539
  environment: occurrenceInputSchema.shape.environment
3229
3540
  }),
3230
- occurrenceCancel: z20.object({
3231
- project: z20.number().int().positive(),
3232
- monitorSlug: z20.string().regex(SLUG_RE),
3233
- occurrenceId: z20.string().regex(OCCURRENCE_ID_RE),
3234
- environment: z20.string().min(1).max(64).optional()
3235
- }),
3236
- ticket: z20.object({
3237
- scope: z20.enum(["read", "write"]).default("read"),
3238
- project: z20.number().int().positive().optional(),
3239
- environment: z20.string().min(1).max(64).optional()
3541
+ occurrenceCancel: z22.object({
3542
+ project: z22.number().int().positive(),
3543
+ monitorSlug: z22.string().regex(SLUG_RE),
3544
+ occurrenceId: z22.string().regex(OCCURRENCE_ID_RE),
3545
+ environment: z22.string().min(1).max(64).optional()
3546
+ }),
3547
+ releasesList: z22.object({
3548
+ project: z22.number().int().positive(),
3549
+ environment: environmentNameSchema.optional()
3550
+ }),
3551
+ releaseHealth: z22.object({
3552
+ project: z22.number().int().positive(),
3553
+ version: releaseNameSchema,
3554
+ environment: environmentNameSchema.optional(),
3555
+ compare: releaseNameSchema.optional()
3556
+ }),
3557
+ deploymentCreate: z22.object({
3558
+ project: z22.number().int().positive(),
3559
+ version: deploymentInputSchema.shape.version,
3560
+ environment: deploymentInputSchema.shape.environment,
3561
+ name: deploymentInputSchema.shape.name,
3562
+ url: deploymentInputSchema.shape.url,
3563
+ startedAt: deploymentInputSchema.shape.started_at,
3564
+ finishedAt: deploymentInputSchema.shape.finished_at,
3565
+ deployId: deploymentInputSchema.shape.deploy_id
3566
+ }),
3567
+ ticket: z22.object({
3568
+ scope: z22.enum(["read", "write"]).default("read"),
3569
+ project: z22.number().int().positive().optional(),
3570
+ environment: z22.string().min(1).max(64).optional()
3240
3571
  })
3241
3572
  };
3242
3573
  var N = NODE_INPUTS;
@@ -3426,6 +3757,44 @@ var NODE_OPERATIONS = [
3426
3757
  node: { path: "q/metrics/query", window: true },
3427
3758
  summary: "One metric aggregated per step (avg, sum, min, max, count, rate, p50–p99) in a window of at most 7 days, optionally grouped by up to two attributes (≤ 50 groups, ≤ 10,000 points), with exemplar trace ids."
3428
3759
  }),
3760
+ op({
3761
+ ...read,
3762
+ id: "releases.list",
3763
+ path: "/v1/projects/{project}/releases",
3764
+ scope: "releases:read",
3765
+ input: N.releasesList,
3766
+ node: { path: "q/releases" },
3767
+ summary: "Releases of one project in one environment, newest first by deploy order (else version order): first and last deploy, events, issues, and the counts of new, regressed and increased issues in each release's first 24 hours."
3768
+ }),
3769
+ op({
3770
+ ...read,
3771
+ id: "releases.health",
3772
+ path: "/v1/projects/{project}/releases/{version}/health",
3773
+ scope: "releases:read",
3774
+ input: N.releaseHealth,
3775
+ node: { path: "q/releases/health" },
3776
+ summary: "One release in one environment against the previous one (or `compare`): new, regressed and increased issues in its first 24 hours (≤ 50 each, with hourly sparklines) and its deploy markers."
3777
+ }),
3778
+ op({
3779
+ ...read,
3780
+ id: "issues.fix_status",
3781
+ path: "/v1/issues/{issue_id}/fix-status",
3782
+ scope: "releases:read",
3783
+ input: N.issue,
3784
+ node: { path: "q/issues/{issue_id}/fix-status" },
3785
+ summary: "Whether a resolved issue is fixed in each environment it occurred in: fixed (a deploy of the target release and 24 h of its signals without the error), unverified, not fixed (with the event that broke it) or unknown; null while unresolved."
3786
+ }),
3787
+ op({
3788
+ ...read,
3789
+ id: "deployments.create",
3790
+ method: "POST",
3791
+ path: "/v1/projects/{project}/deployments",
3792
+ scope: "releases:write",
3793
+ input: N.deploymentCreate,
3794
+ node: { path: "w/releases/deployments", body: "*" },
3795
+ mcp: "configure",
3796
+ summary: "Record that a release was deployed to an environment (a deploy marker for CI without sentry-cli). Answers the marker and `created`; the same `deploy_id` again changes nothing (`created: false`)."
3797
+ }),
3429
3798
  op({
3430
3799
  ...read,
3431
3800
  id: "telemetry.usage",
@@ -3526,10 +3895,10 @@ var NODE_OPERATIONS = [
3526
3895
  ];
3527
3896
 
3528
3897
  // ../src/shared/contracts/api-ops/privacy.ts
3529
- import { z as z22 } from "zod";
3898
+ import { z as z24 } from "zod";
3530
3899
 
3531
3900
  // ../src/shared/contracts/privacy.ts
3532
- import { z as z21 } from "zod";
3901
+ import { z as z23 } from "zod";
3533
3902
 
3534
3903
  // ../src/shared/privacy/rules.ts
3535
3904
  var PRIVACY_SCHEMA = 1;
@@ -3559,44 +3928,44 @@ var IPV6_RE = new RegExp(`(^|[^0-9A-Fa-f:])((?:${H}:){7}${H}|(?:${H}:){1,6}:(?:$
3559
3928
  var REMOVE = Symbol("remove");
3560
3929
 
3561
3930
  // ../src/shared/contracts/privacy.ts
3562
- var ruleId = z21.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
3563
- var privacyRuleInputSchema = z21.object({
3931
+ var ruleId = z23.string().regex(/^[A-Za-z0-9_-]{1,64}$/);
3932
+ var privacyRuleInputSchema = z23.object({
3564
3933
  id: ruleId,
3565
- selector: z21.string().min(1).max(PRIVACY_LIMITS.selector),
3566
- type: z21.enum(PRIVACY_RULE_TYPES),
3567
- method: z21.enum(PRIVACY_METHODS),
3568
- pattern: z21.string().min(1).max(PRIVACY_LIMITS.pattern).optional(),
3569
- ignoreCase: z21.boolean().optional(),
3570
- replaceWith: z21.string().max(PRIVACY_LIMITS.replaceWith).optional(),
3571
- enabled: z21.boolean().optional()
3934
+ selector: z23.string().min(1).max(PRIVACY_LIMITS.selector),
3935
+ type: z23.enum(PRIVACY_RULE_TYPES),
3936
+ method: z23.enum(PRIVACY_METHODS),
3937
+ pattern: z23.string().min(1).max(PRIVACY_LIMITS.pattern).optional(),
3938
+ ignoreCase: z23.boolean().optional(),
3939
+ replaceWith: z23.string().max(PRIVACY_LIMITS.replaceWith).optional(),
3940
+ enabled: z23.boolean().optional()
3572
3941
  });
3573
- var privacyPolicyInputSchema = z21.object({
3574
- mode: z21.enum(PRIVACY_MODES),
3575
- rules: z21.array(privacyRuleInputSchema).max(PRIVACY_LIMITS.rules),
3576
- allowlist: z21.array(z21.string().min(1).max(PRIVACY_LIMITS.selector)).max(PRIVACY_LIMITS.allowlist)
3942
+ var privacyPolicyInputSchema = z23.object({
3943
+ mode: z23.enum(PRIVACY_MODES),
3944
+ rules: z23.array(privacyRuleInputSchema).max(PRIVACY_LIMITS.rules),
3945
+ allowlist: z23.array(z23.string().min(1).max(PRIVACY_LIMITS.selector)).max(PRIVACY_LIMITS.allowlist)
3577
3946
  });
3578
- var storedPolicySchema = z21.object({
3579
- schema: z21.literal(PRIVACY_SCHEMA),
3580
- version: z21.number().int().min(0),
3581
- mode: z21.enum(PRIVACY_MODES),
3582
- rules: z21.array(z21.record(z21.string(), z21.unknown())).max(PRIVACY_LIMITS.rules),
3583
- allowlist: z21.array(z21.string()).max(PRIVACY_LIMITS.allowlist)
3947
+ var storedPolicySchema = z23.object({
3948
+ schema: z23.literal(PRIVACY_SCHEMA),
3949
+ version: z23.number().int().min(0),
3950
+ mode: z23.enum(PRIVACY_MODES),
3951
+ rules: z23.array(z23.record(z23.string(), z23.unknown())).max(PRIVACY_LIMITS.rules),
3952
+ allowlist: z23.array(z23.string()).max(PRIVACY_LIMITS.allowlist)
3584
3953
  });
3585
- var nodePrivacyBlockSchema = z21.array(z21.object({ project_id: z21.number().int().positive(), policy: z21.unknown() })).max(1000);
3586
- var privacyRollupSchema = z21.object({
3587
- applied_version: z21.number().int().min(0).nullable(),
3588
- policy_missing_24h: z21.number().int().nonnegative(),
3589
- budget_exceeded_24h: z21.number().int().nonnegative(),
3590
- sdk_versions: z21.array(z21.object({ version: z21.number().int().min(0), last_seen_at: z21.string().datetime() })).max(5)
3954
+ var nodePrivacyBlockSchema = z23.array(z23.object({ project_id: z23.number().int().positive(), policy: z23.unknown() })).max(1000);
3955
+ var privacyRollupSchema = z23.object({
3956
+ applied_version: z23.number().int().min(0).nullable(),
3957
+ policy_missing_24h: z23.number().int().nonnegative(),
3958
+ budget_exceeded_24h: z23.number().int().nonnegative(),
3959
+ sdk_versions: z23.array(z23.object({ version: z23.number().int().min(0), last_seen_at: z23.string().datetime() })).max(5)
3591
3960
  });
3592
3961
 
3593
3962
  // ../src/shared/contracts/api-ops/privacy.ts
3594
3963
  var PRIVACY_INPUTS = {
3595
- get: z22.object({ workspaceId: uuid, projectId }),
3596
- set: z22.object({
3964
+ get: z24.object({ workspaceId: uuid, projectId }),
3965
+ set: z24.object({
3597
3966
  workspaceId: uuid,
3598
3967
  projectId,
3599
- expectedVersion: z22.number().int().min(0),
3968
+ expectedVersion: z24.number().int().min(0),
3600
3969
  policy: privacyPolicyInputSchema
3601
3970
  })
3602
3971
  };
@@ -3636,10 +4005,10 @@ var PRIVACY_OPERATIONS = [
3636
4005
  ];
3637
4006
 
3638
4007
  // ../src/shared/contracts/api-ops/projects.ts
3639
- import { z as z26 } from "zod";
4008
+ import { z as z28 } from "zod";
3640
4009
 
3641
4010
  // ../src/shared/contracts/ingest-keys.ts
3642
- import { z as z23 } from "zod";
4011
+ import { z as z25 } from "zod";
3643
4012
  var INGEST_KEY_SCOPES = ["traces", "logs", "metrics", "errors", "monitors"];
3644
4013
  var INGEST_KEY_STATES = ["active", "revoked"];
3645
4014
  var INGEST_KEY_LIMITS = {
@@ -3649,92 +4018,92 @@ var INGEST_KEY_LIMITS = {
3649
4018
  edgeCacheSeconds: 60
3650
4019
  };
3651
4020
  var CHECKIN_AUTH_MODES = ["public_or_key", "key_only"];
3652
- var ingestKeyConfigSchema = z23.object({
3653
- v: z23.literal(1),
3654
- key_id: z23.guid(),
3655
- project_public_id: z23.number().int().positive(),
3656
- project_id: z23.number().int().positive(),
3657
- workspace_id: z23.guid(),
4021
+ var ingestKeyConfigSchema = z25.object({
4022
+ v: z25.literal(1),
4023
+ key_id: z25.guid(),
4024
+ project_public_id: z25.number().int().positive(),
4025
+ project_id: z25.number().int().positive(),
4026
+ workspace_id: z25.guid(),
3658
4027
  node_id: nodeIdSchema,
3659
- scopes: z23.array(z23.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
3660
- environments: z23.array(z23.string().max(INGEST_KEY_LIMITS.environmentMaxChars)).max(INGEST_KEY_LIMITS.environmentsMax),
3661
- expires_at: z23.string().datetime({ offset: true }).nullable(),
3662
- state: z23.enum(INGEST_KEY_STATES),
3663
- workspace_status: z23.enum(["active", "suspended", "deleting"]),
3664
- ingest_kill: z23.boolean(),
3665
- telemetry_kill: z23.boolean(),
3666
- telemetry_rate_bytes_per_sec: z23.number().int().positive(),
3667
- telemetry_burst_bytes: z23.number().int().positive(),
3668
- traces_monthly_bytes: z23.number().int().positive(),
3669
- logs_monthly_bytes: z23.number().int().positive(),
3670
- metrics_monthly_bytes: z23.number().int().positive().optional(),
3671
- telemetry_buffer_minutes: z23.number().int().min(1).max(1440),
3672
- revision: z23.number().int().nonnegative()
4028
+ scopes: z25.array(z25.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
4029
+ environments: z25.array(z25.string().max(INGEST_KEY_LIMITS.environmentMaxChars)).max(INGEST_KEY_LIMITS.environmentsMax),
4030
+ expires_at: z25.string().datetime({ offset: true }).nullable(),
4031
+ state: z25.enum(INGEST_KEY_STATES),
4032
+ workspace_status: z25.enum(["active", "suspended", "deleting"]),
4033
+ ingest_kill: z25.boolean(),
4034
+ telemetry_kill: z25.boolean(),
4035
+ telemetry_rate_bytes_per_sec: z25.number().int().positive(),
4036
+ telemetry_burst_bytes: z25.number().int().positive(),
4037
+ traces_monthly_bytes: z25.number().int().positive(),
4038
+ logs_monthly_bytes: z25.number().int().positive(),
4039
+ metrics_monthly_bytes: z25.number().int().positive().optional(),
4040
+ telemetry_buffer_minutes: z25.number().int().min(1).max(1440),
4041
+ revision: z25.number().int().nonnegative()
3673
4042
  });
3674
- var createIngestKeyInputSchema = z23.object({
3675
- projectId: z23.number().int().positive(),
3676
- name: z23.string().trim().min(1).max(INGEST_KEY_LIMITS.nameMaxChars).refine((s) => !/[\u0000-\u001f\u007f]/.test(s)),
3677
- scopes: z23.array(z23.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
3678
- environments: z23.array(z23.string().trim().min(1).max(INGEST_KEY_LIMITS.environmentMaxChars).regex(/^[^\s/\u0000-\u001f]+$/)).max(INGEST_KEY_LIMITS.environmentsMax),
3679
- expiresAt: z23.string().datetime({ offset: true }).nullable()
4043
+ var createIngestKeyInputSchema = z25.object({
4044
+ projectId: z25.number().int().positive(),
4045
+ name: z25.string().trim().min(1).max(INGEST_KEY_LIMITS.nameMaxChars).refine((s) => !/[\u0000-\u001f\u007f]/.test(s)),
4046
+ scopes: z25.array(z25.enum(INGEST_KEY_SCOPES)).min(1).max(INGEST_KEY_SCOPES.length),
4047
+ environments: z25.array(z25.string().trim().min(1).max(INGEST_KEY_LIMITS.environmentMaxChars).regex(/^[^\s/\u0000-\u001f]+$/)).max(INGEST_KEY_LIMITS.environmentsMax),
4048
+ expiresAt: z25.string().datetime({ offset: true }).nullable()
3680
4049
  });
3681
- var ingestKeyRowSchema = z23.object({
3682
- id: z23.guid(),
3683
- project_id: z23.number().int().positive(),
3684
- name: z23.string(),
3685
- prefix: z23.string(),
3686
- scopes: z23.array(z23.enum(INGEST_KEY_SCOPES)),
3687
- environments: z23.array(z23.string()),
3688
- expires_at: z23.string().nullable(),
3689
- state: z23.enum(INGEST_KEY_STATES),
3690
- created_by: z23.guid().nullable(),
3691
- created_at: z23.string(),
3692
- revoked_at: z23.string().nullable(),
3693
- last_used_at: z23.string().nullable()
4050
+ var ingestKeyRowSchema = z25.object({
4051
+ id: z25.guid(),
4052
+ project_id: z25.number().int().positive(),
4053
+ name: z25.string(),
4054
+ prefix: z25.string(),
4055
+ scopes: z25.array(z25.enum(INGEST_KEY_SCOPES)),
4056
+ environments: z25.array(z25.string()),
4057
+ expires_at: z25.string().nullable(),
4058
+ state: z25.enum(INGEST_KEY_STATES),
4059
+ created_by: z25.guid().nullable(),
4060
+ created_at: z25.string(),
4061
+ revoked_at: z25.string().nullable(),
4062
+ last_used_at: z25.string().nullable()
3694
4063
  });
3695
4064
 
3696
4065
  // ../src/shared/contracts/node-config.ts
3697
- import { z as z25 } from "zod";
4066
+ import { z as z27 } from "zod";
3698
4067
 
3699
4068
  // ../src/shared/contracts/backup.ts
3700
- import { z as z24 } from "zod";
4069
+ import { z as z26 } from "zod";
3701
4070
  var BACKUP_KINDS = ["daily", "weekly", "manual", "pre_upgrade"];
3702
- var ageRecipient = z24.string().regex(/^age1[02-9ac-hj-np-z]{58}$/);
3703
- var backupIdSchema = z24.string().regex(/^[a-z0-9-]{8,64}$/);
3704
- var nodeBackupConfigSchema = z24.object({
3705
- enabled: z24.boolean(),
3706
- hour_utc: z24.number().int().min(0).max(23),
3707
- weekly_day: z24.number().int().min(1).max(7),
4071
+ var ageRecipient = z26.string().regex(/^age1[02-9ac-hj-np-z]{58}$/);
4072
+ var backupIdSchema = z26.string().regex(/^[a-z0-9-]{8,64}$/);
4073
+ var nodeBackupConfigSchema = z26.object({
4074
+ enabled: z26.boolean(),
4075
+ hour_utc: z26.number().int().min(0).max(23),
4076
+ weekly_day: z26.number().int().min(1).max(7),
3708
4077
  workspace_recipient: ageRecipient
3709
4078
  });
3710
- var backupCredentialsRequestSchema = z24.object({
3711
- mode: z24.enum(["upload", "download"]),
4079
+ var backupCredentialsRequestSchema = z26.object({
4080
+ mode: z26.enum(["upload", "download"]),
3712
4081
  backup_id: backupIdSchema,
3713
- source_node_id: z24.guid().optional()
4082
+ source_node_id: z26.guid().optional()
3714
4083
  });
3715
- var backupCredentialsSchema = z24.object({
3716
- endpoint: z24.string().url(),
3717
- bucket: z24.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/),
3718
- prefix: z24.string().regex(/^backups\/[0-9a-f-]{36}\/$/),
3719
- access_key_id: z24.string().min(8).max(200),
3720
- secret_access_key: z24.string().min(8).max(200),
3721
- session_token: z24.string().min(8).max(4000),
3722
- expires_at: z24.string().datetime()
4084
+ var backupCredentialsSchema = z26.object({
4085
+ endpoint: z26.string().url(),
4086
+ bucket: z26.string().regex(/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$/),
4087
+ prefix: z26.string().regex(/^backups\/[0-9a-f-]{36}\/$/),
4088
+ access_key_id: z26.string().min(8).max(200),
4089
+ secret_access_key: z26.string().min(8).max(200),
4090
+ session_token: z26.string().min(8).max(4000),
4091
+ expires_at: z26.string().datetime()
3723
4092
  });
3724
- var rowCountsSchema = z24.record(z24.string().regex(/^[a-z_][a-z0-9_]{0,63}$/), z24.number().int().nonnegative());
3725
- var backupManifestSchema = z24.object({
3726
- v: z24.literal(1),
4093
+ var rowCountsSchema = z26.record(z26.string().regex(/^[a-z_][a-z0-9_]{0,63}$/), z26.number().int().nonnegative());
4094
+ var backupManifestSchema = z26.object({
4095
+ v: z26.literal(1),
3727
4096
  backup_id: backupIdSchema,
3728
- node_id: z24.guid(),
3729
- kind: z24.enum(BACKUP_KINDS),
3730
- created_at: z24.string().datetime(),
3731
- object_key: z24.string(),
3732
- size_bytes: z24.number().int().nonnegative(),
3733
- sha256: z24.string().regex(/^[0-9a-f]{64}$/),
3734
- clickhouse_version: z24.string().max(40),
3735
- schema_version: z24.number().int().nonnegative(),
4097
+ node_id: z26.guid(),
4098
+ kind: z26.enum(BACKUP_KINDS),
4099
+ created_at: z26.string().datetime(),
4100
+ object_key: z26.string(),
4101
+ size_bytes: z26.number().int().nonnegative(),
4102
+ sha256: z26.string().regex(/^[0-9a-f]{64}$/),
4103
+ clickhouse_version: z26.string().max(40),
4104
+ schema_version: z26.number().int().nonnegative(),
3736
4105
  row_counts: rowCountsSchema,
3737
- recipients: z24.array(z24.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
4106
+ recipients: z26.array(z26.string().regex(/^[0-9a-f]{8}$/)).min(1).max(4)
3738
4107
  });
3739
4108
  var BACKUP_ERROR_CODES = [
3740
4109
  "CLICKHOUSE_BACKUP_FAILED",
@@ -3748,48 +4117,48 @@ var BACKUP_ERROR_CODES = [
3748
4117
  "RESTORE_FAILED",
3749
4118
  "ROW_COUNT_MISMATCH"
3750
4119
  ];
3751
- var backupReportSchema = z24.object({
4120
+ var backupReportSchema = z26.object({
3752
4121
  backup_id: backupIdSchema,
3753
- kind: z24.enum(BACKUP_KINDS),
3754
- status: z24.enum(["succeeded", "failed"]),
3755
- started_at: z24.string().datetime(),
3756
- finished_at: z24.string().datetime(),
4122
+ kind: z26.enum(BACKUP_KINDS),
4123
+ status: z26.enum(["succeeded", "failed"]),
4124
+ started_at: z26.string().datetime(),
4125
+ finished_at: z26.string().datetime(),
3757
4126
  manifest: backupManifestSchema.nullable(),
3758
- error_code: z24.enum(BACKUP_ERROR_CODES).nullable()
4127
+ error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
3759
4128
  });
3760
- var drillReportSchema = z24.object({
4129
+ var drillReportSchema = z26.object({
3761
4130
  backup_id: backupIdSchema,
3762
- kind: z24.enum(["weekly_local", "monthly_new_machine"]),
3763
- status: z24.enum(["passed", "failed"]),
3764
- finished_at: z24.string().datetime(),
3765
- detail: z24.string().max(300),
3766
- error_code: z24.enum(BACKUP_ERROR_CODES).nullable()
4131
+ kind: z26.enum(["weekly_local", "monthly_new_machine"]),
4132
+ status: z26.enum(["passed", "failed"]),
4133
+ finished_at: z26.string().datetime(),
4134
+ detail: z26.string().max(300),
4135
+ error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
3767
4136
  });
3768
- var nodeIdentityEscrowSchema = z24.object({
3769
- v: z24.literal(1),
3770
- node_id: z24.guid(),
3771
- seal: z24.object({
3772
- publicKey: z24.string().regex(/^[A-Za-z0-9_-]{43}$/),
3773
- privateKey: z24.string().regex(/^[A-Za-z0-9_-]{43}$/)
3774
- }),
3775
- created_at: z24.string().datetime()
4137
+ var nodeIdentityEscrowSchema = z26.object({
4138
+ v: z26.literal(1),
4139
+ node_id: z26.guid(),
4140
+ seal: z26.object({
4141
+ publicKey: z26.string().regex(/^[A-Za-z0-9_-]{43}$/),
4142
+ privateKey: z26.string().regex(/^[A-Za-z0-9_-]{43}$/)
4143
+ }),
4144
+ created_at: z26.string().datetime()
3776
4145
  });
3777
- var restoreArgsSchema = z24.object({
3778
- job_id: z24.guid(),
3779
- workspace_id: z24.guid(),
3780
- source_node_id: z24.guid(),
4146
+ var restoreArgsSchema = z26.object({
4147
+ job_id: z26.guid(),
4148
+ workspace_id: z26.guid(),
4149
+ source_node_id: z26.guid(),
3781
4150
  manifest: backupManifestSchema,
3782
- sealed_identity: z24.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
3783
- mode: z24.enum(["rebuild", "drill"])
4151
+ sealed_identity: z26.string().regex(/^[A-Za-z0-9_-]{40,2000}$/),
4152
+ mode: z26.enum(["rebuild", "drill"])
3784
4153
  });
3785
- var restoreReportSchema = z24.object({
3786
- job_id: z24.guid(),
4154
+ var restoreReportSchema = z26.object({
4155
+ job_id: z26.guid(),
3787
4156
  backup_id: backupIdSchema,
3788
- mode: z24.enum(["rebuild", "drill"]),
3789
- status: z24.enum(["succeeded", "failed"]),
3790
- finished_at: z24.string().datetime(),
3791
- detail: z24.string().max(300),
3792
- error_code: z24.enum(BACKUP_ERROR_CODES).nullable()
4157
+ mode: z26.enum(["rebuild", "drill"]),
4158
+ status: z26.enum(["succeeded", "failed"]),
4159
+ finished_at: z26.string().datetime(),
4160
+ detail: z26.string().max(300),
4161
+ error_code: z26.enum(BACKUP_ERROR_CODES).nullable()
3793
4162
  });
3794
4163
 
3795
4164
  // ../src/shared/contracts/node-config.ts
@@ -3803,83 +4172,84 @@ var SCRUB_GROUPS = [
3803
4172
  "headers"
3804
4173
  ];
3805
4174
  var MAX_NODE_MONITORS = 5000;
3806
- var kid = z25.string().regex(/^[A-Za-z0-9_-]{1,40}$/);
3807
- var publicKey = z25.string().regex(/^[A-Za-z0-9_-]{43}$/);
3808
- var nodeConfigSchema = z25.object({
3809
- v: z25.literal(1),
3810
- config_version: z25.number().int().positive(),
3811
- node_id: z25.guid(),
3812
- workspace_id: z25.guid(),
3813
- workspace_status: z25.enum(["active", "suspended"]),
3814
- issued_at: z25.string().datetime(),
3815
- retention_days: z25.number().int().min(1).max(3650),
3816
- channel: z25.enum(["stable", "canary"]).optional(),
3817
- projects: z25.array(z25.object({
3818
- project_id: z25.number().int().positive(),
3819
- slug: z25.string().max(64),
3820
- short_prefix: z25.string().regex(/^[A-Z0-9]{1,12}$/),
3821
- user_id_salt: z25.string().regex(/^[A-Za-z0-9_-]{22,64}$/),
3822
- scrub_disabled: z25.array(z25.enum(SCRUB_GROUPS)).max(SCRUB_GROUPS.length),
3823
- upload_tokens: z25.array(z25.object({
3824
- hash: z25.string().regex(/^[a-f0-9]{64}$/),
3825
- expires_at: z25.string().datetime()
4175
+ var kid = z27.string().regex(/^[A-Za-z0-9_-]{1,40}$/);
4176
+ var publicKey = z27.string().regex(/^[A-Za-z0-9_-]{43}$/);
4177
+ var nodeConfigSchema = z27.object({
4178
+ v: z27.literal(1),
4179
+ config_version: z27.number().int().positive(),
4180
+ node_id: z27.guid(),
4181
+ workspace_id: z27.guid(),
4182
+ workspace_status: z27.enum(["active", "suspended"]),
4183
+ issued_at: z27.string().datetime(),
4184
+ retention_days: z27.number().int().min(1).max(3650),
4185
+ channel: z27.enum(["stable", "canary"]).optional(),
4186
+ projects: z27.array(z27.object({
4187
+ project_id: z27.number().int().positive(),
4188
+ slug: z27.string().max(64),
4189
+ short_prefix: z27.string().regex(/^[A-Z0-9]{1,12}$/),
4190
+ user_id_salt: z27.string().regex(/^[A-Za-z0-9_-]{22,64}$/),
4191
+ scrub_disabled: z27.array(z27.enum(SCRUB_GROUPS)).max(SCRUB_GROUPS.length),
4192
+ upload_tokens: z27.array(z27.object({
4193
+ hash: z27.string().regex(/^[a-f0-9]{64}$/),
4194
+ expires_at: z27.string().datetime(),
4195
+ scopes: z27.array(z27.enum(UPLOAD_SCOPES)).min(1).max(UPLOAD_SCOPES.length).optional()
3826
4196
  })).max(10).optional()
3827
4197
  })).max(1000),
3828
- ticket_keys: z25.array(z25.object({ kid, public_key: publicKey, not_after: z25.string().datetime() })).min(1).max(5),
3829
- control_ops_keys: z25.array(z25.object({ kid, public_key: publicKey })).min(1).max(5),
3830
- kill_switches: z25.object({ ingest: z25.boolean(), alerts: z25.boolean() }),
4198
+ ticket_keys: z27.array(z27.object({ kid, public_key: publicKey, not_after: z27.string().datetime() })).min(1).max(5),
4199
+ control_ops_keys: z27.array(z27.object({ kid, public_key: publicKey })).min(1).max(5),
4200
+ kill_switches: z27.object({ ingest: z27.boolean(), alerts: z27.boolean() }),
3831
4201
  backup: nodeBackupConfigSchema.optional(),
3832
- purged_projects: z25.array(z25.number().int().positive()).max(1000).optional(),
3833
- monitors: z25.array(monitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
3834
- purged_monitors: z25.array(z25.guid()).max(5000).optional(),
3835
- telemetry: z25.object({
3836
- traces_retention_days: z25.number().int().min(1).max(90),
3837
- logs_retention_days: z25.number().int().min(1).max(90),
3838
- traces_disk_share: z25.number().min(0.2).max(0.8)
4202
+ purged_projects: z27.array(z27.number().int().positive()).max(1000).optional(),
4203
+ monitors: z27.array(monitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4204
+ purged_monitors: z27.array(z27.guid()).max(5000).optional(),
4205
+ telemetry: z27.object({
4206
+ traces_retention_days: z27.number().int().min(1).max(90),
4207
+ logs_retention_days: z27.number().int().min(1).max(90),
4208
+ traces_disk_share: z27.number().min(0.2).max(0.8)
3839
4209
  }).optional(),
3840
4210
  metrics: metricsConfigSchema.optional(),
3841
- slos: z25.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
3842
- signal_monitors: z25.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
4211
+ slos: z27.array(nodeSloSchema).max(SLO_LIMITS.maxNodeSlos).optional(),
4212
+ signal_monitors: z27.array(signalMonitorDefinitionSchema).max(MAX_NODE_MONITORS).optional(),
3843
4213
  signal_limits: signalLimitsConfigSchema.optional(),
3844
4214
  privacy: nodePrivacyBlockSchema.optional()
3845
4215
  });
3846
- var signedNodeConfigSchema = z25.object({ config: nodeConfigSchema, kid, sig: z25.string() });
4216
+ var signedNodeConfigSchema = z27.object({ config: nodeConfigSchema, kid, sig: z27.string() });
3847
4217
 
3848
4218
  // ../src/shared/contracts/api-ops/projects.ts
3849
- var slug = z26.string().regex(/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/);
3850
- var name3 = z26.string().trim().min(1).max(60);
3851
- var label2 = z26.string().trim().min(1).max(40);
3852
- var platform = z26.enum(PLATFORMS);
3853
- var origin = z26.string().trim().toLowerCase().regex(/^https?:\/\/[a-z0-9.-]+(:[0-9]{1,5})?$/).max(200);
3854
- var keyId = z26.number().int().positive();
4219
+ var slug = z28.string().regex(/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/);
4220
+ var name3 = z28.string().trim().min(1).max(60);
4221
+ var label2 = z28.string().trim().min(1).max(40);
4222
+ var platform = z28.enum(PLATFORMS);
4223
+ var origin = z28.string().trim().toLowerCase().regex(/^https?:\/\/[a-z0-9.-]+(:[0-9]{1,5})?$/).max(200);
4224
+ var keyId = z28.number().int().positive();
3855
4225
  var PROJECT_INPUTS = {
3856
- create: z26.object({ workspaceId: uuid, name: name3, slug, platform }),
3857
- update: z26.object({ projectId, name: name3, platform, isPinned: z26.boolean() }),
3858
- updateIntake: z26.object({
4226
+ create: z28.object({ workspaceId: uuid, name: name3, slug, platform }),
4227
+ update: z28.object({ projectId, name: name3, platform, isPinned: z28.boolean() }),
4228
+ updateIntake: z28.object({
3859
4229
  projectId,
3860
- rateLimit: z26.number().int().positive().nullable(),
3861
- burst: z26.number().int().positive().nullable(),
3862
- allowedOrigins: z26.array(origin).max(50)
4230
+ rateLimit: z28.number().int().positive().nullable(),
4231
+ burst: z28.number().int().positive().nullable(),
4232
+ allowedOrigins: z28.array(origin).max(50)
3863
4233
  }),
3864
- updateObservability: z26.object({
4234
+ updateObservability: z28.object({
3865
4235
  projectId,
3866
- primaryEnvironment: z26.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
3867
- allowCodeMonitors: z26.boolean()
4236
+ primaryEnvironment: z28.string().trim().min(1).max(64).refine((v) => v !== "*" && ENVIRONMENT_RE.test(v)),
4237
+ allowCodeMonitors: z28.boolean()
3868
4238
  }),
3869
- setScrub: z26.object({ projectId, group: z26.enum(SCRUB_GROUPS), enabled: z26.boolean() }),
3870
- setCheckinAuth: z26.object({ projectId, mode: z26.enum(CHECKIN_AUTH_MODES) }),
3871
- setEnvironmentHidden: z26.object({
4239
+ setScrub: z28.object({ projectId, group: z28.enum(SCRUB_GROUPS), enabled: z28.boolean() }),
4240
+ setCheckinAuth: z28.object({ projectId, mode: z28.enum(CHECKIN_AUTH_MODES) }),
4241
+ setEnvironmentHidden: z28.object({
3872
4242
  projectId,
3873
- name: z26.string().min(1).max(64),
3874
- hidden: z26.boolean()
3875
- }),
3876
- scheduleDeletion: z26.object({ projectId, confirmSlug: slug }),
3877
- projectOnly: z26.object({ projectId }),
3878
- labelled: z26.object({ projectId, label: label2 }),
3879
- keyOnly: z26.object({ keyId }),
3880
- tokenOnly: z26.object({ tokenId: keyId }),
4243
+ name: z28.string().min(1).max(64),
4244
+ hidden: z28.boolean()
4245
+ }),
4246
+ scheduleDeletion: z28.object({ projectId, confirmSlug: slug }),
4247
+ projectOnly: z28.object({ projectId }),
4248
+ labelled: z28.object({ projectId, label: label2 }),
4249
+ keyOnly: z28.object({ keyId }),
4250
+ tokenOnly: z28.object({ tokenId: keyId }),
3881
4251
  createIngestKey: createIngestKeyInputSchema,
3882
- ingestKeyOnly: z26.object({ keyId: uuid })
4252
+ ingestKeyOnly: z28.object({ keyId: uuid })
3883
4253
  };
3884
4254
  var P2 = PROJECT_INPUTS;
3885
4255
  var PROJECT_OPERATIONS = [
@@ -4134,24 +4504,24 @@ var PROJECT_OPERATIONS = [
4134
4504
  ];
4135
4505
 
4136
4506
  // ../src/shared/contracts/api-ops/reads.ts
4137
- import { z as z27 } from "zod";
4138
- var list = z27.object({ workspaceId: uuid, limit: pageLimit, cursor });
4507
+ import { z as z29 } from "zod";
4508
+ var list = z29.object({ workspaceId: uuid, limit: pageLimit, cursor });
4139
4509
  var READ_INPUTS = {
4140
- workspace: z27.object({ workspaceId: uuid }),
4510
+ workspace: z29.object({ workspaceId: uuid }),
4141
4511
  list,
4142
- projectsGet: z27.object({ workspaceId: uuid, projectId }),
4512
+ projectsGet: z29.object({ workspaceId: uuid, projectId }),
4143
4513
  monitorsList: list.extend({ projectId: projectId.optional() }),
4144
- monitorsGet: z27.object({ workspaceId: uuid, monitorId: uuid }),
4145
- uptimeGet: z27.object({ workspaceId: uuid, checkId: uuid }),
4146
- slosGet: z27.object({ workspaceId: uuid, sloId: uuid }),
4514
+ monitorsGet: z29.object({ workspaceId: uuid, monitorId: uuid }),
4515
+ uptimeGet: z29.object({ workspaceId: uuid, checkId: uuid }),
4516
+ slosGet: z29.object({ workspaceId: uuid, sloId: uuid }),
4147
4517
  alertsList: list.extend({
4148
- state: z27.enum(["open", "resolved", "all"]).default("all"),
4518
+ state: z29.enum(["open", "resolved", "all"]).default("all"),
4149
4519
  monitorId: uuid.optional()
4150
4520
  }),
4151
- approvalsGet: z27.object({ workspaceId: uuid, approvalId: uuid }),
4521
+ approvalsGet: z29.object({ workspaceId: uuid, approvalId: uuid }),
4152
4522
  monitorsListTyped: list.extend({
4153
4523
  projectId: projectId.optional(),
4154
- type: z27.enum(MONITOR_TYPES).optional()
4524
+ type: z29.enum(MONITOR_TYPES).optional()
4155
4525
  })
4156
4526
  };
4157
4527
  var R = READ_INPUTS;
@@ -4435,14 +4805,14 @@ function approvalRequestSchema(operationId, input) {
4435
4805
  }
4436
4806
 
4437
4807
  // ../src/shared/contracts/api-ops/wire.ts
4438
- import { z as z28 } from "zod";
4808
+ import { z as z30 } from "zod";
4439
4809
  var toSnake = (s) => s.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);
4440
4810
  var toCamel = (s) => s.replace(/_([a-z0-9])/g, (_, c) => c.toUpperCase());
4441
4811
  var schemaCache = new WeakMap;
4442
4812
  function inputJsonSchema(op) {
4443
4813
  let js = schemaCache.get(op.input);
4444
4814
  if (!js) {
4445
- js = z28.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
4815
+ js = z30.toJSONSchema(op.input, { io: "input", unrepresentable: "any" });
4446
4816
  schemaCache.set(op.input, js);
4447
4817
  }
4448
4818
  return js;
@@ -4656,7 +5026,7 @@ function wireInput(operationId, opts = {}) {
4656
5026
  for (const [k, v] of Object.entries(op.input.shape))
4657
5027
  if (!omit.has(k))
4658
5028
  shape[toSnake(k)] = v;
4659
- return z29.object(shape);
5029
+ return z31.object(shape);
4660
5030
  }
4661
5031
  var BUDGETS = [
4662
5032
  { stringBytes: MCP_LIMITS.untrustedStringMaxBytes, listMax: MCP_LIMITS.listMax },
@@ -4716,7 +5086,10 @@ function untrustedTree(value, reserveBytes = 2048) {
4716
5086
  function wrapResult(parts, extra = {}) {
4717
5087
  const t = untrustedTree(parts.data);
4718
5088
  const structuredContent = {
4719
- untrusted: { data: t.data, provenance: { source: parts.source, operations: [...parts.operations] } }
5089
+ untrusted: {
5090
+ data: t.data,
5091
+ provenance: { source: parts.source, operations: [...parts.operations] }
5092
+ }
4720
5093
  };
4721
5094
  if (extra.next_cursor !== undefined) {
4722
5095
  const c = extra.next_cursor === null ? null : cleanUntrustedText(extra.next_cursor, 600).text;
@@ -4746,40 +5119,52 @@ function errorResult(o) {
4746
5119
  }
4747
5120
  };
4748
5121
  }
4749
- var TOOL_OUTPUT_SCHEMA = z29.object({
4750
- untrusted: z29.object({
4751
- data: z29.unknown(),
4752
- provenance: z29.object({
4753
- source: z29.enum(["node", "control_plane", "docs"]),
4754
- operations: z29.array(z29.string())
5122
+ var TOOL_OUTPUT_SCHEMA = z31.object({
5123
+ untrusted: z31.object({
5124
+ data: z31.unknown(),
5125
+ provenance: z31.object({
5126
+ source: z31.enum(["node", "control_plane", "docs"]),
5127
+ operations: z31.array(z31.string())
4755
5128
  })
4756
5129
  }).optional(),
4757
- doc: z29.object({ slug: z29.string(), locale: z29.enum(["en", "vi"]), url: z29.string(), markdown: z29.string(), truncated: z29.boolean() }).optional(),
4758
- results: z29.array(z29.object({ slug: z29.string(), title: z29.string(), description: z29.string(), section: z29.string(), url: z29.string() })).optional(),
4759
- next_cursor: z29.string().nullable().optional(),
4760
- complete: z29.boolean().optional(),
4761
- omitted: z29.array(z29.object({ part: z29.string(), reason: z29.string(), scope: z29.string().optional() })).optional(),
4762
- truncated: z29.literal(true).optional(),
4763
- suspicious_unicode: z29.literal(true).optional(),
4764
- error: z29.object({
4765
- code: z29.string(),
4766
- status: z29.number(),
4767
- detail: z29.string().optional(),
4768
- scope: z29.string().optional(),
4769
- retry_after: z29.number().optional()
5130
+ doc: z31.object({
5131
+ slug: z31.string(),
5132
+ locale: z31.enum(["en", "vi"]),
5133
+ url: z31.string(),
5134
+ markdown: z31.string(),
5135
+ truncated: z31.boolean()
5136
+ }).optional(),
5137
+ results: z31.array(z31.object({
5138
+ slug: z31.string(),
5139
+ title: z31.string(),
5140
+ description: z31.string(),
5141
+ section: z31.string(),
5142
+ url: z31.string()
5143
+ })).optional(),
5144
+ next_cursor: z31.string().nullable().optional(),
5145
+ complete: z31.boolean().optional(),
5146
+ omitted: z31.array(z31.object({ part: z31.string(), reason: z31.string(), scope: z31.string().optional() })).optional(),
5147
+ truncated: z31.literal(true).optional(),
5148
+ suspicious_unicode: z31.literal(true).optional(),
5149
+ error: z31.object({
5150
+ code: z31.string(),
5151
+ status: z31.number(),
5152
+ detail: z31.string().optional(),
5153
+ scope: z31.string().optional(),
5154
+ retry_after: z31.number().optional()
4770
5155
  }).optional(),
4771
- operations: z29.array(z29.record(z29.string(), z29.unknown())).optional(),
4772
- operation: z29.record(z29.string(), z29.unknown()).optional(),
4773
- plan: z29.record(z29.string(), z29.unknown()).optional(),
4774
- status: z29.enum(["done", "approval_required", "approval_pending", ...APPROVAL_STATES]).optional(),
4775
- approval: z29.object({
4776
- approval_id: z29.string(),
4777
- approval_url: z29.string(),
4778
- expires_at: z29.string(),
4779
- state: z29.enum(APPROVAL_STATES),
4780
- result_code: z29.string().nullable().optional(),
4781
- result: z29.record(z29.string(), z29.unknown()).optional(),
4782
- next: z29.string().optional()
5156
+ operations: z31.array(z31.record(z31.string(), z31.unknown())).optional(),
5157
+ operation: z31.record(z31.string(), z31.unknown()).optional(),
5158
+ plan: z31.record(z31.string(), z31.unknown()).optional(),
5159
+ status: z31.enum(["done", "approval_required", "approval_pending", ...APPROVAL_STATES]).optional(),
5160
+ approval: z31.object({
5161
+ approval_id: z31.string(),
5162
+ approval_url: z31.string(),
5163
+ expires_at: z31.string(),
5164
+ state: z31.enum(APPROVAL_STATES),
5165
+ result_code: z31.string().nullable().optional(),
5166
+ result: z31.record(z31.string(), z31.unknown()).optional(),
5167
+ next: z31.string().optional()
4783
5168
  }).optional()
4784
5169
  });
4785
5170
  var spec = (name) => {
@@ -4825,10 +5210,10 @@ var has = (rt, operationId) => {
4825
5210
  return !!op && rt.scopes.includes(op.scope);
4826
5211
  };
4827
5212
  var isoWindow = {
4828
- start: z29.string().max(40).describe("RFC 3339 start of the window, e.g. 2026-10-26T00:00:00Z. Required with end."),
4829
- end: z29.string().max(40).describe("RFC 3339 end of the window. The plan limits its length.")
5213
+ start: z31.string().max(40).describe("RFC 3339 start of the window, e.g. 2026-10-26T00:00:00Z. Required with end."),
5214
+ end: z31.string().max(40).describe("RFC 3339 end of the window. The plan limits its length.")
4830
5215
  };
4831
- var traceIdSchema = z29.string().regex(/^[0-9a-fA-F]{32}$/);
5216
+ var traceIdSchema = z31.string().regex(/^[0-9a-fA-F]{32}$/);
4832
5217
  var MONITOR_KINDS2 = {
4833
5218
  cron: { list: "monitors.list", get: "monitors.get", idField: "monitor_id" },
4834
5219
  uptime: { list: "uptime.list", get: "uptime.get", idField: "check_id" },
@@ -4892,8 +5277,8 @@ function describe(op, scopes) {
4892
5277
  destructive: isDestructiveOperation(op)
4893
5278
  };
4894
5279
  }
4895
- var params = z29.record(z29.string(), z29.unknown()).default({}).describe("Operation fields in wire names (snake_case), as describe_operation's args_schema shows.");
4896
- var operationIdArg = z29.string().min(3).max(80).describe("An operation id from search_operations, e.g. `monitors.update`.");
5280
+ var params = z31.record(z31.string(), z31.unknown()).default({}).describe("Operation fields in wire names (snake_case), as describe_operation's args_schema shows.");
5281
+ var operationIdArg = z31.string().min(3).max(80).describe("An operation id from search_operations, e.g. `monitors.update`.");
4897
5282
  function approvalBlock(t, next) {
4898
5283
  return {
4899
5284
  approval_id: t.approval_id,
@@ -4913,7 +5298,7 @@ var MCP_TOOL_DEFS = [
4913
5298
  title: "Workspace and node",
4914
5299
  description: "The workspace this token belongs to (name, plan, limits) and the state of its node, the server that stores errors, traces and logs. Start here to learn what the token can reach.",
4915
5300
  operations: ["workspace.get", "node.get"],
4916
- input: z29.object({}),
5301
+ input: z31.object({}),
4917
5302
  async run(_args, rt) {
4918
5303
  const [ws, node] = await Promise.all([rt.call("workspace.get", {}), rt.call("node.get", {})]);
4919
5304
  if (!ws.ok)
@@ -4921,7 +5306,11 @@ var MCP_TOOL_DEFS = [
4921
5306
  const omitted = [];
4922
5307
  if (!node.ok)
4923
5308
  omitted.push({ part: "node", reason: node.code });
4924
- return wrapResult({ data: { workspace: ws.body, node: node.ok ? node.body : null }, operations: ["workspace.get", "node.get"], source: "control_plane" }, { omitted });
5309
+ return wrapResult({
5310
+ data: { workspace: ws.body, node: node.ok ? node.body : null },
5311
+ operations: ["workspace.get", "node.get"],
5312
+ source: "control_plane"
5313
+ }, { omitted });
4925
5314
  }
4926
5315
  },
4927
5316
  single("list_projects", "projects.list", "List projects", "Projects this token can read, with their numeric ids (use them as `project` in other tools), platforms and environments."),
@@ -4929,11 +5318,11 @@ var MCP_TOOL_DEFS = [
4929
5318
  {
4930
5319
  ...spec("get_issue"),
4931
5320
  title: "Get an issue",
4932
- description: "One issue with its 24 h and 30 d counts and, when the token can read events, its latest event (stack trace, request, breadcrumbs — scrubbed on the node).",
4933
- operations: ["issues.get", "events.get"],
4934
- input: z29.object({
4935
- issue_id: z29.number().int().positive().describe("Issue id from search_issues."),
4936
- include_latest_event: z29.boolean().default(true)
5321
+ description: "One issue with its 24 h and 30 d counts and, when the token can read events, its latest event (stack trace, request, breadcrumbs — scrubbed on the node). A resolved issue also carries `fix_status` when the token can read releases: fixed, unverified, not_fixed (with the event that broke it) or unknown, per environment.",
5322
+ operations: ["issues.get", "events.get", "issues.fix_status"],
5323
+ input: z31.object({
5324
+ issue_id: z31.number().int().positive().describe("Issue id from search_issues."),
5325
+ include_latest_event: z31.boolean().default(true)
4937
5326
  }),
4938
5327
  async run(args, rt) {
4939
5328
  const omitted = [];
@@ -4951,7 +5340,20 @@ var MCP_TOOL_DEFS = [
4951
5340
  latest = ev.body;
4952
5341
  else if (ev)
4953
5342
  omitted.push({ part: "latest_event", reason: ev.code });
4954
- return wrapResult({ data: { issue: issue.body, latest_event: latest }, operations: ["issues.get", "events.get"], source: "node" }, { omitted });
5343
+ const ops = ["issues.get", "events.get"];
5344
+ const data = { issue: issue.body, latest_event: latest };
5345
+ const resolved = issue.body?.issue?.status === "resolved";
5346
+ if (resolved && !has(rt, "issues.fix_status"))
5347
+ omitted.push({ part: "fix_status", reason: "scope", scope: "releases:read" });
5348
+ else if (resolved) {
5349
+ const fx = await rt.call("issues.fix_status", { issue_id: args["issue_id"] });
5350
+ ops.push("issues.fix_status");
5351
+ if (fx.ok)
5352
+ data["fix_status"] = fx.body;
5353
+ else
5354
+ omitted.push({ part: "fix_status", reason: fx.code });
5355
+ }
5356
+ return wrapResult({ data, operations: ops, source: "node" }, { omitted });
4955
5357
  }
4956
5358
  },
4957
5359
  single("list_events", "events.list", "List events of an issue", "Events of one issue, newest first, with a cursor for older ones."),
@@ -4961,9 +5363,9 @@ var MCP_TOOL_DEFS = [
4961
5363
  title: "Get a trace",
4962
5364
  description: "Summary of one distributed trace (services, duration, errors) by its 32-hex trace id, and optionally its spans (errors only, or the first page).",
4963
5365
  operations: ["traces.get", "traces.spans"],
4964
- input: z29.object({
5366
+ input: z31.object({
4965
5367
  trace_id: traceIdSchema.describe("W3C trace id, 32 hex characters."),
4966
- spans: z29.enum(["none", "errors", "all"]).default("none")
5368
+ spans: z31.enum(["none", "errors", "all"]).default("none")
4967
5369
  }),
4968
5370
  async run(args, rt) {
4969
5371
  const sum = await rt.call("traces.get", { trace_id: args["trace_id"] });
@@ -4981,7 +5383,11 @@ var MCP_TOOL_DEFS = [
4981
5383
  else
4982
5384
  omitted.push({ part: "spans", reason: r.code });
4983
5385
  }
4984
- return wrapResult({ data: { trace: sum.body, ...spans !== undefined ? { spans } : {} }, operations: ["traces.get", "traces.spans"], source: "node" }, { omitted });
5386
+ return wrapResult({
5387
+ data: { trace: sum.body, ...spans !== undefined ? { spans } : {} },
5388
+ operations: ["traces.get", "traces.spans"],
5389
+ source: "node"
5390
+ }, { omitted });
4985
5391
  }
4986
5392
  },
4987
5393
  single("search_spans", "spans.list", "Search spans", "OpenTelemetry spans in a time window (start and end required): filter by project, environment, service, operation, status, kind, duration or attribute filters (`attrs`, JSON list of {k, op, v}). mode=traces returns one row per trace."),
@@ -4991,23 +5397,29 @@ var MCP_TOOL_DEFS = [
4991
5397
  title: "Query metrics",
4992
5398
  description: "OpenTelemetry metrics of one project. Without `name`: the metric catalog (name, type, unit, series count, last seen; `q` narrows by name) and the node's series caps. With `name` plus start and end: the metric aggregated per step — `aggregation` defaults to rate for counters, p95 for histograms and avg for gauges — optionally filtered by attributes (`attrs`, JSON list of {k, op, v}) and grouped by up to two attribute keys (`group_by`, comma-separated). Exemplar trace ids open with get_trace.",
4993
5399
  operations: ["metrics.names", "metrics.query"],
4994
- input: z29.object({
4995
- project: z29.number().int().positive().describe("Numeric project id from list_projects."),
4996
- name: z29.string().regex(METRIC_NAME_RE).optional().describe("Metric name from the catalog, e.g. http.server.request.duration."),
4997
- q: z29.string().max(255).optional().describe("Catalog only: part of a metric name."),
4998
- aggregation: z29.enum(METRIC_AGGREGATIONS).optional(),
5400
+ input: z31.object({
5401
+ project: z31.number().int().positive().describe("Numeric project id from list_projects."),
5402
+ name: z31.string().regex(METRIC_NAME_RE).optional().describe("Metric name from the catalog, e.g. http.server.request.duration."),
5403
+ q: z31.string().max(255).optional().describe("Catalog only: part of a metric name."),
5404
+ aggregation: z31.enum(METRIC_AGGREGATIONS).optional(),
4999
5405
  start: isoWindow.start.optional(),
5000
5406
  end: isoWindow.end.optional(),
5001
- step: z29.number().int().min(60).max(86400).multipleOf(60).optional().describe("Seconds per point (whole minutes); picked from the window when absent."),
5002
- attrs: z29.string().max(2000).optional(),
5003
- group_by: z29.string().max(600).optional(),
5004
- environment: z29.string().max(2000).optional().describe("Comma-separated environments.")
5407
+ step: z31.number().int().min(60).max(86400).multipleOf(60).optional().describe("Seconds per point (whole minutes); picked from the window when absent."),
5408
+ attrs: z31.string().max(2000).optional(),
5409
+ group_by: z31.string().max(600).optional(),
5410
+ environment: z31.string().max(2000).optional().describe("Comma-separated environments.")
5005
5411
  }),
5006
5412
  async run(args, rt) {
5007
- const scope = { project: args["project"], ...args["environment"] ? { environment: args["environment"] } : {} };
5413
+ const scope = {
5414
+ project: args["project"],
5415
+ ...args["environment"] ? { environment: args["environment"] } : {}
5416
+ };
5008
5417
  const name = args["name"];
5009
5418
  if (!name) {
5010
- const r = await rt.call("metrics.names", { ...scope, ...args["q"] ? { q: args["q"] } : {} });
5419
+ const r = await rt.call("metrics.names", {
5420
+ ...scope,
5421
+ ...args["q"] ? { q: args["q"] } : {}
5422
+ });
5011
5423
  if (!r.ok)
5012
5424
  return errorResult(r);
5013
5425
  return wrapResult({ data: r.body, operations: ["metrics.names"], source: "node" }, listExtra(r.body));
@@ -5022,7 +5434,12 @@ var MCP_TOOL_DEFS = [
5022
5434
  const rows = cat.body?.names ?? [];
5023
5435
  const kind = rows.find((n) => n.name === name)?.kind;
5024
5436
  if (!METRIC_KINDS.includes(kind))
5025
- return errorResult({ ok: false, status: 404, code: "NOT_FOUND", detail: "unknown_metric" });
5437
+ return errorResult({
5438
+ ok: false,
5439
+ status: 404,
5440
+ code: "NOT_FOUND",
5441
+ detail: "unknown_metric"
5442
+ });
5026
5443
  aggregation = defaultAggregation(kind);
5027
5444
  }
5028
5445
  const r = await rt.call("metrics.query", {
@@ -5040,23 +5457,65 @@ var MCP_TOOL_DEFS = [
5040
5457
  return wrapResult({ data: r.body, operations: ops, source: "node" }, listExtra(r.body));
5041
5458
  }
5042
5459
  },
5460
+ {
5461
+ ...spec("release_health"),
5462
+ title: "Release health",
5463
+ description: "What changed with a release (spec 13). With `version`: that release in one environment against the previous one (or `compare`) — three lists for its first 24 hours: new issues, regressed issues and increased issues (≥ 2× events per hour and ≥ 10 events), up to 50 each with hourly sparklines, plus its deploy markers. Without `version`: the project's releases, newest deploy first, with those three counts. `environment` defaults to production (else the busiest). Whether a resolved issue is really fixed: get_issue returns its fix status.",
5464
+ operations: ["releases.list", "releases.health"],
5465
+ input: z31.object({
5466
+ project: z31.number().int().positive().describe("Numeric project id from list_projects."),
5467
+ version: releaseNameSchema.optional().describe("Release name exactly as the SDK sends it, e.g. web@1.4.2."),
5468
+ environment: environmentNameSchema.optional().describe("One environment, e.g. production."),
5469
+ compare: releaseNameSchema.optional().describe("With version: compare against this release instead of the previous one.")
5470
+ }),
5471
+ async run(args, rt) {
5472
+ const scope = {
5473
+ project: args["project"],
5474
+ ...args["environment"] ? { environment: args["environment"] } : {}
5475
+ };
5476
+ const version = args["version"];
5477
+ if (!version) {
5478
+ const r = await rt.call("releases.list", scope);
5479
+ if (!r.ok)
5480
+ return errorResult(r);
5481
+ return wrapResult({ data: r.body, operations: ["releases.list"], source: "node" });
5482
+ }
5483
+ const r = await rt.call("releases.health", {
5484
+ ...scope,
5485
+ version,
5486
+ ...args["compare"] ? { compare: args["compare"] } : {}
5487
+ });
5488
+ if (!r.ok)
5489
+ return errorResult(r);
5490
+ return wrapResult({ data: r.body, operations: ["releases.health"], source: "node" });
5491
+ }
5492
+ },
5043
5493
  {
5044
5494
  ...spec("correlate"),
5045
5495
  title: "Correlate by trace or run",
5046
5496
  description: "Everything that shares one W3C trace id or one Belvador run id (`belvador.run.id`, set by job monitors) in a time window: the trace summary, its error spans and the logs. Give exactly one of trace_id or run_id.",
5047
5497
  operations: ["traces.get", "traces.spans", "spans.list", "logs.list"],
5048
- input: z29.object({
5498
+ input: z31.object({
5049
5499
  trace_id: traceIdSchema.optional(),
5050
- run_id: z29.string().min(1).max(128).optional(),
5500
+ run_id: z31.string().min(1).max(128).optional(),
5051
5501
  ...isoWindow,
5052
- project: z29.string().max(2000).optional().describe("Comma-separated project ids.")
5502
+ project: z31.string().max(2000).optional().describe("Comma-separated project ids.")
5053
5503
  }),
5054
5504
  async run(args, rt) {
5055
5505
  const trace = args["trace_id"];
5056
5506
  const run = args["run_id"];
5057
5507
  if (!!trace === !!run)
5058
- return errorResult({ ok: false, status: 400, code: "INVALID_INPUT", detail: "one_of_trace_id_or_run_id" });
5059
- const window = { start: args["start"], end: args["end"], ...args["project"] ? { project: args["project"] } : {} };
5508
+ return errorResult({
5509
+ ok: false,
5510
+ status: 400,
5511
+ code: "INVALID_INPUT",
5512
+ detail: "one_of_trace_id_or_run_id"
5513
+ });
5514
+ const window = {
5515
+ start: args["start"],
5516
+ end: args["end"],
5517
+ ...args["project"] ? { project: args["project"] } : {}
5518
+ };
5060
5519
  const attrs = run ? JSON.stringify([{ k: "belvador.run.id", op: "=", v: run }]) : undefined;
5061
5520
  const omitted = [];
5062
5521
  const data = {};
@@ -5065,7 +5524,12 @@ var MCP_TOOL_DEFS = [
5065
5524
  const none = Promise.resolve(null);
5066
5525
  const [t, s, l] = await Promise.all([
5067
5526
  trace && has(rt, "traces.get") ? rt.call("traces.get", { trace_id: trace }) : none,
5068
- has(rt, spansOp) ? trace ? rt.call("traces.spans", { trace_id: trace, errors_only: "1", start: args["start"], end: args["end"] }) : rt.call("spans.list", { ...window, status: "error", attrs }) : none,
5527
+ has(rt, spansOp) ? trace ? rt.call("traces.spans", {
5528
+ trace_id: trace,
5529
+ errors_only: "1",
5530
+ start: args["start"],
5531
+ end: args["end"]
5532
+ }) : rt.call("spans.list", { ...window, status: "error", attrs }) : none,
5069
5533
  has(rt, "logs.list") ? rt.call("logs.list", { ...window, ...trace ? { trace_id: trace } : { attrs } }) : none
5070
5534
  ]);
5071
5535
  const windowError = [s, l].find((r) => r && !r.ok && (r.code === "QUERY_WINDOW_REQUIRED" || r.code === "QUERY_WINDOW_TOO_LARGE"));
@@ -5094,10 +5558,10 @@ var MCP_TOOL_DEFS = [
5094
5558
  title: "List monitors",
5095
5559
  description: "Monitors (cron, heartbeat, count, assertion, deadline, progress), uptime checks and SLOs with their current status. `kind` narrows to one family; `project_id` to one project (cron and uptime).",
5096
5560
  operations: ["monitors.list", "uptime.list", "slos.list"],
5097
- input: z29.object({
5098
- kind: z29.enum(["all", "cron", "uptime", "slo"]).default("all"),
5099
- project_id: z29.number().int().positive().optional(),
5100
- limit: z29.number().int().min(1).max(200).default(50)
5561
+ input: z31.object({
5562
+ kind: z31.enum(["all", "cron", "uptime", "slo"]).default("all"),
5563
+ project_id: z31.number().int().positive().optional(),
5564
+ limit: z31.number().int().min(1).max(200).default(50)
5101
5565
  }),
5102
5566
  async run(args, rt) {
5103
5567
  const kinds = args["kind"] && args["kind"] !== "all" ? [args["kind"]] : ["cron", "uptime", "slo"];
@@ -5124,11 +5588,18 @@ var MCP_TOOL_DEFS = [
5124
5588
  ...spec("get_monitor_status"),
5125
5589
  title: "Get a monitor",
5126
5590
  description: "One monitor (any type), uptime check or SLO by id: settings, current status and recent results. For count, assertion, deadline and progress monitors it adds the last 24 h of minute counts or runs from the node, and for deadline monitors the newest occurrences. `backtest: true` (count/assertion only) also replays the current settings over the last 30 days: how often it would have alerted.",
5127
- operations: ["monitors.get", "uptime.get", "slos.get", "monitors.signal", "monitors.occurrences", "monitors.backtest"],
5128
- input: z29.object({
5129
- kind: z29.enum(["cron", "uptime", "slo"]),
5130
- id: z29.guid(),
5131
- backtest: z29.boolean().default(false)
5591
+ operations: [
5592
+ "monitors.get",
5593
+ "uptime.get",
5594
+ "slos.get",
5595
+ "monitors.signal",
5596
+ "monitors.occurrences",
5597
+ "monitors.backtest"
5598
+ ],
5599
+ input: z31.object({
5600
+ kind: z31.enum(["cron", "uptime", "slo"]),
5601
+ id: z31.guid(),
5602
+ backtest: z31.boolean().default(false)
5132
5603
  }),
5133
5604
  async run(args, rt) {
5134
5605
  const k = MONITOR_KINDS2[args["kind"]];
@@ -5172,7 +5643,11 @@ var MCP_TOOL_DEFS = [
5172
5643
  else
5173
5644
  omitted.push({ part, reason: a.code });
5174
5645
  }
5175
- return wrapResult({ data, operations: ops, source: omitted.length === parts.length ? "control_plane" : "node" }, { omitted });
5646
+ return wrapResult({
5647
+ data,
5648
+ operations: ops,
5649
+ source: omitted.length === parts.length ? "control_plane" : "node"
5650
+ }, { omitted });
5176
5651
  }
5177
5652
  },
5178
5653
  single("list_alerts", "alerts.list", "List alerts", "Alerts Belvador raised (open, resolved or all), newest first, optionally for one monitor."),
@@ -5184,15 +5659,19 @@ var MCP_TOOL_DEFS = [
5184
5659
  title: "Send a test event",
5185
5660
  description: "Asks the node to send one tagged test error through the public intake of a project, proving the path real errors take. Not read-only: it creates one test event (reuse idempotency_key to retry without a second one).",
5186
5661
  operations: ["projects.send_test_event"],
5187
- input: z29.object({
5188
- project_id: z29.number().int().positive(),
5189
- idempotency_key: z29.string().min(8).max(255).optional()
5662
+ input: z31.object({
5663
+ project_id: z31.number().int().positive(),
5664
+ idempotency_key: z31.string().min(8).max(255).optional()
5190
5665
  }),
5191
5666
  async run(args, rt) {
5192
5667
  const r = await rt.call("projects.send_test_event", { project_id: args["project_id"] }, { idempotencyKey: args["idempotency_key"] ?? rt.newKey() });
5193
5668
  if (!r.ok)
5194
5669
  return errorResult(r);
5195
- return wrapResult({ data: r.body, operations: ["projects.send_test_event"], source: "control_plane" });
5670
+ return wrapResult({
5671
+ data: r.body,
5672
+ operations: ["projects.send_test_event"],
5673
+ source: "control_plane"
5674
+ });
5196
5675
  }
5197
5676
  },
5198
5677
  {
@@ -5200,9 +5679,9 @@ var MCP_TOOL_DEFS = [
5200
5679
  title: "Find a configuration change",
5201
5680
  description: "Searches what this token can change in its Belvador workspace: projects, keys and tokens, monitors of every type, maintenance windows, occurrences, uptime checks, SLOs, alert rules and destinations, members, service accounts and the node. Returns operation ids for describe_operation and plan_change, whether a person must approve the change, and whether this token holds the scope.",
5202
5681
  operations: [],
5203
- input: z29.object({
5204
- query: z29.string().min(1).max(200).describe("Words such as `rotate dsn key`, `heartbeat monitor`, `slack alert`."),
5205
- limit: z29.number().int().min(1).max(20).default(10)
5682
+ input: z31.object({
5683
+ query: z31.string().min(1).max(200).describe("Words such as `rotate dsn key`, `heartbeat monitor`, `slack alert`."),
5684
+ limit: z31.number().int().min(1).max(20).default(10)
5206
5685
  }),
5207
5686
  async run(args, rt) {
5208
5687
  const q = words(String(args["query"]));
@@ -5230,7 +5709,7 @@ var MCP_TOOL_DEFS = [
5230
5709
  title: "Describe a configuration change",
5231
5710
  description: "Everything needed to call one operation: its fields (JSON Schema, wire names), the scope, whether it needs If-Match (call plan_change for the current ETag), an idempotency key, or a person's approval, and which fields the approving person types on belvador.dev instead of the agent.",
5232
5711
  operations: [],
5233
- input: z29.object({ operation_id: operationIdArg }),
5712
+ input: z31.object({ operation_id: operationIdArg }),
5234
5713
  async run(args, rt) {
5235
5714
  const op = configureOp(args["operation_id"]);
5236
5715
  if (!op || op.method === "GET")
@@ -5259,7 +5738,7 @@ var MCP_TOOL_DEFS = [
5259
5738
  title: "Check a change before applying it",
5260
5739
  description: "Validates params for one operation without changing anything: field errors, missing scope, whether a person must approve, and — when the resource can be read — its current state, the fields that would change and the ETag to pass as if_match.",
5261
5740
  operations: [],
5262
- input: z29.object({ operation_id: operationIdArg, params }),
5741
+ input: z31.object({ operation_id: operationIdArg, params }),
5263
5742
  async run(args, rt) {
5264
5743
  const op = configureOp(args["operation_id"]);
5265
5744
  if (!op || op.method === "GET")
@@ -5308,11 +5787,11 @@ var MCP_TOOL_DEFS = [
5308
5787
  title: "Apply a configuration change",
5309
5788
  description: "Runs one operation with params (validate first with plan_change). Always send idempotency_key: repeating a call with the same key never applies it twice. Sensitive operations answer approval_required with an approval_url a person opens on belvador.dev; nothing changes until they approve with their authenticator code.",
5310
5789
  operations: [],
5311
- input: z29.object({
5790
+ input: z31.object({
5312
5791
  operation_id: operationIdArg,
5313
5792
  params,
5314
- idempotency_key: z29.string().min(8).max(255).describe("Unique per change; reuse it to retry or to fetch the result."),
5315
- if_match: z29.string().max(200).optional().describe("ETag from plan_change, for operations that need it.")
5793
+ idempotency_key: z31.string().min(8).max(255).describe("Unique per change; reuse it to retry or to fetch the result."),
5794
+ if_match: z31.string().max(200).optional().describe("ETag from plan_change, for operations that need it.")
5316
5795
  }),
5317
5796
  async run(args, rt) {
5318
5797
  const op = configureOp(args["operation_id"]);
@@ -5321,8 +5800,15 @@ var MCP_TOOL_DEFS = [
5321
5800
  const p = args["params"] ?? {};
5322
5801
  for (const f of humanWire(op))
5323
5802
  if (f in p)
5324
- return errorResult({ ok: false, status: 400, code: "INVALID_INPUT", detail: `${f} is typed by the approving person` });
5325
- const opts = { idempotencyKey: String(args["idempotency_key"]) };
5803
+ return errorResult({
5804
+ ok: false,
5805
+ status: 400,
5806
+ code: "INVALID_INPUT",
5807
+ detail: `${f} is typed by the approving person`
5808
+ });
5809
+ const opts = {
5810
+ idempotencyKey: String(args["idempotency_key"])
5811
+ };
5326
5812
  if (typeof args["if_match"] === "string" && args["if_match"])
5327
5813
  opts.ifMatch = args["if_match"];
5328
5814
  const r = await rt.call(op.id, p, opts);
@@ -5342,7 +5828,10 @@ var MCP_TOOL_DEFS = [
5342
5828
  if (r.approval && r.approval.state === "pending") {
5343
5829
  const next = APPROVAL_SETUP_OPS.includes(op.id) ? `${NEXT_PENDING} ${NEXT_SETUP}` : NEXT_PENDING;
5344
5830
  return {
5345
- structuredContent: { status: "approval_required", approval: approvalBlock(r.approval, next) },
5831
+ structuredContent: {
5832
+ status: "approval_required",
5833
+ approval: approvalBlock(r.approval, next)
5834
+ },
5346
5835
  approval: r.approval
5347
5836
  };
5348
5837
  }
@@ -5363,7 +5852,7 @@ var MCP_TOOL_DEFS = [
5363
5852
  title: "Follow an approval",
5364
5853
  description: "State of a change waiting for a person's approval: pending, approved, executed (with the ids it produced), rejected, expired or failed (with the error code).",
5365
5854
  operations: ["approvals.get"],
5366
- input: z29.object({ approval_id: z29.guid().describe("approval_id from apply_change.") }),
5855
+ input: z31.object({ approval_id: z31.guid().describe("approval_id from apply_change.") }),
5367
5856
  async run(args, rt) {
5368
5857
  const r = await rt.call("approvals.get", { approval_id: args["approval_id"] });
5369
5858
  if (!r.ok)
@@ -5383,10 +5872,10 @@ var MCP_TOOL_DEFS = [
5383
5872
  title: "Search Belvador docs",
5384
5873
  description: "Searches the public Belvador documentation (titles and summaries) and returns the best pages with their slugs for get_doc.",
5385
5874
  operations: [],
5386
- input: z29.object({
5387
- query: z29.string().min(1).max(200),
5388
- locale: z29.enum(["en", "vi"]).default("en"),
5389
- limit: z29.number().int().min(1).max(10).default(5)
5875
+ input: z31.object({
5876
+ query: z31.string().min(1).max(200),
5877
+ locale: z31.enum(["en", "vi"]).default("en"),
5878
+ limit: z31.number().int().min(1).max(10).default(5)
5390
5879
  }),
5391
5880
  async run(args, rt) {
5392
5881
  const locale = args["locale"] ?? "en";
@@ -5402,9 +5891,9 @@ var MCP_TOOL_DEFS = [
5402
5891
  title: "Read a docs page",
5403
5892
  description: "The Markdown of one public Belvador docs page by slug (e.g. `quickstart`, `sdk/react`, `reference/api`).",
5404
5893
  operations: [],
5405
- input: z29.object({
5406
- slug: z29.string().regex(/^[a-z0-9][a-z0-9/-]{0,120}$/),
5407
- locale: z29.enum(["en", "vi"]).default("en")
5894
+ input: z31.object({
5895
+ slug: z31.string().regex(/^[a-z0-9][a-z0-9/-]{0,120}$/),
5896
+ locale: z31.enum(["en", "vi"]).default("en")
5408
5897
  }),
5409
5898
  async run(args, rt) {
5410
5899
  const locale = args["locale"] ?? "en";
@@ -5417,7 +5906,13 @@ var MCP_TOOL_DEFS = [
5417
5906
  const markdown = cut ? cleanUntrustedText(md, max).text : md;
5418
5907
  return {
5419
5908
  structuredContent: {
5420
- doc: { slug, locale, url: `https://belvador.dev/${locale}/docs/${slug}`, markdown, truncated: cut }
5909
+ doc: {
5910
+ slug,
5911
+ locale,
5912
+ url: `https://belvador.dev/${locale}/docs/${slug}`,
5913
+ markdown,
5914
+ truncated: cut
5915
+ }
5421
5916
  }
5422
5917
  };
5423
5918
  }
@@ -5435,7 +5930,13 @@ function parseDocsIndex(index) {
5435
5930
  }
5436
5931
  const m = /^- \[([^\]]+)\]\(https:\/\/belvador\.dev\/api\/public\/docs\/(en|vi)\/([a-z0-9/-]+)\):\s*(.*)$/.exec(line);
5437
5932
  if (m)
5438
- out.push({ title: m[1], slug: m[3], description: m[4], section, url: `https://belvador.dev/${m[2]}/docs/${m[3]}` });
5933
+ out.push({
5934
+ title: m[1],
5935
+ slug: m[3],
5936
+ description: m[4],
5937
+ section,
5938
+ url: `https://belvador.dev/${m[2]}/docs/${m[3]}`
5939
+ });
5439
5940
  }
5440
5941
  return out;
5441
5942
  }
@@ -5586,7 +6087,7 @@ function findToken(env = process.env, keychain = keychainToken) {
5586
6087
  }
5587
6088
 
5588
6089
  // packages/mcp/src/cli.ts
5589
- var PACKAGE_VERSION = "0.5.0";
6090
+ var PACKAGE_VERSION = "0.6.0";
5590
6091
  var HELP = `belvador-mcp ${PACKAGE_VERSION} — Belvador MCP server (stdio)
5591
6092
 
5592
6093
  Usage: npx -y @belvador/mcp [--toolsets=${MCP_DEFAULT_TOOLSETS.join(",")}]