@sanctuary-framework/mcp-server 1.1.2 → 1.1.3
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/cli.cjs +120 -34
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +125 -39
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +96 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +96 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import { fileURLToPath } from 'url';
|
|
|
19
19
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
20
20
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
21
21
|
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
22
|
-
import 'readline/promises';
|
|
22
|
+
import { createInterface } from 'readline/promises';
|
|
23
23
|
|
|
24
24
|
var __defProp = Object.defineProperty;
|
|
25
25
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -26355,14 +26355,41 @@ function createComplianceTools(deps) {
|
|
|
26355
26355
|
init_random();
|
|
26356
26356
|
init_encoding();
|
|
26357
26357
|
var RECOVERY_KEY_FILENAME = "recovery-key.txt";
|
|
26358
|
-
|
|
26358
|
+
var RECOVERY_KEY_COPY = {
|
|
26359
|
+
fileName: RECOVERY_KEY_FILENAME,
|
|
26360
|
+
bannerHeader: "SANCTUARY: First Run, Recovery Key Generated",
|
|
26361
|
+
bannerSecretLabel: "Recovery Key",
|
|
26362
|
+
bannerSaveLine: "SAVE THIS KEY. It will not be shown again.",
|
|
26363
|
+
bannerLossLine: "Without it, your encrypted state is unrecoverable.",
|
|
26364
|
+
fileWarningHeader: "SANCTUARY RECOVERY KEY, DO NOT COMMIT, DO NOT EMAIL, MOVE OFF-HOST IMMEDIATELY.",
|
|
26365
|
+
fileSecretLabel: "Recovery key:",
|
|
26366
|
+
fileBody: "This file was created on first init. Sanctuary will NOT regenerate this file on\nsubsequent runs and will NOT display the key again. After moving this file off\nthe host (encrypted backup, password manager, paper safe), delete it from the\nfortress directory. Do NOT keep it in the fortress; the recovery key bypasses\nthe cocoon passphrase by design.\n",
|
|
26367
|
+
promptLabel: "recovery key"
|
|
26368
|
+
};
|
|
26369
|
+
var RecoveryKeyConfirmationDeclinedError = class extends Error {
|
|
26370
|
+
constructor() {
|
|
26371
|
+
super(
|
|
26372
|
+
"Recovery key confirmation declined. Save the recovery key (printed above and written to recovery-key.txt) before re-running init."
|
|
26373
|
+
);
|
|
26374
|
+
this.name = "RecoveryKeyConfirmationDeclinedError";
|
|
26375
|
+
}
|
|
26376
|
+
};
|
|
26377
|
+
var RecoveryKeyConfirmationNonInteractiveError = class extends Error {
|
|
26378
|
+
constructor() {
|
|
26379
|
+
super(
|
|
26380
|
+
"Recovery key confirmation requires an interactive terminal. Re-run with --no-confirm for CI/scripted use, or run from a TTY."
|
|
26381
|
+
);
|
|
26382
|
+
this.name = "RecoveryKeyConfirmationNonInteractiveError";
|
|
26383
|
+
}
|
|
26384
|
+
};
|
|
26385
|
+
function printSecretBanner(secret, filePath, copy, output = process.stderr) {
|
|
26359
26386
|
const lines = [
|
|
26360
|
-
|
|
26387
|
+
copy.bannerHeader,
|
|
26361
26388
|
"",
|
|
26362
|
-
|
|
26389
|
+
`${copy.bannerSecretLabel}: ${secret}`,
|
|
26363
26390
|
"",
|
|
26364
|
-
|
|
26365
|
-
|
|
26391
|
+
copy.bannerSaveLine,
|
|
26392
|
+
copy.bannerLossLine,
|
|
26366
26393
|
"",
|
|
26367
26394
|
"Plaintext copy written to:",
|
|
26368
26395
|
` ${filePath}`,
|
|
@@ -26381,8 +26408,8 @@ ${bottom}
|
|
|
26381
26408
|
|
|
26382
26409
|
`);
|
|
26383
26410
|
}
|
|
26384
|
-
async function
|
|
26385
|
-
const filePath = join(opts.storagePath,
|
|
26411
|
+
async function writeSecretFile(opts) {
|
|
26412
|
+
const filePath = join(opts.storagePath, opts.copy.fileName);
|
|
26386
26413
|
try {
|
|
26387
26414
|
await access(filePath, constants.F_OK);
|
|
26388
26415
|
return { filePath, written: false };
|
|
@@ -26392,40 +26419,76 @@ async function writeRecoveryKeyFile(opts) {
|
|
|
26392
26419
|
const now = (opts.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
|
|
26393
26420
|
const fortressLine = opts.fortressId ? `Fortress: ${opts.fortressId}
|
|
26394
26421
|
` : "";
|
|
26395
|
-
const content =
|
|
26422
|
+
const content = `${opts.copy.fileWarningHeader}
|
|
26396
26423
|
Generated: ${now}
|
|
26397
26424
|
` + fortressLine + `
|
|
26398
|
-
|
|
26399
|
-
${opts.
|
|
26400
|
-
|
|
26401
|
-
|
|
26402
|
-
subsequent runs and will NOT display the key again. After moving this file off
|
|
26403
|
-
the host (encrypted backup, password manager, paper safe), delete it from the
|
|
26404
|
-
fortress directory. Do NOT keep it in the fortress; the recovery key bypasses
|
|
26405
|
-
the cocoon passphrase by design.
|
|
26406
|
-
`;
|
|
26425
|
+
${opts.copy.fileSecretLabel}
|
|
26426
|
+
${opts.secret}
|
|
26427
|
+
|
|
26428
|
+
` + opts.copy.fileBody;
|
|
26407
26429
|
await writeFile(filePath, content, { mode: 384 });
|
|
26408
26430
|
return { filePath, written: true };
|
|
26409
26431
|
}
|
|
26410
|
-
async function
|
|
26411
|
-
const
|
|
26432
|
+
async function confirmSecretSaved(copy, declinedError, nonInteractiveError, io) {
|
|
26433
|
+
const input = io?.input ?? process.stdin;
|
|
26434
|
+
const output = io?.output ?? process.stderr;
|
|
26435
|
+
const realStdin = !io && process.stdin.isTTY !== true;
|
|
26436
|
+
if (realStdin) {
|
|
26437
|
+
throw new nonInteractiveError();
|
|
26438
|
+
}
|
|
26439
|
+
const rl = createInterface({ input, output });
|
|
26440
|
+
try {
|
|
26441
|
+
const answer = await rl.question(
|
|
26442
|
+
`Have you saved the ${copy.promptLabel}? [y/N] `
|
|
26443
|
+
);
|
|
26444
|
+
const normalized = answer.trim().toLowerCase();
|
|
26445
|
+
if (normalized !== "y" && normalized !== "yes") {
|
|
26446
|
+
throw new declinedError();
|
|
26447
|
+
}
|
|
26448
|
+
} finally {
|
|
26449
|
+
rl.close();
|
|
26450
|
+
}
|
|
26451
|
+
}
|
|
26452
|
+
async function discloseSecret(opts, copy, declinedError, nonInteractiveError) {
|
|
26453
|
+
const mode = opts.mode ?? "interactive";
|
|
26454
|
+
const writeOpts = {
|
|
26412
26455
|
storagePath: opts.storagePath,
|
|
26413
|
-
|
|
26414
|
-
|
|
26415
|
-
|
|
26416
|
-
|
|
26417
|
-
|
|
26418
|
-
|
|
26419
|
-
|
|
26420
|
-
|
|
26421
|
-
);
|
|
26422
|
-
{
|
|
26456
|
+
secret: opts.secret,
|
|
26457
|
+
copy
|
|
26458
|
+
};
|
|
26459
|
+
if (opts.fortressId !== void 0) writeOpts.fortressId = opts.fortressId;
|
|
26460
|
+
if (opts.now !== void 0) writeOpts.now = opts.now;
|
|
26461
|
+
const fileResult = await writeSecretFile(writeOpts);
|
|
26462
|
+
printSecretBanner(opts.secret, fileResult.filePath, copy, opts.io?.output);
|
|
26463
|
+
if (mode === "no-confirm" || mode === "stdio-server") {
|
|
26423
26464
|
return {
|
|
26424
26465
|
filePath: fileResult.filePath,
|
|
26425
26466
|
fileWritten: fileResult.written,
|
|
26426
26467
|
confirmed: false
|
|
26427
26468
|
};
|
|
26428
26469
|
}
|
|
26470
|
+
await confirmSecretSaved(copy, declinedError, nonInteractiveError, opts.io);
|
|
26471
|
+
return {
|
|
26472
|
+
filePath: fileResult.filePath,
|
|
26473
|
+
fileWritten: fileResult.written,
|
|
26474
|
+
confirmed: true
|
|
26475
|
+
};
|
|
26476
|
+
}
|
|
26477
|
+
async function discloseRecoveryKey(opts) {
|
|
26478
|
+
const internalOpts = {
|
|
26479
|
+
secret: opts.recoveryKey,
|
|
26480
|
+
storagePath: opts.storagePath
|
|
26481
|
+
};
|
|
26482
|
+
if (opts.fortressId !== void 0) internalOpts.fortressId = opts.fortressId;
|
|
26483
|
+
if (opts.mode !== void 0) internalOpts.mode = opts.mode;
|
|
26484
|
+
if (opts.now !== void 0) internalOpts.now = opts.now;
|
|
26485
|
+
if (opts.io !== void 0) internalOpts.io = opts.io;
|
|
26486
|
+
return discloseSecret(
|
|
26487
|
+
internalOpts,
|
|
26488
|
+
RECOVERY_KEY_COPY,
|
|
26489
|
+
RecoveryKeyConfirmationDeclinedError,
|
|
26490
|
+
RecoveryKeyConfirmationNonInteractiveError
|
|
26491
|
+
);
|
|
26429
26492
|
}
|
|
26430
26493
|
|
|
26431
26494
|
// src/hub/agent-registry.ts
|
|
@@ -29565,7 +29628,9 @@ Refusing to start the cocoon while the reset-history marker is unreadable.`
|
|
|
29565
29628
|
if (recoveryKey) {
|
|
29566
29629
|
await discloseRecoveryKey({
|
|
29567
29630
|
recoveryKey,
|
|
29568
|
-
storagePath: config.storage_path
|
|
29631
|
+
storagePath: config.storage_path,
|
|
29632
|
+
mode: "stdio-server"
|
|
29633
|
+
});
|
|
29569
29634
|
}
|
|
29570
29635
|
return {
|
|
29571
29636
|
server,
|