@sanctuary-framework/mcp-server 1.1.3 → 1.1.5
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 +197 -6
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +198 -7
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +25 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -5
- package/dist/index.d.ts +8 -5
- package/dist/index.js +26 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -13357,7 +13357,7 @@ function renderDashboardV11Html(options = {}) {
|
|
|
13357
13357
|
streamUrl,
|
|
13358
13358
|
identityId,
|
|
13359
13359
|
fortressId
|
|
13360
|
-
});
|
|
13360
|
+
}).replace(/</g, "\\u003c");
|
|
13361
13361
|
const clientBlock = embedClient ? `<script type="module">${getClientScript()}</script>` : `<!-- client script omitted by render option -->`;
|
|
13362
13362
|
return `<!doctype html>
|
|
13363
13363
|
<html lang="en">
|
|
@@ -13388,7 +13388,7 @@ function renderDashboardV11Html(options = {}) {
|
|
|
13388
13388
|
<aside class="fortress" id="fortress"><p class="muted">Loading fortress column.</p></aside>
|
|
13389
13389
|
</div>
|
|
13390
13390
|
<div id="toast-host" aria-live="polite"></div>
|
|
13391
|
-
<script id="dashboard-config" type="application/json">${
|
|
13391
|
+
<script id="dashboard-config" type="application/json">${config}</script>
|
|
13392
13392
|
${clientBlock}
|
|
13393
13393
|
</body>
|
|
13394
13394
|
</html>`;
|
|
@@ -28583,8 +28583,69 @@ var init_hub = __esm({
|
|
|
28583
28583
|
init_api_router();
|
|
28584
28584
|
}
|
|
28585
28585
|
});
|
|
28586
|
+
function localAgentsFilePath(storagePath) {
|
|
28587
|
+
return path.join(storagePath, "state", "_hub", "local-agents.json");
|
|
28588
|
+
}
|
|
28589
|
+
function readPersistedLocalAgents(storagePath) {
|
|
28590
|
+
const filePath = localAgentsFilePath(storagePath);
|
|
28591
|
+
if (!fs.existsSync(filePath)) return [];
|
|
28592
|
+
try {
|
|
28593
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
28594
|
+
const parsed = JSON.parse(raw);
|
|
28595
|
+
if (!parsed || !Array.isArray(parsed.agents)) return [];
|
|
28596
|
+
return parsed.agents;
|
|
28597
|
+
} catch {
|
|
28598
|
+
return [];
|
|
28599
|
+
}
|
|
28600
|
+
}
|
|
28601
|
+
function writePersistedLocalAgents(storagePath, agents) {
|
|
28602
|
+
const filePath = localAgentsFilePath(storagePath);
|
|
28603
|
+
const dir = path.dirname(filePath);
|
|
28604
|
+
fs.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
28605
|
+
const payload = {
|
|
28606
|
+
version: PERSISTED_VERSION,
|
|
28607
|
+
agents
|
|
28608
|
+
};
|
|
28609
|
+
const tmpPath = `${filePath}.tmp`;
|
|
28610
|
+
fs.writeFileSync(tmpPath, `${JSON.stringify(payload, null, 2)}
|
|
28611
|
+
`, {
|
|
28612
|
+
mode: 384
|
|
28613
|
+
});
|
|
28614
|
+
fs.renameSync(tmpPath, filePath);
|
|
28615
|
+
fs.chmodSync(filePath, 384);
|
|
28616
|
+
}
|
|
28617
|
+
function upsertPersistedLocalAgent(storagePath, record) {
|
|
28618
|
+
const existing = readPersistedLocalAgents(storagePath);
|
|
28619
|
+
const idx = existing.findIndex((r) => r.agent_id === record.agent_id);
|
|
28620
|
+
let next;
|
|
28621
|
+
if (idx >= 0) {
|
|
28622
|
+
const prior = existing[idx];
|
|
28623
|
+
if (prior === void 0) {
|
|
28624
|
+
next = [...existing, record];
|
|
28625
|
+
} else {
|
|
28626
|
+
const updated = {
|
|
28627
|
+
...record,
|
|
28628
|
+
wrapped_at: prior.wrapped_at,
|
|
28629
|
+
last_activity_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
28630
|
+
};
|
|
28631
|
+
next = [...existing];
|
|
28632
|
+
next[idx] = updated;
|
|
28633
|
+
}
|
|
28634
|
+
} else {
|
|
28635
|
+
next = [...existing, record];
|
|
28636
|
+
}
|
|
28637
|
+
writePersistedLocalAgents(storagePath, next);
|
|
28638
|
+
return next;
|
|
28639
|
+
}
|
|
28640
|
+
var PERSISTED_VERSION;
|
|
28641
|
+
var init_agent_registry_persistence = __esm({
|
|
28642
|
+
"src/hub/agent-registry-persistence.ts"() {
|
|
28643
|
+
PERSISTED_VERSION = "1.1";
|
|
28644
|
+
}
|
|
28645
|
+
});
|
|
28586
28646
|
function buildV11Bindings(inputs) {
|
|
28587
|
-
const
|
|
28647
|
+
const seed = inputs.storagePath !== void 0 ? readPersistedLocalAgents(inputs.storagePath) : [];
|
|
28648
|
+
const registry = new InMemoryLocalAgentRegistry(seed);
|
|
28588
28649
|
const hubService = new HubService({
|
|
28589
28650
|
identityId: inputs.identityId,
|
|
28590
28651
|
fortressId: inputs.fortressId,
|
|
@@ -28622,6 +28683,7 @@ var init_wiring = __esm({
|
|
|
28622
28683
|
"src/dashboard/v1_1/wiring.ts"() {
|
|
28623
28684
|
init_hub();
|
|
28624
28685
|
init_errors4();
|
|
28686
|
+
init_agent_registry_persistence();
|
|
28625
28687
|
CapabilityErrorAgentController = class {
|
|
28626
28688
|
fail(action) {
|
|
28627
28689
|
throw new HubCapabilityError(
|
|
@@ -30654,7 +30716,12 @@ Refusing to start the cocoon while the reset-history marker is unreadable.`
|
|
|
30654
30716
|
buildV11Bindings({
|
|
30655
30717
|
identityId: embeddedHubIdentityId,
|
|
30656
30718
|
fortressId: fortressIdFromStoragePath(config.storage_path),
|
|
30657
|
-
auditLog
|
|
30719
|
+
auditLog,
|
|
30720
|
+
// v1.1.5 (Finding Z): rehydrate the hub agent registry from
|
|
30721
|
+
// `<storagePath>/state/_hub/local-agents.json` so the embedded
|
|
30722
|
+
// dashboard surfaces wraps performed by prior `sanctuary wrap`
|
|
30723
|
+
// invocations against this same fortress.
|
|
30724
|
+
storagePath: config.storage_path
|
|
30658
30725
|
})
|
|
30659
30726
|
);
|
|
30660
30727
|
await dashboard.start();
|
|
@@ -31297,6 +31364,7 @@ __export(cli_exports, {
|
|
|
31297
31364
|
PORT_FALLBACK_ATTEMPTS: () => PORT_FALLBACK_ATTEMPTS,
|
|
31298
31365
|
formatMcpServerCount: () => formatMcpServerCount,
|
|
31299
31366
|
formatWrapSuccess: () => formatWrapSuccess,
|
|
31367
|
+
formatWrapSuccessNoDashboard: () => formatWrapSuccessNoDashboard,
|
|
31300
31368
|
parseCocoonArgs: () => parseCocoonArgs,
|
|
31301
31369
|
parseWrapArgs: () => parseWrapArgs,
|
|
31302
31370
|
promoteFortressToStoragePath: () => promoteFortressToStoragePath,
|
|
@@ -31569,6 +31637,28 @@ async function runWrap(options, deps = {}) {
|
|
|
31569
31637
|
backupPath
|
|
31570
31638
|
);
|
|
31571
31639
|
if (!verifyOk) process.exit(1);
|
|
31640
|
+
try {
|
|
31641
|
+
upsertPersistedLocalAgent(
|
|
31642
|
+
storagePath,
|
|
31643
|
+
buildLocalAgentRecord({
|
|
31644
|
+
storagePath,
|
|
31645
|
+
platform: agentConfig.platform
|
|
31646
|
+
})
|
|
31647
|
+
);
|
|
31648
|
+
} catch (err) {
|
|
31649
|
+
console.error(
|
|
31650
|
+
` Note: v1.1 hub agent record not persisted (${err.message}). Re-run \`sanctuary wrap\` to retry, or check storage permissions on ${storagePath}.`
|
|
31651
|
+
);
|
|
31652
|
+
}
|
|
31653
|
+
if (options.noDashboard) {
|
|
31654
|
+
const toolName2 = toolNameFor(agentConfig.platform, agentConfig.servers);
|
|
31655
|
+
printWrapSuccessNoDashboard({
|
|
31656
|
+
toolName: toolName2,
|
|
31657
|
+
version: readPackageVersion(),
|
|
31658
|
+
toolCount: countUpstreamTools(upstreamServers),
|
|
31659
|
+
serverCount: upstreamServers.length});
|
|
31660
|
+
return;
|
|
31661
|
+
}
|
|
31572
31662
|
const authToken = generateAuthToken();
|
|
31573
31663
|
const startFn = deps.startDashboard ?? ((opts) => startDashboard({
|
|
31574
31664
|
port: opts.port,
|
|
@@ -31608,7 +31698,12 @@ async function runWrap(options, deps = {}) {
|
|
|
31608
31698
|
buildV11Bindings({
|
|
31609
31699
|
identityId: `fortress:${storagePath}`,
|
|
31610
31700
|
fortressId: fortressIdFromStoragePath(storagePath),
|
|
31611
|
-
auditLog: wrapAuditLog
|
|
31701
|
+
auditLog: wrapAuditLog,
|
|
31702
|
+
// v1.1.5 (Finding Z): rehydrate from the file the upsert
|
|
31703
|
+
// above just wrote, so the registry the wrap-auto dashboard
|
|
31704
|
+
// serves contains this wrap plus any prior wraps against the
|
|
31705
|
+
// same fortress.
|
|
31706
|
+
storagePath
|
|
31612
31707
|
})
|
|
31613
31708
|
);
|
|
31614
31709
|
dashboard.setV11LoopbackAutoAuth(true);
|
|
@@ -31748,6 +31843,32 @@ function formatWrapSuccess(info) {
|
|
|
31748
31843
|
function printWrapSuccess(info) {
|
|
31749
31844
|
console.error(formatWrapSuccess(info));
|
|
31750
31845
|
}
|
|
31846
|
+
function formatWrapSuccessNoDashboard(info) {
|
|
31847
|
+
const g = (s) => `\x1B[32m${s}\x1B[0m`;
|
|
31848
|
+
const d = (s) => `\x1B[2m${s}\x1B[0m`;
|
|
31849
|
+
const b = (s) => `\x1B[1m${s}\x1B[0m`;
|
|
31850
|
+
const check = "\u2713";
|
|
31851
|
+
const lines = [];
|
|
31852
|
+
lines.push("");
|
|
31853
|
+
lines.push(
|
|
31854
|
+
` ${g(check)} Wrapped ${b(info.toolName)} with Sanctuary v${info.version}`
|
|
31855
|
+
);
|
|
31856
|
+
lines.push(
|
|
31857
|
+
` ${g(check)} ${info.toolCount} tools registered across ${info.serverCount} upstream server${info.serverCount !== 1 ? "s" : ""}`
|
|
31858
|
+
);
|
|
31859
|
+
lines.push(
|
|
31860
|
+
` ${d("Dashboard spawn skipped per --no-dashboard. Run `sanctuary dashboard` separately for a persistent dashboard.")}`
|
|
31861
|
+
);
|
|
31862
|
+
lines.push("");
|
|
31863
|
+
lines.push(
|
|
31864
|
+
` ${b("Your agent is protected.")} L1 Full / L2 Degraded (no TEE) / L3 Full / L4 Full.`
|
|
31865
|
+
);
|
|
31866
|
+
lines.push("");
|
|
31867
|
+
return lines.join("\n");
|
|
31868
|
+
}
|
|
31869
|
+
function printWrapSuccessNoDashboard(info) {
|
|
31870
|
+
console.error(formatWrapSuccessNoDashboard(info));
|
|
31871
|
+
}
|
|
31751
31872
|
async function verifyRewrittenConfig(configPath, backupPath) {
|
|
31752
31873
|
try {
|
|
31753
31874
|
const raw = await promises.readFile(configPath, "utf-8");
|
|
@@ -31864,6 +31985,57 @@ function toolNameFor(platform4, _servers) {
|
|
|
31864
31985
|
return "your agent";
|
|
31865
31986
|
}
|
|
31866
31987
|
}
|
|
31988
|
+
function harnessKindForPlatform(platform4) {
|
|
31989
|
+
switch (platform4) {
|
|
31990
|
+
case "openclaw":
|
|
31991
|
+
return "openclaw";
|
|
31992
|
+
case "hermes":
|
|
31993
|
+
return "hermes";
|
|
31994
|
+
case "claude-code":
|
|
31995
|
+
return "claude_code";
|
|
31996
|
+
case "cursor":
|
|
31997
|
+
return "cursor";
|
|
31998
|
+
case "cline":
|
|
31999
|
+
return "cline";
|
|
32000
|
+
case "generic":
|
|
32001
|
+
return "generic_mcp";
|
|
32002
|
+
default: {
|
|
32003
|
+
return "other";
|
|
32004
|
+
}
|
|
32005
|
+
}
|
|
32006
|
+
}
|
|
32007
|
+
function buildLocalAgentRecord(input) {
|
|
32008
|
+
const harness = harnessKindForPlatform(input.platform);
|
|
32009
|
+
const fortressId = fortressIdFromStoragePath(input.storagePath);
|
|
32010
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
32011
|
+
return {
|
|
32012
|
+
version: "1.1",
|
|
32013
|
+
agent_id: `agent:${harness}:${fortressId}`,
|
|
32014
|
+
identity_id: `fortress:${input.storagePath}`,
|
|
32015
|
+
harness,
|
|
32016
|
+
model_provider: {
|
|
32017
|
+
vendor: "unknown",
|
|
32018
|
+
model_id: "unknown",
|
|
32019
|
+
runs_locally: false
|
|
32020
|
+
},
|
|
32021
|
+
policy_id: "unbound",
|
|
32022
|
+
status: "active",
|
|
32023
|
+
budget_summary: {
|
|
32024
|
+
last_refreshed_at: nowIso
|
|
32025
|
+
},
|
|
32026
|
+
last_activity_at: nowIso,
|
|
32027
|
+
wrapped_at: nowIso,
|
|
32028
|
+
capabilities: {
|
|
32029
|
+
can_pause: false,
|
|
32030
|
+
can_resume: false,
|
|
32031
|
+
can_restart: false,
|
|
32032
|
+
can_unwrap: true,
|
|
32033
|
+
can_lockdown: false,
|
|
32034
|
+
can_chat: false,
|
|
32035
|
+
can_change_template: false
|
|
32036
|
+
}
|
|
32037
|
+
};
|
|
32038
|
+
}
|
|
31867
32039
|
function countUpstreamTools(servers) {
|
|
31868
32040
|
return servers.length === 0 ? 0 : servers.length;
|
|
31869
32041
|
}
|
|
@@ -31924,6 +32096,9 @@ function parseWrapArgs(argv) {
|
|
|
31924
32096
|
case "--no-open":
|
|
31925
32097
|
options.noOpen = true;
|
|
31926
32098
|
break;
|
|
32099
|
+
case "--no-dashboard":
|
|
32100
|
+
options.noDashboard = true;
|
|
32101
|
+
break;
|
|
31927
32102
|
case "--fortress":
|
|
31928
32103
|
options.fortress = argv[++i];
|
|
31929
32104
|
break;
|
|
@@ -31964,6 +32139,11 @@ function printWrapHelp() {
|
|
|
31964
32139
|
--port <port> Preferred dashboard port (default: 3501)
|
|
31965
32140
|
--dry-run Show what would happen without making changes
|
|
31966
32141
|
--no-open Do not auto-open the dashboard in a browser
|
|
32142
|
+
--no-dashboard Do not spawn a per-call dashboard server. Wrap still
|
|
32143
|
+
persists the agent record so a separately-running
|
|
32144
|
+
\`sanctuary dashboard\` (or a later wrap) sees the
|
|
32145
|
+
harness. Use this for the clean operator setup
|
|
32146
|
+
(one persistent dashboard + many wraps).
|
|
31967
32147
|
--help, -h Show this help
|
|
31968
32148
|
|
|
31969
32149
|
What happens:
|
|
@@ -31981,6 +32161,7 @@ var init_cli2 = __esm({
|
|
|
31981
32161
|
init_passphrase();
|
|
31982
32162
|
init_dashboard2();
|
|
31983
32163
|
init_wiring();
|
|
32164
|
+
init_agent_registry_persistence();
|
|
31984
32165
|
init_filesystem();
|
|
31985
32166
|
init_key_derivation();
|
|
31986
32167
|
init_encoding();
|
|
@@ -35618,7 +35799,12 @@ Refusing to start the dashboard while the reset-history marker is unreadable.`
|
|
|
35618
35799
|
buildV11Bindings({
|
|
35619
35800
|
identityId: hubIdentityId,
|
|
35620
35801
|
fortressId: fortressIdFromStoragePath(config.storage_path),
|
|
35621
|
-
auditLog
|
|
35802
|
+
auditLog,
|
|
35803
|
+
// v1.1.5 (Finding Z): rehydrate the hub agent registry from
|
|
35804
|
+
// `<storagePath>/state/_hub/local-agents.json` so the standalone
|
|
35805
|
+
// dashboard surfaces wraps performed by prior `sanctuary wrap`
|
|
35806
|
+
// invocations against this same fortress.
|
|
35807
|
+
storagePath: config.storage_path
|
|
35622
35808
|
})
|
|
35623
35809
|
);
|
|
35624
35810
|
const hostIsLoopback = dashboardHost === "127.0.0.1" || dashboardHost === "::1" || dashboardHost === "localhost";
|
|
@@ -35648,6 +35834,10 @@ Refusing to start the dashboard while the reset-history marker is unreadable.`
|
|
|
35648
35834
|
console.error(`Sanctuary Dashboard v${SANCTUARY_VERSION} (standalone mode)`);
|
|
35649
35835
|
console.error(`Storage: ${config.storage_path}`);
|
|
35650
35836
|
console.error(`Identities loaded: ${loadResult.loaded}`);
|
|
35837
|
+
const persistedAgentsCount = readPersistedLocalAgents(
|
|
35838
|
+
config.storage_path
|
|
35839
|
+
).length;
|
|
35840
|
+
console.error(`Local agents loaded: ${persistedAgentsCount}`);
|
|
35651
35841
|
console.error(`Listening: http://${dashboardHost}:${dashboardPort}`);
|
|
35652
35842
|
if (loadResult.total > 0 && loadResult.loaded === 0) {
|
|
35653
35843
|
const service = keychainServiceFor(config.storage_path, os.homedir());
|
|
@@ -35706,6 +35896,7 @@ var init_dashboard_standalone = __esm({
|
|
|
35706
35896
|
init_recovery_key_disclosure();
|
|
35707
35897
|
init_discovery();
|
|
35708
35898
|
init_wiring();
|
|
35899
|
+
init_agent_registry_persistence();
|
|
35709
35900
|
}
|
|
35710
35901
|
});
|
|
35711
35902
|
|