@sanctuary-framework/mcp-server 0.5.9 → 0.5.11

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 CHANGED
@@ -3454,11 +3454,12 @@ function generateDashboardHTML(options) {
3454
3454
  // API Updates
3455
3455
  async function updateSovereignty() {
3456
3456
  const data = await fetchAPI('/api/sovereignty');
3457
- if (!data) return;
3457
+ if (!data || data.error) return;
3458
3458
 
3459
3459
  apiState.sovereignty = data;
3460
3460
 
3461
- const score = calculateSovereigntyScore(data.shr);
3461
+ // API returns { score, overall_level, layers: { l1, l2, l3, l4 }, ... }
3462
+ const score = data.score ?? 0;
3462
3463
  const badge = document.getElementById('sovereignty-badge');
3463
3464
  const scoreEl = document.getElementById('sovereignty-score');
3464
3465
 
@@ -3468,18 +3469,18 @@ function generateDashboardHTML(options) {
3468
3469
  if (score < 70) badge.classList.add('degraded');
3469
3470
  if (score < 40) badge.classList.add('inactive');
3470
3471
 
3471
- updateLayerCards(data.shr);
3472
+ updateLayerCards(data);
3472
3473
  }
3473
3474
 
3474
- function updateLayerCards(shr) {
3475
- if (!shr || !shr.layers) return;
3475
+ function updateLayerCards(data) {
3476
+ if (!data || !data.layers) return;
3476
3477
 
3477
- const layers = shr.layers;
3478
+ const layers = data.layers;
3478
3479
 
3479
- updateLayerCard('l1', layers.l1, layers.l1?.encryption || 'AES-256-GCM');
3480
- updateLayerCard('l2', layers.l2, layers.l2?.isolation_type || 'Process-level');
3481
- updateLayerCard('l3', layers.l3, layers.l3?.proof_system || 'Schnorr-Pedersen');
3482
- updateLayerCard('l4', layers.l4, layers.l4?.reputation_mode || 'Weighted');
3480
+ updateLayerCard('l1', layers.l1, layers.l1?.detail || 'AES-256-GCM');
3481
+ updateLayerCard('l2', layers.l2, layers.l2?.detail || 'Process-level');
3482
+ updateLayerCard('l3', layers.l3, layers.l3?.detail || 'Schnorr-Pedersen');
3483
+ updateLayerCard('l4', layers.l4, layers.l4?.detail || 'Weighted');
3483
3484
  }
3484
3485
 
3485
3486
  function updateLayerCard(layer, layerData, detail) {
@@ -3507,14 +3508,16 @@ function generateDashboardHTML(options) {
3507
3508
 
3508
3509
  apiState.identity = data;
3509
3510
 
3510
- const primary = data.primary || {};
3511
+ // API returns { identities: [...], count, primary_id }
3512
+ // Find the primary identity from the array
3513
+ const primary = (data.identities || []).find(id => id.identity_id === data.primary_id) || {};
3511
3514
  document.getElementById('identity-label').textContent = primary.label || '\u2014';
3512
3515
  document.getElementById('identity-did').textContent = truncate(primary.did, 24);
3513
3516
  document.getElementById('identity-did').title = primary.did || '';
3514
- document.getElementById('identity-pubkey').textContent = truncate(primary.publicKey, 24);
3515
- document.getElementById('identity-pubkey').title = primary.publicKey || '';
3516
- document.getElementById('identity-created').textContent = formatTime(primary.createdAt);
3517
- document.getElementById('identity-count').textContent = data.identities?.length || '\u2014';
3517
+ document.getElementById('identity-pubkey').textContent = truncate(primary.public_key, 24);
3518
+ document.getElementById('identity-pubkey').title = primary.public_key || '';
3519
+ document.getElementById('identity-created').textContent = formatTime(primary.created_at);
3520
+ document.getElementById('identity-count').textContent = data.count || '\u2014';
3518
3521
  }
3519
3522
 
3520
3523
  async function updateHandshakes() {
@@ -3523,14 +3526,14 @@ function generateDashboardHTML(options) {
3523
3526
 
3524
3527
  apiState.handshakes = data.handshakes || [];
3525
3528
 
3526
- document.getElementById('handshake-count').textContent = data.handshakes?.length || '0';
3529
+ document.getElementById('handshake-count').textContent = data.count || '0';
3527
3530
 
3528
3531
  if (data.handshakes && data.handshakes.length > 0) {
3529
3532
  const latest = data.handshakes[0];
3530
- document.getElementById('handshake-latest').textContent = truncate(latest.counterpartyId, 20);
3531
- document.getElementById('handshake-latest').title = latest.counterpartyId || '';
3532
- document.getElementById('handshake-tier').textContent = (latest.trustTier || 'Unverified').toUpperCase();
3533
- document.getElementById('handshake-time').textContent = formatTime(latest.completedAt);
3533
+ document.getElementById('handshake-latest').textContent = truncate(latest.counterparty_id, 20);
3534
+ document.getElementById('handshake-latest').title = latest.counterparty_id || '';
3535
+ document.getElementById('handshake-tier').textContent = (latest.trust_tier || 'Unverified').toUpperCase();
3536
+ document.getElementById('handshake-time').textContent = formatTime(latest.completed_at);
3534
3537
  } else {
3535
3538
  document.getElementById('handshake-latest').textContent = '\u2014';
3536
3539
  document.getElementById('handshake-tier').textContent = 'Unverified';
@@ -3552,12 +3555,12 @@ function generateDashboardHTML(options) {
3552
3555
  .map(
3553
3556
  (hs) => \`
3554
3557
  <div class="table-row">
3555
- <div class="table-cell strong">\${esc(truncate(hs.counterpartyId, 24))}</div>
3556
- <div class="table-cell">\${esc(hs.trustTier || 'Unverified')}</div>
3557
- <div class="table-cell">\${esc(hs.sovereigntyLevel || '\u2014')}</div>
3558
+ <div class="table-cell strong">\${esc(truncate(hs.counterparty_id, 24))}</div>
3559
+ <div class="table-cell">\${esc(hs.trust_tier || 'Unverified')}</div>
3560
+ <div class="table-cell">\${esc(hs.sovereignty_level || '\u2014')}</div>
3558
3561
  <div class="table-cell">\${hs.verified ? 'Yes' : 'No'}</div>
3559
- <div class="table-cell">\${formatTime(hs.completedAt)}</div>
3560
- <div class="table-cell">\${formatTime(hs.expiresAt)}</div>
3562
+ <div class="table-cell">\${formatTime(hs.completed_at)}</div>
3563
+ <div class="table-cell">\${formatTime(hs.expires_at)}</div>
3561
3564
  </div>
3562
3565
  \`
3563
3566
  )
@@ -3575,11 +3578,14 @@ function generateDashboardHTML(options) {
3575
3578
  function renderSHRViewer(shr) {
3576
3579
  const viewer = document.getElementById('shr-viewer');
3577
3580
 
3578
- if (!shr) {
3581
+ if (!shr || shr.error) {
3579
3582
  viewer.innerHTML = '<div class="empty-state">No SHR available</div>';
3580
3583
  return;
3581
3584
  }
3582
3585
 
3586
+ // SignedSHR shape: { body: { implementation, instance_id, layers, ... }, signed_by, signature }
3587
+ const body = shr.body || shr;
3588
+
3583
3589
  let html = '';
3584
3590
 
3585
3591
  // Implementation
@@ -3592,15 +3598,15 @@ function generateDashboardHTML(options) {
3592
3598
  <div class="shr-section-content">
3593
3599
  <div class="shr-item">
3594
3600
  <div class="shr-key">sanctuary_version:</div>
3595
- <div class="shr-value">\${esc(shr.implementation?.sanctuary_version || '\u2014')}</div>
3601
+ <div class="shr-value">\${esc(body.implementation?.sanctuary_version || '\u2014')}</div>
3596
3602
  </div>
3597
3603
  <div class="shr-item">
3598
3604
  <div class="shr-key">node_version:</div>
3599
- <div class="shr-value">\${esc(shr.implementation?.node_version || '\u2014')}</div>
3605
+ <div class="shr-value">\${esc(body.implementation?.node_version || '\u2014')}</div>
3600
3606
  </div>
3601
3607
  <div class="shr-item">
3602
3608
  <div class="shr-key">generated_by:</div>
3603
- <div class="shr-value">\${esc(shr.implementation?.generated_by || '\u2014')}</div>
3609
+ <div class="shr-value">\${esc(body.implementation?.generated_by || '\u2014')}</div>
3604
3610
  </div>
3605
3611
  </div>
3606
3612
  </div>
@@ -3616,22 +3622,22 @@ function generateDashboardHTML(options) {
3616
3622
  <div class="shr-section-content">
3617
3623
  <div class="shr-item">
3618
3624
  <div class="shr-key">instance_id:</div>
3619
- <div class="shr-value">\${esc(truncate(shr.instance_id, 20))}</div>
3625
+ <div class="shr-value">\${esc(truncate(body.instance_id, 20))}</div>
3620
3626
  </div>
3621
3627
  <div class="shr-item">
3622
3628
  <div class="shr-key">generated_at:</div>
3623
- <div class="shr-value">\${formatTime(shr.generated_at)}</div>
3629
+ <div class="shr-value">\${formatTime(body.generated_at)}</div>
3624
3630
  </div>
3625
3631
  <div class="shr-item">
3626
3632
  <div class="shr-key">expires_at:</div>
3627
- <div class="shr-value">\${formatTime(shr.expires_at)}</div>
3633
+ <div class="shr-value">\${formatTime(body.expires_at)}</div>
3628
3634
  </div>
3629
3635
  </div>
3630
3636
  </div>
3631
3637
  \`;
3632
3638
 
3633
3639
  // Layers
3634
- if (shr.layers) {
3640
+ if (body.layers) {
3635
3641
  html += \`<div class="shr-section">
3636
3642
  <div class="shr-section-header">
3637
3643
  <div class="shr-toggle">\u25BC</div>
@@ -3640,7 +3646,7 @@ function generateDashboardHTML(options) {
3640
3646
  <div class="shr-section-content">
3641
3647
  \`;
3642
3648
 
3643
- for (const [key, layer] of Object.entries(shr.layers)) {
3649
+ for (const [key, layer] of Object.entries(body.layers)) {
3644
3650
  html += \`
3645
3651
  <div style="margin-bottom: 12px;">
3646
3652
  <div style="color: var(--blue); font-weight: 600; margin-bottom: 4px;">\${esc(key)}</div>
@@ -11368,11 +11374,57 @@ var TOOL_API_SCOPED = {
11368
11374
  ],
11369
11375
  default_action: "redact"
11370
11376
  };
11377
+ var REMOTE_INFERENCE_SANITIZE = {
11378
+ id: "remote-inference-sanitize",
11379
+ name: "Remote Inference Sanitization",
11380
+ description: "Maximum privacy for remote/cloud LLM calls. Strips all identity, financial, location, and personal data before passing queries to external models. Inspired by Vitalik Buterin's 2-of-2 sovereignty model.",
11381
+ use_when: "Your local agent needs to call a remote LLM for tasks beyond local model capability (complex coding, deep research) and you want to minimize data leakage to the remote provider. The remote model gets only the task, query, format requirements, and stripped code context.",
11382
+ rules: [
11383
+ {
11384
+ provider: "inference",
11385
+ allow: [
11386
+ "task",
11387
+ "task_description",
11388
+ "current_query",
11389
+ "query",
11390
+ "prompt",
11391
+ "question",
11392
+ "instruction",
11393
+ "output_format",
11394
+ "format",
11395
+ "language",
11396
+ "code_context",
11397
+ // Stripped code snippets for coding tasks
11398
+ "error_message"
11399
+ // For debugging help
11400
+ ],
11401
+ redact: [
11402
+ ...ALWAYS_REDACT_SECRETS,
11403
+ ...PII_PATTERNS,
11404
+ ...INTERNAL_STATE_PATTERNS,
11405
+ ...HISTORY_PATTERNS,
11406
+ "tool_results",
11407
+ "previous_results",
11408
+ // Additional redactions for remote inference
11409
+ "model_data",
11410
+ "agent_state",
11411
+ "runtime_config",
11412
+ "capabilities",
11413
+ "tool_list"
11414
+ ],
11415
+ // Deny patterns — these must NEVER reach the remote model, not even redacted
11416
+ hash: [],
11417
+ summarize: []
11418
+ }
11419
+ ],
11420
+ default_action: "deny"
11421
+ };
11371
11422
  var TEMPLATES = {
11372
11423
  "inference-minimal": INFERENCE_MINIMAL,
11373
11424
  "inference-standard": INFERENCE_STANDARD,
11374
11425
  "logging-strict": LOGGING_STRICT,
11375
- "tool-api-scoped": TOOL_API_SCOPED
11426
+ "tool-api-scoped": TOOL_API_SCOPED,
11427
+ "remote-inference-sanitize": REMOTE_INFERENCE_SANITIZE
11376
11428
  };
11377
11429
  function listTemplateIds() {
11378
11430
  return Object.keys(TEMPLATES);