@burdenoff/mcp-libs 2026.1009.1 → 2026.1009.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/modules/files/index.cjs +101 -432
  2. package/dist/modules/files/index.cjs.map +1 -1
  3. package/dist/modules/files/index.js +102 -428
  4. package/dist/modules/files/index.js.map +1 -1
  5. package/dist/modules/groups/index.cjs +89 -360
  6. package/dist/modules/groups/index.cjs.map +1 -1
  7. package/dist/modules/groups/index.js +90 -356
  8. package/dist/modules/groups/index.js.map +1 -1
  9. package/dist/modules/rbac/index.cjs +85 -409
  10. package/dist/modules/rbac/index.cjs.map +1 -1
  11. package/dist/modules/rbac/index.js +86 -405
  12. package/dist/modules/rbac/index.js.map +1 -1
  13. package/dist/modules/sandbox/index.cjs +80 -1136
  14. package/dist/modules/sandbox/index.cjs.map +1 -1
  15. package/dist/modules/sandbox/index.js +80 -916
  16. package/dist/modules/sandbox/index.js.map +1 -1
  17. package/dist/modules/scheduler/index.cjs +70 -1044
  18. package/dist/modules/scheduler/index.cjs.map +1 -1
  19. package/dist/modules/scheduler/index.js +69 -1038
  20. package/dist/modules/scheduler/index.js.map +1 -1
  21. package/dist/modules/security/index.cjs +42 -507
  22. package/dist/modules/security/index.cjs.map +1 -1
  23. package/dist/modules/security/index.js +41 -501
  24. package/dist/modules/security/index.js.map +1 -1
  25. package/dist/modules/store/index.cjs +49 -479
  26. package/dist/modules/store/index.cjs.map +1 -1
  27. package/dist/modules/store/index.js +48 -473
  28. package/dist/modules/store/index.js.map +1 -1
  29. package/dist/modules/support/index.cjs +18 -19
  30. package/dist/modules/support/index.cjs.map +1 -1
  31. package/dist/modules/support/index.js +18 -19
  32. package/dist/modules/support/index.js.map +1 -1
  33. package/dist/modules/tags/index.cjs +43 -348
  34. package/dist/modules/tags/index.cjs.map +1 -1
  35. package/dist/modules/tags/index.js +42 -342
  36. package/dist/modules/tags/index.js.map +1 -1
  37. package/dist/modules/vibecontrols/index.js +1774 -1
  38. package/dist/modules/vibecontrols/index.js.map +1 -1
  39. package/dist/modules/workspaces/index.cjs +5 -12
  40. package/dist/modules/workspaces/index.cjs.map +1 -1
  41. package/dist/modules/workspaces/index.js +5 -12
  42. package/dist/modules/workspaces/index.js.map +1 -1
  43. package/package.json +1 -1
  44. package/dist/chunk-XITZQYB2.js +0 -1776
  45. package/dist/chunk-XITZQYB2.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var zod = require('zod');
4
3
  require('graphql-request');
5
4
  require('cross-fetch');
6
5
  require('@modelcontextprotocol/sdk/server/mcp.js');
7
6
  require('@modelcontextprotocol/sdk/types.js');
7
+ require('zod');
8
8
 
9
- // src/modules/security/tools.ts
9
+ // src/core/auth/store.ts
10
10
 
11
11
  // src/core/errors.ts
