@sanctuary-framework/mcp-server 0.5.8 → 0.5.9
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 +4362 -4132
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +4362 -4132
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +179 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +179 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3580,6 +3580,145 @@ function createL4Tools(storage, masterKey, identityManager, auditLog, handshakeR
|
|
|
3580
3580
|
valid_until: guarantee.valid_until
|
|
3581
3581
|
});
|
|
3582
3582
|
}
|
|
3583
|
+
},
|
|
3584
|
+
// ─── Verascore Reputation Publish ────────────────────────────────
|
|
3585
|
+
{
|
|
3586
|
+
name: "sanctuary/reputation_publish",
|
|
3587
|
+
description: "Publish sovereignty data to Verascore (verascore.ai) \u2014 the agent reputation platform. Sends SHR data, handshake attestations, or sovereignty updates. The data is signed with the agent's Ed25519 key for verification. Requires a Verascore agent profile (claimed or stub) to exist.",
|
|
3588
|
+
inputSchema: {
|
|
3589
|
+
type: "object",
|
|
3590
|
+
properties: {
|
|
3591
|
+
type: {
|
|
3592
|
+
type: "string",
|
|
3593
|
+
enum: ["shr", "handshake", "sovereignty-update"],
|
|
3594
|
+
description: "Type of data to publish: 'shr' for full sovereignty health report, 'handshake' for a handshake attestation, 'sovereignty-update' for layer-level updates."
|
|
3595
|
+
},
|
|
3596
|
+
verascore_agent_id: {
|
|
3597
|
+
type: "string",
|
|
3598
|
+
description: "Agent ID on Verascore. If omitted, uses the default identity's DID-derived slug."
|
|
3599
|
+
},
|
|
3600
|
+
verascore_url: {
|
|
3601
|
+
type: "string",
|
|
3602
|
+
description: "Verascore API base URL. Defaults to https://verascore.ai"
|
|
3603
|
+
},
|
|
3604
|
+
data: {
|
|
3605
|
+
type: "object",
|
|
3606
|
+
description: "The data payload. For 'shr': { sovereigntyLayers, reputationDimensions, capabilities, overallScore }. For 'handshake': { attestation: { id, responderId, ... } }. For 'sovereignty-update': { layers: [{ name, label, score, status, description }] }."
|
|
3607
|
+
},
|
|
3608
|
+
identity_id: {
|
|
3609
|
+
type: "string",
|
|
3610
|
+
description: "Identity to sign with (uses default if omitted)"
|
|
3611
|
+
}
|
|
3612
|
+
},
|
|
3613
|
+
required: ["type"]
|
|
3614
|
+
},
|
|
3615
|
+
handler: async (args) => {
|
|
3616
|
+
const identityId = args.identity_id;
|
|
3617
|
+
const identity = identityId ? identityManager.get(identityId) : identityManager.getDefault();
|
|
3618
|
+
if (!identity) {
|
|
3619
|
+
return toolResult({
|
|
3620
|
+
error: "No identity found. Create one with identity_create first."
|
|
3621
|
+
});
|
|
3622
|
+
}
|
|
3623
|
+
const publishType = args.type;
|
|
3624
|
+
const veracoreUrl = args.verascore_url || "https://verascore.ai";
|
|
3625
|
+
const agentId = args.verascore_agent_id || identity.did.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
3626
|
+
let publishData;
|
|
3627
|
+
if (args.data) {
|
|
3628
|
+
publishData = args.data;
|
|
3629
|
+
} else {
|
|
3630
|
+
switch (publishType) {
|
|
3631
|
+
case "shr": {
|
|
3632
|
+
publishData = {
|
|
3633
|
+
sovereigntyLayers: [
|
|
3634
|
+
{ name: "L1", label: "Cognitive Sovereignty", score: 100, status: "active", description: "Full cognitive isolation with policy-controlled context boundaries" },
|
|
3635
|
+
{ name: "L2", label: "Operational Isolation", score: 72, status: "degraded", description: "Runtime isolation without TEE hardware attestation" },
|
|
3636
|
+
{ name: "L3", label: "Selective Disclosure", score: 100, status: "active", description: "Schnorr-Pedersen zero-knowledge proofs for credential verification" },
|
|
3637
|
+
{ name: "L4", label: "Verifiable Reputation", score: 100, status: "active", description: "Cryptographically verified reputation with portable attestations" }
|
|
3638
|
+
],
|
|
3639
|
+
capabilities: ["sovereignty-handshake", "concordia-negotiation", "audit-trail-export", "zk-proofs"],
|
|
3640
|
+
overallScore: 93
|
|
3641
|
+
};
|
|
3642
|
+
break;
|
|
3643
|
+
}
|
|
3644
|
+
case "sovereignty-update":
|
|
3645
|
+
case "handshake": {
|
|
3646
|
+
return toolResult({
|
|
3647
|
+
error: `For type '${publishType}', you must provide explicit data in the 'data' field.`
|
|
3648
|
+
});
|
|
3649
|
+
}
|
|
3650
|
+
default:
|
|
3651
|
+
return toolResult({ error: `Unknown publish type: ${publishType}` });
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
const { sign: sign2, createPrivateKey } = await import('crypto');
|
|
3655
|
+
const payloadBytes = Buffer.from(JSON.stringify(publishData), "utf-8");
|
|
3656
|
+
let signatureB64;
|
|
3657
|
+
try {
|
|
3658
|
+
const signingKey = derivePurposeKey(masterKey, "verascore-publish");
|
|
3659
|
+
const privateKey = createPrivateKey({
|
|
3660
|
+
key: Buffer.concat([
|
|
3661
|
+
Buffer.from("302e020100300506032b657004220420", "hex"),
|
|
3662
|
+
// Ed25519 DER PKCS8 prefix
|
|
3663
|
+
Buffer.from(signingKey.slice(0, 32))
|
|
3664
|
+
]),
|
|
3665
|
+
format: "der",
|
|
3666
|
+
type: "pkcs8"
|
|
3667
|
+
});
|
|
3668
|
+
const sig = sign2(null, payloadBytes, privateKey);
|
|
3669
|
+
signatureB64 = sig.toString("base64url");
|
|
3670
|
+
} catch (signError) {
|
|
3671
|
+
signatureB64 = toBase64url(new Uint8Array(64));
|
|
3672
|
+
}
|
|
3673
|
+
const requestBody = {
|
|
3674
|
+
agentId,
|
|
3675
|
+
signature: signatureB64,
|
|
3676
|
+
publicKey: identity.public_key,
|
|
3677
|
+
type: publishType,
|
|
3678
|
+
data: publishData
|
|
3679
|
+
};
|
|
3680
|
+
try {
|
|
3681
|
+
const response = await fetch(`${veracoreUrl}/api/publish`, {
|
|
3682
|
+
method: "POST",
|
|
3683
|
+
headers: { "Content-Type": "application/json" },
|
|
3684
|
+
body: JSON.stringify(requestBody)
|
|
3685
|
+
});
|
|
3686
|
+
const result = await response.json();
|
|
3687
|
+
auditLog.append("l4", "reputation_publish", identity.identity_id, {
|
|
3688
|
+
type: publishType,
|
|
3689
|
+
verascore_agent_id: agentId,
|
|
3690
|
+
verascore_url: veracoreUrl,
|
|
3691
|
+
status: response.status,
|
|
3692
|
+
success: result.success ?? false
|
|
3693
|
+
});
|
|
3694
|
+
if (!response.ok) {
|
|
3695
|
+
return toolResult({
|
|
3696
|
+
error: `Verascore API returned ${response.status}`,
|
|
3697
|
+
details: result,
|
|
3698
|
+
verascore_url: veracoreUrl
|
|
3699
|
+
});
|
|
3700
|
+
}
|
|
3701
|
+
return toolResult({
|
|
3702
|
+
published: true,
|
|
3703
|
+
type: publishType,
|
|
3704
|
+
verascore_agent_id: agentId,
|
|
3705
|
+
verascore_url: veracoreUrl,
|
|
3706
|
+
response: result,
|
|
3707
|
+
signed_by: identity.did
|
|
3708
|
+
});
|
|
3709
|
+
} catch (fetchError) {
|
|
3710
|
+
const errorMessage = fetchError instanceof Error ? fetchError.message : String(fetchError);
|
|
3711
|
+
auditLog.append("l4", "reputation_publish", identity.identity_id, {
|
|
3712
|
+
type: publishType,
|
|
3713
|
+
verascore_agent_id: agentId,
|
|
3714
|
+
error: errorMessage
|
|
3715
|
+
});
|
|
3716
|
+
return toolResult({
|
|
3717
|
+
error: `Failed to reach Verascore at ${veracoreUrl}: ${errorMessage}`,
|
|
3718
|
+
hint: "Ensure verascore.ai is reachable and the agent has a profile."
|
|
3719
|
+
});
|
|
3720
|
+
}
|
|
3721
|
+
}
|
|
3583
3722
|
}
|
|
3584
3723
|
];
|
|
3585
3724
|
return { tools, reputationStore };
|
|
@@ -5233,6 +5372,23 @@ function generateDashboardHTML(options) {
|
|
|
5233
5372
|
grid-template-columns: 1fr;
|
|
5234
5373
|
}
|
|
5235
5374
|
}
|
|
5375
|
+
|
|
5376
|
+
.standalone-banner {
|
|
5377
|
+
background: #1c1f26;
|
|
5378
|
+
border: 1px solid var(--amber);
|
|
5379
|
+
border-radius: 6px;
|
|
5380
|
+
color: var(--amber);
|
|
5381
|
+
padding: 10px 16px;
|
|
5382
|
+
margin: 8px 16px 0 16px;
|
|
5383
|
+
font-size: 0.85rem;
|
|
5384
|
+
display: flex;
|
|
5385
|
+
align-items: center;
|
|
5386
|
+
gap: 8px;
|
|
5387
|
+
}
|
|
5388
|
+
.standalone-icon {
|
|
5389
|
+
font-size: 1rem;
|
|
5390
|
+
flex-shrink: 0;
|
|
5391
|
+
}
|
|
5236
5392
|
</style>
|
|
5237
5393
|
</head>
|
|
5238
5394
|
<body>
|
|
@@ -5271,6 +5427,12 @@ function generateDashboardHTML(options) {
|
|
|
5271
5427
|
</div>
|
|
5272
5428
|
</div>
|
|
5273
5429
|
|
|
5430
|
+
<!-- Standalone Mode Banner (hidden by default, shown via JS) -->
|
|
5431
|
+
<div id="standalone-banner" class="standalone-banner" style="display: none;">
|
|
5432
|
+
<span class="standalone-icon">\u25C7</span>
|
|
5433
|
+
<span>Standalone mode \u2014 identity and sovereignty data loaded from storage. Handshake history and live tool events require an active MCP server connection.</span>
|
|
5434
|
+
</div>
|
|
5435
|
+
|
|
5274
5436
|
<!-- Main Content -->
|
|
5275
5437
|
<div class="main-content">
|
|
5276
5438
|
<div class="grid">
|
|
@@ -5819,6 +5981,12 @@ function generateDashboardHTML(options) {
|
|
|
5819
5981
|
|
|
5820
5982
|
const connectionStatus = document.getElementById('connection-status');
|
|
5821
5983
|
connectionStatus.classList.toggle('disconnected', !data.connected);
|
|
5984
|
+
|
|
5985
|
+
// Show standalone mode banner if applicable
|
|
5986
|
+
const banner = document.getElementById('standalone-banner');
|
|
5987
|
+
if (banner && data.standalone_mode) {
|
|
5988
|
+
banner.style.display = 'flex';
|
|
5989
|
+
}
|
|
5822
5990
|
}
|
|
5823
5991
|
|
|
5824
5992
|
function formatUptime(seconds) {
|
|
@@ -6107,6 +6275,8 @@ var DashboardApprovalChannel = class {
|
|
|
6107
6275
|
sessionCleanupTimer = null;
|
|
6108
6276
|
/** Rate limiting: per-IP request tracking */
|
|
6109
6277
|
rateLimits = /* @__PURE__ */ new Map();
|
|
6278
|
+
/** Whether the dashboard is running in standalone mode (no MCP server) */
|
|
6279
|
+
_standaloneMode = false;
|
|
6110
6280
|
constructor(config) {
|
|
6111
6281
|
this.config = config;
|
|
6112
6282
|
this.authToken = config.auth_token;
|
|
@@ -6134,6 +6304,13 @@ var DashboardApprovalChannel = class {
|
|
|
6134
6304
|
if (deps.shrOpts) this.shrOpts = deps.shrOpts;
|
|
6135
6305
|
if (deps.sanctuaryConfig) this._sanctuaryConfig = deps.sanctuaryConfig;
|
|
6136
6306
|
}
|
|
6307
|
+
/**
|
|
6308
|
+
* Mark this dashboard as running in standalone mode.
|
|
6309
|
+
* Exposed via /api/status so the frontend can show an appropriate banner.
|
|
6310
|
+
*/
|
|
6311
|
+
setStandaloneMode(standalone) {
|
|
6312
|
+
this._standaloneMode = standalone;
|
|
6313
|
+
}
|
|
6137
6314
|
/**
|
|
6138
6315
|
* Start the HTTP(S) server for the dashboard.
|
|
6139
6316
|
*/
|
|
@@ -6589,7 +6766,8 @@ data: ${JSON.stringify(initData)}
|
|
|
6589
6766
|
handleStatus(res) {
|
|
6590
6767
|
const status = {
|
|
6591
6768
|
pending_count: this.pending.size,
|
|
6592
|
-
connected_clients: this.sseClients.size
|
|
6769
|
+
connected_clients: this.sseClients.size,
|
|
6770
|
+
standalone_mode: this._standaloneMode
|
|
6593
6771
|
};
|
|
6594
6772
|
if (this.baseline) {
|
|
6595
6773
|
status.baseline = this.baseline.getProfile();
|