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