12
12
  var McpInternalError = class extends Error {
@@ -37,12 +37,6 @@ function mcpToolName(productName, ...parts) {
37
37
  }
38
38
 
39
39
  // src/core/result.ts
40
- function jsonResult(data, structured) {
41
- const result = {
42
- content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
43
- };
44
- return result;
45
- }
46
40
  function errorResult(message, hint) {
47
41
  const text = hint ? `${message}
48
42
 
@@ -50,511 +44,52 @@ Hint: ${hint}` : message;
50
44
  return { content: [{ type: "text", text }], isError: true };
51
45
  }
52
46
 
53
- // src/modules/security/operations.ts
54
- var GET_VAULTS = `
55
- query GetVaults($filter: VaultFilterInput, $pagination: SecurityPaginationInput) {
56
- getVaults(filter: $filter, pagination: $pagination) {
57
- items { id name description scope status createdAt }
58
- total hasMore
59
- }
60
- }
61
- `;
62
- var GET_VAULT = `
63
- query GetVault($id: ID!) {
64
- getVault(id: $id) {
65
- id name description scope scopeId status lockAfterMinutes createdAt updatedAt
66
- }
67
- }
68
- `;
69
- var CREATE_VAULT = `
70
- mutation CreateVault($input: CreateVaultInput!) {
71
- createVault(input: $input) {
72
- id name scope scopeId status
73
- }
74
- }
75
- `;
76
- var UPDATE_VAULT = `
77
- mutation UpdateVault($id: ID!, $input: UpdateVaultInput!) {
78
- updateVault(id: $id, input: $input) {
79
- id name description scope status lockAfterMinutes updatedAt
80
- }
81
- }
82
- `;
83
- var DELETE_VAULT = `
84
- mutation DeleteVault($id: ID!) {
85
- deleteVault(id: $id)
86
- }
87
- `;
88
- var ARCHIVE_VAULT = `
89
- mutation ArchiveVault($id: ID!) {
90
- archiveVault(id: $id) { id status }
91
- }
92
- `;
93
- var GET_SECRETS = `
94
- query GetSecrets($vaultId: ID!, $filter: SecretFilterInput, $pagination: SecurityPaginationInput) {
95
- getSecrets(vaultId: $vaultId, filter: $filter, pagination: $pagination) {
96
- items { id key name description type status isEphemeral createdAt }
97
- total hasMore
98
- }
99
- }
100
- `;
101
- var GET_SECRET = `
102
- query GetSecret($id: ID!) {
103
- getSecret(id: $id) {
104
- id key name description type status isEphemeral expiresAt createdAt updatedAt
105
- }
106
- }
107
- `;
108
- var DECRYPT_SECRET = `
109
- query DecryptSecret($id: ID!) {
110
- decryptSecret(id: $id) {
111
- id key value
112
- }
113
- }
114
- `;
115
- var CREATE_SECRET = `
116
- mutation CreateSecret($input: CreateSecretInput!) {
117
- createSecret(input: $input) {
118
- id key name type status
119
- }
120
- }
121
- `;
122
- var UPDATE_SECRET = `
123
- mutation UpdateSecret($id: ID!, $input: UpdateSecretInput!) {
124
- updateSecret(id: $id, input: $input) {
125
- id key name status updatedAt
126
- }
127
- }
128
- `;
129
- var DELETE_SECRET = `
130
- mutation DeleteSecret($id: ID!) {
131
- deleteSecret(id: $id)
132
- }
133
- `;
134
- var ROTATE_SECRET = `
135
- mutation RotateSecret($id: ID!, $newValue: String!) {
136
- rotateSecret(id: $id, newValue: $newValue) {
137
- id key updatedAt
138
- }
139
- }
140
- `;
141
-
142
47
  // src/modules/security/tools.ts
143
- var VaultScopeEnum = zod.z.enum(["WORKSPACE", "GLOBAL", "VIBE"]);
144
- var VaultStatusEnum = zod.z.enum(["ACTIVE", "LOCKED", "ARCHIVED"]);
145
- var SecretTypeEnum = zod.z.enum(["API_KEY", "PASSWORD", "CERTIFICATE", "TOKEN", "OTHER"]);
146
- var SecretStatusEnum = zod.z.enum(["ACTIVE", "EXPIRED", "REVOKED"]);
147
- function readWorkspaceContext(ctx) {
148
- const auth = ctx.auth.read();
149
- if (!auth?.workspaceId) return null;
150
- return { workspaceId: auth.workspaceId };
151
- }
152
- function registerSecurityTools(server, ctx, track) {
153
- server.registerTool(
154
- track(mcpToolName(ctx.productName, "security_vaults_list")),
155
- {
156
- title: "List Vaults",
157
- description: "List vaults in the current workspace with optional filters and pagination.",
158
- inputSchema: {
159
- scope: VaultScopeEnum.optional().describe("Filter by vault scope"),
160
- status: VaultStatusEnum.optional().describe("Filter by status"),
161
- search: zod.z.string().optional().describe("Free-text search"),
162
- limit: zod.z.number().optional().describe("Page size (default 50)"),
163
- offset: zod.z.number().optional().describe("Skip results")
164
- }
165
- },
166
- async ({ scope, status, search, limit, offset }) => {
167
- try {
168
- const workspaceCtx = readWorkspaceContext(ctx);
169
- if (!workspaceCtx) {
170
- return errorResult(
171
- "No active workspace. Bind a workspace via the auth login flow first."
172
- );
173
- }
174
- const filter = { context: workspaceCtx };
175
- if (scope !== void 0) filter.scope = scope;
176
- if (status !== void 0) filter.status = status;
177
- if (search !== void 0) filter.search = search;
178
- const pagination = {};
179
- if (limit !== void 0) pagination.limit = limit;
180
- if (offset !== void 0) pagination.offset = offset;
181
- const data = await ctx.gql.workspace.request(GET_VAULTS, {
182
- filter,
183
- pagination: Object.keys(pagination).length > 0 ? pagination : void 0
184
- });
185
- return jsonResult(data.getVaults);
186
- } catch (error) {
187
- ctx.logger.error("security_vaults_list failed", { error });
188
- return errorResult(
189
- `Failed to list vaults: ${error instanceof Error ? error.message : String(error)}`
190
- );
191
- }
192
- }
193
- );
194
- server.registerTool(
195
- track(mcpToolName(ctx.productName, "security_vaults_get")),
196
- {
197
- title: "Get Vault",
198
- description: "Get a vault by ID.",
199
- inputSchema: {
200
- id: zod.z.string().describe("Vault ID")
201
- }
202
- },
203
- async ({ id }) => {
204
- try {
205
- const data = await ctx.gql.workspace.request(GET_VAULT, {
206
- id
207
- });
208
- if (!data.getVault) {
209
- return errorResult(`Vault ${id} not found`);
210
- }
211
- return jsonResult(data.getVault);
212
- } catch (error) {
213
- ctx.logger.error("security_vaults_get failed", { error });
214
- return errorResult(
215
- `Failed to get vault: ${error instanceof Error ? error.message : String(error)}`
216
- );
217
- }
218
- }
219
- );
220
- server.registerTool(
221
- track(mcpToolName(ctx.productName, "security_vaults_create")),
222
- {
223
- title: "Create Vault",
224
- description: "Create a new vault scoped to the current workspace.",
225
- inputSchema: {
226
- name: zod.z.string().describe("Vault name"),
227
- description: zod.z.string().optional().describe("Vault description"),
228
- scope: VaultScopeEnum.optional().describe("Vault scope (default: WORKSPACE)"),
229
- scopeId: zod.z.string().optional().describe("Scope ID (defaults to current workspace ID when scope is WORKSPACE)"),
230
- lockAfterMinutes: zod.z.number().optional().describe("Auto-lock after N minutes of inactivity")
231
- }
232
- },
233
- async ({ name, description, scope, scopeId, lockAfterMinutes }) => {
234
- try {
235
- const workspaceCtx = readWorkspaceContext(ctx);
236
- if (!workspaceCtx) {
237
- return errorResult(
238
- "No active workspace. Bind a workspace via the auth login flow first."
239
- );
240
- }
241
- const resolvedScope = scope ?? "WORKSPACE";
242
- const input = {
243
- context: workspaceCtx,
244
- name,
245
- scope: resolvedScope,
246
- scopeId: scopeId ?? workspaceCtx.workspaceId
247
- };
248
- if (description !== void 0) input.description = description;
249
- if (lockAfterMinutes !== void 0) input.lockAfterMinutes = lockAfterMinutes;
250
- const data = await ctx.gql.workspace.request(CREATE_VAULT, {
251
- input
252
- });
253
- return jsonResult(data.createVault);
254
- } catch (error) {
255
- ctx.logger.error("security_vaults_create failed", { error });
256
- return errorResult(
257
- `Failed to create vault: ${error instanceof Error ? error.message : String(error)}`
258
- );
259
- }
260
- }
261
- );
262
- server.registerTool(
263
- track(mcpToolName(ctx.productName, "security_vaults_update")),
264
- {
265
- title: "Update Vault",
266
- description: "Update a vault (name/description/lockAfterMinutes/status). At least one field must be provided. The workspace context is implicit. Returns the updated Vault.",
267
- inputSchema: {
268
- id: zod.z.string().describe("Vault ID"),
269
- name: zod.z.string().optional().describe("Updated vault name"),
270
- description: zod.z.string().optional().describe("Updated description"),
271
- status: VaultStatusEnum.optional().describe("Updated vault status"),
272
- lockAfterMinutes: zod.z.number().int().optional().describe("Auto-lock after N minutes of inactivity")
273
- }
274
- },
275
- async ({ id, name, description, status, lockAfterMinutes }) => {
276
- try {
277
- const workspaceCtx = readWorkspaceContext(ctx);
278
- if (!workspaceCtx) {
279
- return errorResult(
280
- "No active workspace. Bind a workspace via the auth login flow first."
281
- );
282
- }
283
- const input = { context: workspaceCtx };
284
- if (name !== void 0) input.name = name;
285
- if (description !== void 0) input.description = description;
286
- if (status !== void 0) input.status = status;
287
- if (lockAfterMinutes !== void 0) input.lockAfterMinutes = lockAfterMinutes;
288
- if (Object.keys(input).length === 1) {
289
- return errorResult(
290
- "No updates specified \u2014 provide at least one of name/description/status/lockAfterMinutes"
291
- );
292
- }
293
- const data = await ctx.gql.workspace.request(UPDATE_VAULT, {
294
- id,
295
- input
296
- });
297
- return jsonResult(data.updateVault);
298
- } catch (error) {
299
- ctx.logger.error("security_vaults_update failed", { error });
300
- return errorResult(
301
- `Failed to update vault: ${error instanceof Error ? error.message : String(error)}`
302
- );
303
- }
304
- }
305
- );
306
- server.registerTool(
307
- track(mcpToolName(ctx.productName, "security_vaults_delete")),
308
- {
309
- title: "Delete Vault",
310
- description: "Delete a vault. Set archive=true to soft-archive instead of permanently deleting.",
311
- inputSchema: {
312
- id: zod.z.string().describe("Vault ID"),
313
- archive: zod.z.boolean().optional().describe("Archive instead of hard delete")
314
- }
315
- },
316
- async ({ id, archive }) => {
317
- try {
318
- if (archive === true) {
319
- const data2 = await ctx.gql.workspace.request(ARCHIVE_VAULT, { id });
320
- return jsonResult({ archived: true, vault: data2.archiveVault });
321
- }
322
- const data = await ctx.gql.workspace.request(DELETE_VAULT, {
323
- id
324
- });
325
- return jsonResult({ deleted: data.deleteVault, vaultId: id });
326
- } catch (error) {
327
- ctx.logger.error("security_vaults_delete failed", { error });
328
- return errorResult(
329
- `Failed to delete vault: ${error instanceof Error ? error.message : String(error)}`
330
- );
331
- }
332
- }
333
- );
334
- server.registerTool(
335
- track(mcpToolName(ctx.productName, "security_secrets_list")),
336
- {
337
- title: "List Secrets",
338
- description: "List secrets in a vault with optional filters and pagination.",
339
- inputSchema: {
340
- vaultId: zod.z.string().describe("Vault ID"),
341
- type: SecretTypeEnum.optional().describe("Filter by secret type"),
342
- search: zod.z.string().optional().describe("Free-text search"),
343
- limit: zod.z.number().optional().describe("Page size (default 100)"),
344
- offset: zod.z.number().optional().describe("Skip results")
345
- }
346
- },
347
- async ({ vaultId, type, search, limit, offset }) => {
348
- try {
349
- const workspaceCtx = readWorkspaceContext(ctx);
350
- if (!workspaceCtx) {
351
- return errorResult(
352
- "No active workspace. Bind a workspace via the auth login flow first."
353
- );
354
- }
355
- const filter = { context: workspaceCtx };
356
- if (type !== void 0) filter.type = type;
357
- if (search !== void 0) filter.search = search;
358
- const pagination = {};
359
- if (limit !== void 0) pagination.limit = limit;
360
- if (offset !== void 0) pagination.offset = offset;
361
- const data = await ctx.gql.workspace.request(GET_SECRETS, {
362
- vaultId,
363
- filter,
364
- pagination: Object.keys(pagination).length > 0 ? pagination : void 0
365
- });
366
- return jsonResult(data.getSecrets);
367
- } catch (error) {
368
- ctx.logger.error("security_secrets_list failed", { error });
369
- return errorResult(
370
- `Failed to list secrets: ${error instanceof Error ? error.message : String(error)}`
371
- );
372
- }
373
- }
374
- );
375
- server.registerTool(
376
- track(mcpToolName(ctx.productName, "security_secrets_get")),
377
- {
378
- title: "Get Secret Metadata",
379
- description: "Get a secret's metadata. Does NOT decrypt the value \u2014 use security_secrets_reveal for that.",
380
- inputSchema: {
381
- id: zod.z.string().describe("Secret ID")
382
- }
383
- },
384
- async ({ id }) => {
385
- try {
386
- const data = await ctx.gql.workspace.request(GET_SECRET, {
387
- id
388
- });
389
- if (!data.getSecret) {
390
- return errorResult(`Secret ${id} not found`);
391
- }
392
- return jsonResult(data.getSecret);
393
- } catch (error) {
394
- ctx.logger.error("security_secrets_get failed", { error });
395
- return errorResult(
396
- `Failed to get secret: ${error instanceof Error ? error.message : String(error)}`
397
- );
398
- }
399
- }
400
- );
401
- server.registerTool(
402
- track(mcpToolName(ctx.productName, "security_secrets_reveal")),
403
- {
404
- title: "Reveal Secret Value",
405
- description: "Decrypt and return the secret value. This action is audited server-side. Treat the result as sensitive and avoid persisting it.",
406
- inputSchema: {
407
- id: zod.z.string().describe("Secret ID")
408
- }
409
- },
410
- async ({ id }) => {
411
- try {
412
- const data = await ctx.gql.workspace.request(DECRYPT_SECRET, { id });
413
- return jsonResult(data.decryptSecret);
414
- } catch (error) {
415
- ctx.logger.error("security_secrets_reveal failed", { error });
416
- return errorResult(
417
- `Failed to reveal secret: ${error instanceof Error ? error.message : String(error)}`
418
- );
419
- }
420
- }
421
- );
48
+ function stubbedTool(server, toolName, title, description, featureNote, inputSchema, altSuggestions) {
422
49
  server.registerTool(
423
- track(mcpToolName(ctx.productName, "security_secrets_set")),
50
+ toolName,
424
51
  {
425
- title: "Create Secret",
426
- description: "Create a new secret in a vault. The value is encrypted server-side.",
427
- inputSchema: {
428
- vaultId: zod.z.string().describe("Vault ID"),
429
- key: zod.z.string().describe("Secret key (unique within the vault)"),
430
- name: zod.z.string().describe("Human-readable secret name"),
431
- value: zod.z.string().describe("Secret value (will be encrypted server-side)"),
432
- description: zod.z.string().optional().describe("Secret description"),
433
- type: SecretTypeEnum.optional().describe("Secret type (default: OTHER)"),
434
- isEphemeral: zod.z.boolean().optional().describe("Mark as ephemeral"),
435
- expiresAt: zod.z.string().optional().describe("Expiry timestamp in ISO 8601")
436
- }
52
+ title,
53
+ description: `${description} [STUB]`,
54
+ inputSchema
437
55
  },
438
- async ({ vaultId, key, name, value, description, type, isEphemeral, expiresAt }) => {
439
- try {
440
- const workspaceCtx = readWorkspaceContext(ctx);
441
- if (!workspaceCtx) {
442
- return errorResult(
443
- "No active workspace. Bind a workspace via the auth login flow first."
444
- );
445
- }
446
- const input = {
447
- context: workspaceCtx,
448
- vaultId,
449
- key,
450
- name,
451
- value,
452
- type: type ?? "OTHER",
453
- isEphemeral: isEphemeral === true
454
- };
455
- if (description !== void 0) input.description = description;
456
- if (expiresAt !== void 0) input.expiresAt = expiresAt;
457
- const data = await ctx.gql.workspace.request(CREATE_SECRET, {
458
- input
459
- });
460
- return jsonResult(data.createSecret);
461
- } catch (error) {
462
- ctx.logger.error("security_secrets_set failed", { error });
463
- return errorResult(
464
- `Failed to create secret: ${error instanceof Error ? error.message : String(error)}`
465
- );
466
- }
467
- }
468
- );
469
- server.registerTool(
470
- track(mcpToolName(ctx.productName, "security_secrets_update")),
471
- {
472
- title: "Update Secret Metadata",
473
- description: "Update secret metadata (name, description, status). To rotate the value, use security_secrets_rotate.",
474
- inputSchema: {
475
- id: zod.z.string().describe("Secret ID"),
476
- name: zod.z.string().optional().describe("Updated name"),
477
- description: zod.z.string().optional().describe("Updated description"),
478
- status: SecretStatusEnum.optional().describe("Updated status")
479
- }
480
- },
481
- async ({ id, name, description, status }) => {
482
- try {
483
- const workspaceCtx = readWorkspaceContext(ctx);
484
- if (!workspaceCtx) {
485
- return errorResult(
486
- "No active workspace. Bind a workspace via the auth login flow first."
487
- );
488
- }
489
- const input = { context: workspaceCtx };
490
- if (name !== void 0) input.name = name;
491
- if (description !== void 0) input.description = description;
492
- if (status !== void 0) input.status = status;
493
- if (Object.keys(input).length === 1) {
494
- return errorResult("No updates specified");
495
- }
496
- const data = await ctx.gql.workspace.request(UPDATE_SECRET, {
497
- id,
498
- input
499
- });
500
- return jsonResult(data.updateSecret);
501
- } catch (error) {
502
- ctx.logger.error("security_secrets_update failed", { error });
503
- return errorResult(
504
- `Failed to update secret: ${error instanceof Error ? error.message : String(error)}`
505
- );
506
- }
507
- }
508
- );
509
- server.registerTool(
510
- track(mcpToolName(ctx.productName, "security_secrets_rotate")),
511
- {
512
- title: "Rotate Secret Value",
513
- description: "Replace a secret's encrypted value with a new one.",
514
- inputSchema: {
515
- id: zod.z.string().describe("Secret ID"),
516
- newValue: zod.z.string().describe("New secret value")
517
- }
518
- },
519
- async ({ id, newValue }) => {
520
- try {
521
- const data = await ctx.gql.workspace.request(ROTATE_SECRET, {
522
- id,
523
- newValue
524
- });
525
- return jsonResult(data.rotateSecret);
526
- } catch (error) {
527
- ctx.logger.error("security_secrets_rotate failed", { error });
528
- return errorResult(
529
- `Failed to rotate secret: ${error instanceof Error ? error.message : String(error)}`
530
- );
531
- }
532
- }
533
- );
534
- server.registerTool(
535
- track(mcpToolName(ctx.productName, "security_secrets_delete")),
536
- {
537
- title: "Delete Secret",
538
- description: "Delete a secret by ID.",
539
- inputSchema: {
540
- id: zod.z.string().describe("Secret ID")
541
- }
542
- },
543
- async ({ id }) => {
544
- try {
545
- const data = await ctx.gql.workspace.request(DELETE_SECRET, {
546
- id
547
- });
548
- return jsonResult({ deleted: data.deleteSecret, secretId: id });
549
- } catch (error) {
550
- ctx.logger.error("security_secrets_delete failed", { error });
551
- return errorResult(
552
- `Failed to delete secret: ${error instanceof Error ? error.message : String(error)}`
553
- );
554
- }
555
- }
56
+ async () => errorResult(
57
+ `[stubbed] ${featureNote} Use ${altSuggestions.join(", ")} instead. The tool remains registered so callers receive a meaningful response instead of a schema-validation error.`
58
+ )
556
59
  );
557
60
  }
61
+ function registerSecurityTools(server, ctx, track) {
62
+ const featureNote = "Live alpha removed `Mutation.createSecret` and `CreateSecretInput`. The surviving workspaces-endpoint variant requires a `SecretType!` value whose enum members are unlistable from outside the gateway (introspection disabled). The original `OTHER` default is no longer a valid enum member.";
63
+ const alts = [
64
+ "the next alpha release that restores the global `createSecret` mutation",
65
+ "the SDK security API (which the MCP will mirror once it lands)"
66
+ ];
67
+ const tools = [
68
+ ["security_vaults_list", "List Vaults", "List vaults in the active workspace."],
69
+ ["security_vaults_get", "Get Vault", "Get a vault by ID."],
70
+ ["security_vaults_create", "Create Vault", "Create a new vault."],
71
+ ["security_vaults_update", "Update Vault", "Update a vault."],
72
+ ["security_vaults_delete", "Delete Vault", "Delete a vault."],
73
+ ["security_secrets_list", "List Secrets", "List secrets in a vault."],
74
+ ["security_secrets_get", "Get Secret", "Get a secret by ID."],
75
+ ["security_secrets_reveal", "Reveal Secret", "Decrypt a secret."],
76
+ ["security_secrets_set", "Set Secret", "Create or update a secret."],
77
+ ["security_secrets_update", "Update Secret", "Update secret metadata."],
78
+ ["security_secrets_delete", "Delete Secret", "Delete a secret."],
79
+ ["security_secrets_rotate", "Rotate Secret", "Rotate a secret's value."]
80
+ ];
81
+ for (const [tool, title, desc] of tools) {
82
+ stubbedTool(
83
+ server,
84
+ track(mcpToolName(ctx.productName, tool)),
85
+ title,
86
+ desc,
87
+ featureNote,
88
+ {},
89
+ alts
90
+ );
91
+ }
92
+ }
558
93
 
559
94
  // src/modules/security/index.ts
560
95
  var securityModule = {