@seekrit/cli 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -2720,7 +2720,7 @@ function isCliSessionToken(value) {
|
|
|
2720
2720
|
}
|
|
2721
2721
|
//#endregion
|
|
2722
2722
|
//#region package.json
|
|
2723
|
-
var version = "0.
|
|
2723
|
+
var version = "0.32.0";
|
|
2724
2724
|
//#endregion
|
|
2725
2725
|
//#region ../../packages/api-client/src/index.ts
|
|
2726
2726
|
var SeekritApiError = class extends Error {
|
|
@@ -7395,7 +7395,7 @@ registerMongoCommands(program);
|
|
|
7395
7395
|
registerKmsCommands(program);
|
|
7396
7396
|
registerRecoveryCommands(program);
|
|
7397
7397
|
program.command("mcp").description("run an MCP server over stdio so AI agents can drive seekrit").action(async () => {
|
|
7398
|
-
const { runMcpServer } = await import("./mcp-
|
|
7398
|
+
const { runMcpServer } = await import("./mcp-DR-zla_u.js");
|
|
7399
7399
|
await runMcpServer();
|
|
7400
7400
|
});
|
|
7401
7401
|
registerAuditCommands(program);
|
|
@@ -26,6 +26,16 @@ function errText(err) {
|
|
|
26
26
|
isError: true
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
+
/** Read-only and safe to repeat — every list/inspect tool. */
|
|
30
|
+
const ro = {
|
|
31
|
+
readOnly: true,
|
|
32
|
+
idempotent: true
|
|
33
|
+
};
|
|
34
|
+
/** Removes or overwrites something; repeating it lands in the same state. */
|
|
35
|
+
const destructive = {
|
|
36
|
+
destructive: true,
|
|
37
|
+
idempotent: true
|
|
38
|
+
};
|
|
29
39
|
/**
|
|
30
40
|
* Short primer surfaced as the MCP server `instructions`. Most clients show
|
|
31
41
|
* this to the model on connect, so it has to orient an agent that lands here
|
|
@@ -194,10 +204,17 @@ async function runMcpServer(options = {}) {
|
|
|
194
204
|
version: options.version ?? version
|
|
195
205
|
}, { instructions: serverInstructions() });
|
|
196
206
|
/** Register a tool whose handler returns data (serialized) or throws (→ isError). */
|
|
197
|
-
const tool = (name, description, shape, handler) => {
|
|
207
|
+
const tool = (name, description, hints, shape, handler) => {
|
|
198
208
|
server.registerTool(name, {
|
|
199
209
|
description,
|
|
200
|
-
inputSchema: shape
|
|
210
|
+
inputSchema: shape,
|
|
211
|
+
annotations: {
|
|
212
|
+
title: name,
|
|
213
|
+
readOnlyHint: hints.readOnly ?? false,
|
|
214
|
+
destructiveHint: hints.destructive ?? false,
|
|
215
|
+
idempotentHint: hints.idempotent ?? false,
|
|
216
|
+
openWorldHint: true
|
|
217
|
+
}
|
|
201
218
|
}, (async (args) => {
|
|
202
219
|
try {
|
|
203
220
|
return jsonText(await handler(args));
|
|
@@ -215,7 +232,7 @@ async function runMcpServer(options = {}) {
|
|
|
215
232
|
openWorldHint: false
|
|
216
233
|
}
|
|
217
234
|
}, async () => jsonText(getStartedText()));
|
|
218
|
-
tool("whoami", "Show the authenticated identity, its role, and accessible orgs.", {}, async () => {
|
|
235
|
+
tool("whoami", "Show the authenticated identity, its role, and accessible orgs.", ro, {}, async () => {
|
|
219
236
|
const ctx = getCtx();
|
|
220
237
|
if (isTokenAuth(ctx) && ctx.auth.type === "bearer") {
|
|
221
238
|
const { tokenId } = await parseServiceToken(ctx.auth.token);
|
|
@@ -236,13 +253,13 @@ async function runMcpServer(options = {}) {
|
|
|
236
253
|
...await ctx.client.me()
|
|
237
254
|
};
|
|
238
255
|
});
|
|
239
|
-
tool("list_orgs", "List organizations the caller can access.", {}, async () => (await getCtx().client.listOrgs()).orgs);
|
|
240
|
-
tool("list_apps", "List applications in an organization.", { org: z.string().optional() }, async ({ org }) => {
|
|
256
|
+
tool("list_orgs", "List organizations the caller can access.", ro, {}, async () => (await getCtx().client.listOrgs()).orgs);
|
|
257
|
+
tool("list_apps", "List applications in an organization.", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
241
258
|
const ctx = getCtx();
|
|
242
259
|
const orgRef = await resolveOrg(ctx, org);
|
|
243
260
|
return (await ctx.client.listApps(orgRef.id)).apps;
|
|
244
261
|
});
|
|
245
|
-
tool("list_envs", "List environments of an application.", {
|
|
262
|
+
tool("list_envs", "List environments of an application.", ro, {
|
|
246
263
|
org: z.string().optional(),
|
|
247
264
|
app: z.string()
|
|
248
265
|
}, async ({ org, app }) => {
|
|
@@ -253,7 +270,7 @@ async function runMcpServer(options = {}) {
|
|
|
253
270
|
if (!appRow) throw new Error(`no app "${app}" in ${orgRef.slug}`);
|
|
254
271
|
return (await ctx.client.listEnvs(orgRef.id, appRow.id)).environments;
|
|
255
272
|
});
|
|
256
|
-
tool("list_branches", "List ephemeral branch configs in an application (optionally just one environment's).", {
|
|
273
|
+
tool("list_branches", "List ephemeral branch configs in an application (optionally just one environment's).", ro, {
|
|
257
274
|
org: z.string().optional(),
|
|
258
275
|
app: z.string(),
|
|
259
276
|
env: z.string().optional()
|
|
@@ -271,12 +288,12 @@ async function runMcpServer(options = {}) {
|
|
|
271
288
|
});
|
|
272
289
|
return (await ctx.client.listBranches(parent.orgId, parent.envId)).branches;
|
|
273
290
|
});
|
|
274
|
-
tool("list_groups", "List shared groups (reusable secret bags) in an organization.", { org: z.string().optional() }, async ({ org }) => {
|
|
291
|
+
tool("list_groups", "List shared groups (reusable secret bags) in an organization.", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
275
292
|
const ctx = getCtx();
|
|
276
293
|
const orgRef = await resolveOrg(ctx, org);
|
|
277
294
|
return (await ctx.client.listGroups(orgRef.id)).groups;
|
|
278
295
|
});
|
|
279
|
-
tool("list_group_envs", "List a group's environments (per-slug value sets).", {
|
|
296
|
+
tool("list_group_envs", "List a group's environments (per-slug value sets).", ro, {
|
|
280
297
|
org: z.string().optional(),
|
|
281
298
|
group: z.string()
|
|
282
299
|
}, async ({ org, group }) => {
|
|
@@ -287,7 +304,7 @@ async function runMcpServer(options = {}) {
|
|
|
287
304
|
});
|
|
288
305
|
return (await ctx.client.listGroupEnvs(g.orgId, g.id)).environments;
|
|
289
306
|
});
|
|
290
|
-
tool("list_env_groups", "List the groups composed into an application environment (precedence order).", {
|
|
307
|
+
tool("list_env_groups", "List the groups composed into an application environment (precedence order).", ro, {
|
|
291
308
|
org: z.string().optional(),
|
|
292
309
|
app: z.string(),
|
|
293
310
|
env: z.string()
|
|
@@ -300,17 +317,17 @@ async function runMcpServer(options = {}) {
|
|
|
300
317
|
});
|
|
301
318
|
return (await ctx.client.listEnvGroups(target.orgId, target.envId)).groups;
|
|
302
319
|
});
|
|
303
|
-
tool("list_members", "List organization members and their public keys (for granting access).", { org: z.string().optional() }, async ({ org }) => {
|
|
320
|
+
tool("list_members", "List organization members and their public keys (for granting access).", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
304
321
|
const ctx = getCtx();
|
|
305
322
|
const orgRef = await resolveOrg(ctx, org);
|
|
306
323
|
return (await ctx.client.listMembers(orgRef.id)).members;
|
|
307
324
|
});
|
|
308
|
-
tool("kms_list_keys", "List managed KMS keys the caller can see (metadata only).", { org: z.string().optional() }, async ({ org }) => {
|
|
325
|
+
tool("kms_list_keys", "List managed KMS keys the caller can see (metadata only).", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
309
326
|
const ctx = getCtx();
|
|
310
327
|
const orgRef = await resolveOrg(ctx, org);
|
|
311
328
|
return (await ctx.client.listKmsKeys(orgRef.id)).keys;
|
|
312
329
|
});
|
|
313
|
-
tool("kms_create_key", "Create an org-scoped managed key. Material is generated locally and wrapped to each grantee (self plus any listed users/tokens); the server never sees it. Use the CLI for app/group-scoped keys.", {
|
|
330
|
+
tool("kms_create_key", "Create an org-scoped managed key. Material is generated locally and wrapped to each grantee (self plus any listed users/tokens); the server never sees it. Use the CLI for app/group-scoped keys.", { idempotent: false }, {
|
|
314
331
|
org: z.string().optional(),
|
|
315
332
|
name: z.string(),
|
|
316
333
|
purpose: z.enum(["encrypt", "sign"]),
|
|
@@ -351,7 +368,7 @@ async function runMcpServer(options = {}) {
|
|
|
351
368
|
});
|
|
352
369
|
return key;
|
|
353
370
|
});
|
|
354
|
-
tool("kms_grant", "Grant a principal (user email or token id) use of a key's current version.", {
|
|
371
|
+
tool("kms_grant", "Grant a principal (user email or token id) use of a key's current version.", { idempotent: true }, {
|
|
355
372
|
org: z.string().optional(),
|
|
356
373
|
key: z.string(),
|
|
357
374
|
user: z.string().optional(),
|
|
@@ -376,7 +393,7 @@ async function runMcpServer(options = {}) {
|
|
|
376
393
|
key: k.name
|
|
377
394
|
};
|
|
378
395
|
});
|
|
379
|
-
tool("kms_encrypt", "Encrypt a value under a managed encrypt key; returns a ce1 ciphertext blob. `context` (if given) is bound as AAD and must be supplied identically to decrypt.", {
|
|
396
|
+
tool("kms_encrypt", "Encrypt a value under a managed encrypt key; returns a ce1 ciphertext blob. `context` (if given) is bound as AAD and must be supplied identically to decrypt.", { readOnly: true }, {
|
|
380
397
|
org: z.string().optional(),
|
|
381
398
|
key: z.string(),
|
|
382
399
|
plaintext: z.string(),
|
|
@@ -393,7 +410,7 @@ async function runMcpServer(options = {}) {
|
|
|
393
410
|
version: currentVersion
|
|
394
411
|
}, plaintext, context ?? "") };
|
|
395
412
|
});
|
|
396
|
-
tool("kms_decrypt", "Decrypt a ce1 blob. Supply the same `context` used to encrypt.", {
|
|
413
|
+
tool("kms_decrypt", "Decrypt a ce1 blob. Supply the same `context` used to encrypt.", ro, {
|
|
397
414
|
org: z.string().optional(),
|
|
398
415
|
key: z.string(),
|
|
399
416
|
ciphertext: z.string(),
|
|
@@ -407,7 +424,7 @@ async function runMcpServer(options = {}) {
|
|
|
407
424
|
const { material } = await kmsRecoverMaterial(ctx, orgRef.id, k.id, ref.version);
|
|
408
425
|
return { plaintext: await kmsDecrypt(material, ciphertext, context ?? "") };
|
|
409
426
|
});
|
|
410
|
-
tool("kms_generate_data_key", "Generate a data key under a managed encrypt key (envelope encryption). Returns the plaintext key (base64) and its wrapped form to store.", {
|
|
427
|
+
tool("kms_generate_data_key", "Generate a data key under a managed encrypt key (envelope encryption). Returns the plaintext key (base64) and its wrapped form to store.", { readOnly: true }, {
|
|
411
428
|
org: z.string().optional(),
|
|
412
429
|
key: z.string()
|
|
413
430
|
}, async ({ org, key }) => {
|
|
@@ -426,7 +443,7 @@ async function runMcpServer(options = {}) {
|
|
|
426
443
|
wrapped: dk.wrapped
|
|
427
444
|
};
|
|
428
445
|
});
|
|
429
|
-
tool("kms_sign", "Sign a message with a managed signing key; returns an sg1 signature blob.", {
|
|
446
|
+
tool("kms_sign", "Sign a message with a managed signing key; returns an sg1 signature blob.", { readOnly: true }, {
|
|
430
447
|
org: z.string().optional(),
|
|
431
448
|
key: z.string(),
|
|
432
449
|
message: z.string()
|
|
@@ -442,7 +459,7 @@ async function runMcpServer(options = {}) {
|
|
|
442
459
|
version: currentVersion
|
|
443
460
|
}, message) };
|
|
444
461
|
});
|
|
445
|
-
tool("kms_verify", "Verify an sg1 signature over a message using a signing key's published public key (no grant needed).", {
|
|
462
|
+
tool("kms_verify", "Verify an sg1 signature over a message using a signing key's published public key (no grant needed).", ro, {
|
|
446
463
|
org: z.string().optional(),
|
|
447
464
|
key: z.string(),
|
|
448
465
|
signature: z.string(),
|
|
@@ -457,7 +474,7 @@ async function runMcpServer(options = {}) {
|
|
|
457
474
|
if (!pub) throw new Error(`no published public key for version ${ref.version}`);
|
|
458
475
|
return { valid: await verifyMessage(await importVerifyingKey(pub), signature, message) };
|
|
459
476
|
});
|
|
460
|
-
tool("list_secrets", "List secret names + versions in an environment (never values).", targetShape, async (o) => {
|
|
477
|
+
tool("list_secrets", "List secret names + versions in an environment (never values).", ro, targetShape, async (o) => {
|
|
461
478
|
const ctx = getCtx();
|
|
462
479
|
const { orgId, envId } = await resolveTargetEnv(ctx, o);
|
|
463
480
|
const { secrets } = await ctx.client.listSecrets(orgId, envId);
|
|
@@ -467,12 +484,12 @@ async function runMcpServer(options = {}) {
|
|
|
467
484
|
updatedAt: s.updatedAt
|
|
468
485
|
}));
|
|
469
486
|
});
|
|
470
|
-
tool("list_tokens", "List an organization's service tokens (never the secret token strings).", { org: z.string().optional() }, async ({ org }) => {
|
|
487
|
+
tool("list_tokens", "List an organization's service tokens (never the secret token strings).", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
471
488
|
const ctx = getCtx();
|
|
472
489
|
const orgRef = await resolveOrg(ctx, org);
|
|
473
490
|
return (await ctx.client.listTokens(orgRef.id)).tokens;
|
|
474
491
|
});
|
|
475
|
-
tool("audit", "Read the organization's audit trail (most recent first).", {
|
|
492
|
+
tool("audit", "Read the organization's audit trail (most recent first).", ro, {
|
|
476
493
|
org: z.string().optional(),
|
|
477
494
|
limit: z.number().int().min(1).max(200).optional(),
|
|
478
495
|
action: z.string().optional().describe("filter by action, e.g. secret.updated")
|
|
@@ -484,14 +501,14 @@ async function runMcpServer(options = {}) {
|
|
|
484
501
|
action
|
|
485
502
|
})).entries;
|
|
486
503
|
});
|
|
487
|
-
tool("create_org", "Create an organization. Requires a user session — service tokens cannot own a Stytch org.", {
|
|
504
|
+
tool("create_org", "Create an organization. Requires a user session — service tokens cannot own a Stytch org.", { idempotent: false }, {
|
|
488
505
|
name: z.string(),
|
|
489
506
|
slug: z.string()
|
|
490
507
|
}, async ({ name, slug }) => (await getCtx().client.createOrg({
|
|
491
508
|
name,
|
|
492
509
|
slug
|
|
493
510
|
})).org);
|
|
494
|
-
tool("create_app", "Create an application in an organization.", {
|
|
511
|
+
tool("create_app", "Create an application in an organization.", { idempotent: false }, {
|
|
495
512
|
org: z.string().optional(),
|
|
496
513
|
name: z.string(),
|
|
497
514
|
slug: z.string()
|
|
@@ -503,7 +520,7 @@ async function runMcpServer(options = {}) {
|
|
|
503
520
|
slug
|
|
504
521
|
})).app;
|
|
505
522
|
});
|
|
506
|
-
tool("create_group", "Create a shared group (reusable secret bag) in an organization.", {
|
|
523
|
+
tool("create_group", "Create a shared group (reusable secret bag) in an organization.", { idempotent: false }, {
|
|
507
524
|
org: z.string().optional(),
|
|
508
525
|
name: z.string(),
|
|
509
526
|
slug: z.string()
|
|
@@ -515,7 +532,7 @@ async function runMcpServer(options = {}) {
|
|
|
515
532
|
slug
|
|
516
533
|
})).group;
|
|
517
534
|
});
|
|
518
|
-
tool("create_env", "Create an application environment. Generates the data key locally and grants it to the caller.", {
|
|
535
|
+
tool("create_env", "Create an application environment. Generates the data key locally and grants it to the caller.", { idempotent: false }, {
|
|
519
536
|
org: z.string().optional(),
|
|
520
537
|
app: z.string(),
|
|
521
538
|
name: z.string(),
|
|
@@ -533,7 +550,7 @@ async function runMcpServer(options = {}) {
|
|
|
533
550
|
wrappedDek
|
|
534
551
|
})).environment;
|
|
535
552
|
});
|
|
536
|
-
tool("create_branch", "Fork an environment into an ephemeral branch (a per-PR / preview config). The branch inherits the parent's secrets by layering at read time — nothing is copied or re-encrypted — and holds only the values you override on it. Generates the branch's data key locally, grants it to the caller, and shares it with the parent's other readers.", {
|
|
553
|
+
tool("create_branch", "Fork an environment into an ephemeral branch (a per-PR / preview config). The branch inherits the parent's secrets by layering at read time — nothing is copied or re-encrypted — and holds only the values you override on it. Generates the branch's data key locally, grants it to the caller, and shares it with the parent's other readers.", { idempotent: false }, {
|
|
537
554
|
org: z.string().optional(),
|
|
538
555
|
app: z.string(),
|
|
539
556
|
from: z.string().describe("the environment to branch"),
|
|
@@ -568,7 +585,7 @@ async function runMcpServer(options = {}) {
|
|
|
568
585
|
grants
|
|
569
586
|
})).branch;
|
|
570
587
|
});
|
|
571
|
-
tool("delete_branch", "Tear down a branch config and every value it overrode. The parent environment is untouched.", {
|
|
588
|
+
tool("delete_branch", "Tear down a branch config and every value it overrode. The parent environment is untouched.", destructive, {
|
|
572
589
|
org: z.string().optional(),
|
|
573
590
|
app: z.string(),
|
|
574
591
|
branch: z.string()
|
|
@@ -582,7 +599,7 @@ async function runMcpServer(options = {}) {
|
|
|
582
599
|
await ctx.client.deleteBranch(appRef.orgId, target.id);
|
|
583
600
|
return { deleted: target.slug };
|
|
584
601
|
});
|
|
585
|
-
tool("create_group_env", "Create a group environment. Generates the data key locally and grants it to the caller.", {
|
|
602
|
+
tool("create_group_env", "Create a group environment. Generates the data key locally and grants it to the caller.", { idempotent: false }, {
|
|
586
603
|
org: z.string().optional(),
|
|
587
604
|
group: z.string(),
|
|
588
605
|
name: z.string(),
|
|
@@ -600,7 +617,7 @@ async function runMcpServer(options = {}) {
|
|
|
600
617
|
wrappedDek
|
|
601
618
|
})).environment;
|
|
602
619
|
});
|
|
603
|
-
tool("compose_group", "Compose a group into an application environment (higher position wins on name clashes).", {
|
|
620
|
+
tool("compose_group", "Compose a group into an application environment (higher position wins on name clashes).", { idempotent: true }, {
|
|
604
621
|
org: z.string().optional(),
|
|
605
622
|
app: z.string(),
|
|
606
623
|
env: z.string(),
|
|
@@ -622,7 +639,7 @@ async function runMcpServer(options = {}) {
|
|
|
622
639
|
position
|
|
623
640
|
})).group;
|
|
624
641
|
});
|
|
625
|
-
tool("uncompose_group", "Remove a composed group from an application environment.", {
|
|
642
|
+
tool("uncompose_group", "Remove a composed group from an application environment.", { idempotent: true }, {
|
|
626
643
|
org: z.string().optional(),
|
|
627
644
|
app: z.string(),
|
|
628
645
|
env: z.string(),
|
|
@@ -641,7 +658,7 @@ async function runMcpServer(options = {}) {
|
|
|
641
658
|
await ctx.client.unlinkEnvGroup(target.orgId, target.envId, g.id);
|
|
642
659
|
return { ok: true };
|
|
643
660
|
});
|
|
644
|
-
tool("set_secret", "Encrypt a value locally and store it in an environment. A value may reference another secret as ${OTHER_SECRET}: the reference is stored literally and expanded whenever the secret is read, so it tracks the referenced value. Write $${OTHER_SECRET} for a literal.", {
|
|
661
|
+
tool("set_secret", "Encrypt a value locally and store it in an environment. A value may reference another secret as ${OTHER_SECRET}: the reference is stored literally and expanded whenever the secret is read, so it tracks the referenced value. Write $${OTHER_SECRET} for a literal.", { idempotent: false }, {
|
|
645
662
|
...targetShape,
|
|
646
663
|
name: z.string(),
|
|
647
664
|
value: z.string()
|
|
@@ -655,7 +672,7 @@ async function runMcpServer(options = {}) {
|
|
|
655
672
|
name: o.name
|
|
656
673
|
};
|
|
657
674
|
});
|
|
658
|
-
tool("get_secret", "Return one secret. By default only reports presence + version; pass reveal:true to decrypt the plaintext into this response (avoid unless the value is actually needed — prefer run_command). A revealed current value has its ${OTHER_SECRET} references expanded against this environment's own secrets; pass raw:true for the stored text instead. Pass `version` to read an earlier version instead of the current one (always as stored, never expanded).", {
|
|
675
|
+
tool("get_secret", "Return one secret. By default only reports presence + version; pass reveal:true to decrypt the plaintext into this response (avoid unless the value is actually needed — prefer run_command). A revealed current value has its ${OTHER_SECRET} references expanded against this environment's own secrets; pass raw:true for the stored text instead. Pass `version` to read an earlier version instead of the current one (always as stored, never expanded).", ro, {
|
|
659
676
|
...targetShape,
|
|
660
677
|
name: z.string(),
|
|
661
678
|
reveal: z.boolean().optional(),
|
|
@@ -692,7 +709,7 @@ async function runMcpServer(options = {}) {
|
|
|
692
709
|
revealed: true
|
|
693
710
|
};
|
|
694
711
|
});
|
|
695
|
-
tool("list_secret_versions", "List a secret's version history: who wrote each version, when, and which ones were restores. Never returns values — pair it with restore_secret to roll back, or get_secret(version, reveal:true) to inspect one.", {
|
|
712
|
+
tool("list_secret_versions", "List a secret's version history: who wrote each version, when, and which ones were restores. Never returns values — pair it with restore_secret to roll back, or get_secret(version, reveal:true) to inspect one.", ro, {
|
|
696
713
|
...targetShape,
|
|
697
714
|
name: z.string(),
|
|
698
715
|
limit: z.number().int().min(1).max(200).optional().describe("default 20")
|
|
@@ -710,7 +727,7 @@ async function runMcpServer(options = {}) {
|
|
|
710
727
|
}))
|
|
711
728
|
};
|
|
712
729
|
});
|
|
713
|
-
tool("restore_secret", "Roll a secret back to an earlier version. The stored ciphertext is replayed as a NEW version (history is append-only, nothing is overwritten). Keyless — no decryption happens, so this works even without a key.", {
|
|
730
|
+
tool("restore_secret", "Roll a secret back to an earlier version. The stored ciphertext is replayed as a NEW version (history is append-only, nothing is overwritten). Keyless — no decryption happens, so this works even without a key.", { idempotent: false }, {
|
|
714
731
|
...targetShape,
|
|
715
732
|
name: z.string(),
|
|
716
733
|
version: z.number().int().positive()
|
|
@@ -725,7 +742,7 @@ async function runMcpServer(options = {}) {
|
|
|
725
742
|
version: secret.version
|
|
726
743
|
};
|
|
727
744
|
});
|
|
728
|
-
tool("delete_secret", "Delete a secret from an environment.", {
|
|
745
|
+
tool("delete_secret", "Delete a secret from an environment.", destructive, {
|
|
729
746
|
...targetShape,
|
|
730
747
|
name: z.string()
|
|
731
748
|
}, async (o) => {
|
|
@@ -738,6 +755,9 @@ async function runMcpServer(options = {}) {
|
|
|
738
755
|
};
|
|
739
756
|
});
|
|
740
757
|
tool("run_command", "Run a command with the resolved secrets injected as environment variables, and return its exit code + captured output. Secret VALUES are never returned — this is the preferred way to use secrets. process env > .env > app env > groups.", {
|
|
758
|
+
destructive: true,
|
|
759
|
+
idempotent: false
|
|
760
|
+
}, {
|
|
741
761
|
command: z.string().describe("executable to run"),
|
|
742
762
|
args: z.array(z.string()).optional(),
|
|
743
763
|
org: z.string().optional(),
|
|
@@ -760,7 +780,7 @@ async function runMcpServer(options = {}) {
|
|
|
760
780
|
injectedVarCount: Object.keys(values).length
|
|
761
781
|
};
|
|
762
782
|
});
|
|
763
|
-
tool("export_env", "Write the resolved secrets to a dotenv file on disk and return the variable names written (never the values). Use to materialize a .env for local tooling.", {
|
|
783
|
+
tool("export_env", "Write the resolved secrets to a dotenv file on disk and return the variable names written (never the values). Use to materialize a .env for local tooling.", destructive, {
|
|
764
784
|
file: z.string().describe("path to write, e.g. .env"),
|
|
765
785
|
org: z.string().optional(),
|
|
766
786
|
app: z.string().optional(),
|
|
@@ -779,7 +799,7 @@ async function runMcpServer(options = {}) {
|
|
|
779
799
|
names: Object.keys(values).sort()
|
|
780
800
|
};
|
|
781
801
|
});
|
|
782
|
-
tool("create_token", "Mint a service token, printed once. Runtime tokens bind to one app environment (auto-granted its keys, so a command/agent can decrypt it). Pass admin:true for an org-scoped provisioning token (create apps/groups/envs, grant, mint tokens) — admin tokens need no env binding.", {
|
|
802
|
+
tool("create_token", "Mint a service token, printed once. Runtime tokens bind to one app environment (auto-granted its keys, so a command/agent can decrypt it). Pass admin:true for an org-scoped provisioning token (create apps/groups/envs, grant, mint tokens) — admin tokens need no env binding.", { idempotent: false }, {
|
|
783
803
|
name: z.string().describe("display name, e.g. ci-deploy or agent-session"),
|
|
784
804
|
org: z.string().optional(),
|
|
785
805
|
app: z.string().optional().describe("bind to this app (runtime tokens)"),
|
|
@@ -830,7 +850,7 @@ async function runMcpServer(options = {}) {
|
|
|
830
850
|
note: "save this now — the secret token string is not stored and cannot be retrieved"
|
|
831
851
|
};
|
|
832
852
|
});
|
|
833
|
-
tool("revoke_token", "Revoke a service token by id.", {
|
|
853
|
+
tool("revoke_token", "Revoke a service token by id.", destructive, {
|
|
834
854
|
org: z.string().optional(),
|
|
835
855
|
tokenId: z.string()
|
|
836
856
|
}, async ({ org, tokenId }) => {
|
|
@@ -842,7 +862,7 @@ async function runMcpServer(options = {}) {
|
|
|
842
862
|
tokenId
|
|
843
863
|
};
|
|
844
864
|
});
|
|
845
|
-
tool("grant_env", "Grant a member (by email) or service token (by id) access to an environment's data key. Re-wraps the DEK to the grantee — the caller must already hold the key.", {
|
|
865
|
+
tool("grant_env", "Grant a member (by email) or service token (by id) access to an environment's data key. Re-wraps the DEK to the grantee — the caller must already hold the key.", { idempotent: true }, {
|
|
846
866
|
...targetShape,
|
|
847
867
|
user: z.string().optional().describe("org member email"),
|
|
848
868
|
token: z.string().optional().describe("service token id (skt_…)")
|
|
@@ -887,12 +907,12 @@ async function runMcpServer(options = {}) {
|
|
|
887
907
|
principalId
|
|
888
908
|
};
|
|
889
909
|
});
|
|
890
|
-
tool("list_pg_targets", "List registered Postgres provisioning targets for temporary credentials.", { org: z.string().optional() }, async ({ org }) => {
|
|
910
|
+
tool("list_pg_targets", "List registered Postgres provisioning targets for temporary credentials.", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
891
911
|
const ctx = getCtx();
|
|
892
912
|
const orgRef = await resolveOrg(ctx, org);
|
|
893
913
|
return (await ctx.client.listLeaseTargets(orgRef.id)).targets;
|
|
894
914
|
});
|
|
895
|
-
tool("create_pg_lease", "Mint a short-lived Postgres credential against a target and return a ready-to-use connection URL. The password is generated on THIS machine and only its SCRAM verifier is sent to the API — the plaintext never reaches seekrit or Postgres at rest. The role auto-expires; revoke early with revoke_pg_lease.", {
|
|
915
|
+
tool("create_pg_lease", "Mint a short-lived Postgres credential against a target and return a ready-to-use connection URL. The password is generated on THIS machine and only its SCRAM verifier is sent to the API — the plaintext never reaches seekrit or Postgres at rest. The role auto-expires; revoke early with revoke_pg_lease.", { idempotent: false }, {
|
|
896
916
|
org: z.string().optional(),
|
|
897
917
|
target: z.string().describe("target id or name"),
|
|
898
918
|
role: z.string().optional().describe("role name to create (default: random tmp_ name)"),
|
|
@@ -921,12 +941,12 @@ async function runMcpServer(options = {}) {
|
|
|
921
941
|
note: "short-lived credential; it auto-expires and the plaintext is not stored anywhere"
|
|
922
942
|
};
|
|
923
943
|
});
|
|
924
|
-
tool("list_pg_leases", "List Postgres leases (the ledger — never secret material).", { org: z.string().optional() }, async ({ org }) => {
|
|
944
|
+
tool("list_pg_leases", "List Postgres leases (the ledger — never secret material).", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
925
945
|
const ctx = getCtx();
|
|
926
946
|
const orgRef = await resolveOrg(ctx, org);
|
|
927
947
|
return (await ctx.client.listLeases(orgRef.id)).leases;
|
|
928
948
|
});
|
|
929
|
-
tool("revoke_pg_lease", "Revoke a Postgres lease now (drops the role immediately).", {
|
|
949
|
+
tool("revoke_pg_lease", "Revoke a Postgres lease now (drops the role immediately).", destructive, {
|
|
930
950
|
org: z.string().optional(),
|
|
931
951
|
leaseId: z.string()
|
|
932
952
|
}, async ({ org, leaseId }) => {
|
|
@@ -938,12 +958,12 @@ async function runMcpServer(options = {}) {
|
|
|
938
958
|
leaseId
|
|
939
959
|
};
|
|
940
960
|
});
|
|
941
|
-
tool("list_mysql_targets", "List registered MySQL/MariaDB provisioning targets for temporary credentials.", { org: z.string().optional() }, async ({ org }) => {
|
|
961
|
+
tool("list_mysql_targets", "List registered MySQL/MariaDB provisioning targets for temporary credentials.", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
942
962
|
const ctx = getCtx();
|
|
943
963
|
const orgRef = await resolveOrg(ctx, org);
|
|
944
964
|
return (await ctx.client.listLeaseTargets(orgRef.id)).targets.filter((t) => t.provider === "mysql");
|
|
945
965
|
});
|
|
946
|
-
tool("create_mysql_lease", "Mint a short-lived MySQL/MariaDB credential against a target and return a ready-to-use connection URL. The password is generated on THIS machine and only its mysql_native_password hash is sent to the API — the plaintext never reaches seekrit or MySQL at rest. The user auto-expires; revoke early with revoke_mysql_lease.", {
|
|
966
|
+
tool("create_mysql_lease", "Mint a short-lived MySQL/MariaDB credential against a target and return a ready-to-use connection URL. The password is generated on THIS machine and only its mysql_native_password hash is sent to the API — the plaintext never reaches seekrit or MySQL at rest. The user auto-expires; revoke early with revoke_mysql_lease.", { idempotent: false }, {
|
|
947
967
|
org: z.string().optional(),
|
|
948
968
|
target: z.string().describe("target id or name"),
|
|
949
969
|
user: z.string().optional().describe("user name to create (default: random tmp_ name)"),
|
|
@@ -973,12 +993,12 @@ async function runMcpServer(options = {}) {
|
|
|
973
993
|
note: "short-lived credential; it auto-expires and the plaintext is not stored anywhere"
|
|
974
994
|
};
|
|
975
995
|
});
|
|
976
|
-
tool("list_mysql_leases", "List MySQL/MariaDB leases (the ledger — never secret material).", { org: z.string().optional() }, async ({ org }) => {
|
|
996
|
+
tool("list_mysql_leases", "List MySQL/MariaDB leases (the ledger — never secret material).", ro, { org: z.string().optional() }, async ({ org }) => {
|
|
977
997
|
const ctx = getCtx();
|
|
978
998
|
const orgRef = await resolveOrg(ctx, org);
|
|
979
999
|
return (await ctx.client.listLeases(orgRef.id)).leases.filter((l) => l.provider === "mysql");
|
|
980
1000
|
});
|
|
981
|
-
tool("revoke_mysql_lease", "Revoke a MySQL/MariaDB lease now (drops the user immediately).", {
|
|
1001
|
+
tool("revoke_mysql_lease", "Revoke a MySQL/MariaDB lease now (drops the user immediately).", destructive, {
|
|
982
1002
|
org: z.string().optional(),
|
|
983
1003
|
leaseId: z.string()
|
|
984
1004
|
}, async ({ org, leaseId }) => {
|
|
@@ -990,7 +1010,7 @@ async function runMcpServer(options = {}) {
|
|
|
990
1010
|
leaseId
|
|
991
1011
|
};
|
|
992
1012
|
});
|
|
993
|
-
tool("configure_project", "Link a directory to an org/app by writing seekrit.json (like `seekrit init`). The environment is chosen by the service token at runtime.", {
|
|
1013
|
+
tool("configure_project", "Link a directory to an org/app by writing seekrit.json (like `seekrit init`). The environment is chosen by the service token at runtime.", destructive, {
|
|
994
1014
|
org: z.string(),
|
|
995
1015
|
app: z.string(),
|
|
996
1016
|
dir: z.string().optional()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seekrit/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "End-to-end encrypted secrets manager CLI — inject decrypted secrets into any command.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"@types/node": "^26.1.0",
|
|
28
28
|
"tsdown": "^0.22.3",
|
|
29
29
|
"vitest": "^4.1.9",
|
|
30
|
-
"@seekrit/core": "0.0.1",
|
|
31
30
|
"@seekrit/api-client": "0.0.1",
|
|
31
|
+
"@seekrit/core": "0.0.1",
|
|
32
32
|
"@seekrit/crypto": "0.0.1"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|