protect-mcp 0.5.3 → 0.5.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/README.md CHANGED
@@ -16,6 +16,14 @@ npx protect-mcp serve
16
16
 
17
17
  Open Claude Code in the same project. Every tool call is now intercepted, evaluated, and signed.
18
18
 
19
+ To also connect to the ScopeBlind dashboard in one step:
20
+
21
+ ```bash
22
+ npx protect-mcp quickstart --connect
23
+ ```
24
+
25
+ Creates a free ScopeBlind dashboard and configures receipt upload automatically. No signup required. Free up to 20,000 receipts/month.
26
+
19
27
  ### What `init-hooks` creates
20
28
 
21
29
  | File | Purpose |
@@ -209,6 +217,7 @@ Commands:
209
217
  serve Start HTTP hook server for Claude Code (port 9377)
210
218
  init-hooks Generate Claude Code hook config + skill + sample Cedar policy
211
219
  quickstart Zero-config onboarding: init + demo + show receipts
220
+ connect Link to ScopeBlind dashboard (creates sandbox if needed)
212
221
  init Generate Ed25519 keypair + config template
213
222
  demo Start a demo server wrapped with protect-mcp
214
223
  doctor Check your setup: keys, policies, verifier, connectivity
@@ -246,15 +255,107 @@ npx protect-mcp bundle --output audit.json
246
255
 
247
256
  Self-contained offline-verifiable bundle with receipts + signing keys. Verify with `npx @veritasacta/verify`.
248
257
 
258
+ ## Dashboard
259
+
260
+ protect-mcp works fully offline. Optionally connect to the ScopeBlind dashboard for:
261
+
262
+ - Real-time receipt visualization
263
+ - Abuse alerts and anomaly detection
264
+ - Compliance export and audit bundles
265
+ - Usage analytics
266
+
267
+ Free tier: 20,000 receipts/month. No credit card required.
268
+
269
+ [scopeblind.com/pricing](https://scopeblind.com/pricing)
270
+
271
+ ## Interoperability
272
+
273
+ The receipt format is independently implemented and verified across multiple systems:
274
+
275
+ | Evidence | Detail |
276
+ |----------|--------|
277
+ | **4 independent implementations** | TypeScript (protect-mcp), Python (protect-mcp-adk), Rust (Cedar WASM), APS ProxyGateway |
278
+ | **2 IETF Internet-Drafts** | [draft-farley-acta-signed-receipts-01](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/), [draft-pidlisnyi-aps-00](https://datatracker.ietf.org/doc/draft-pidlisnyi-aps/) |
279
+ | **8 cross-engine receipts** | [Composition test](https://github.com/ScopeBlind/examples/tree/main/interop/composition-test): 2 engines, 1 verifier, all VALID |
280
+ | **1 enterprise integration** | [Microsoft AGT PR #667](https://github.com/microsoft/agent-governance-toolkit/pull/667) merged |
281
+ | **1 verifier, zero dependencies** | `npx @veritasacta/verify receipt.json --key <hex>` (Apache-2.0, offline) |
282
+
283
+ Verify any receipt from any implementation:
284
+
285
+ ```bash
286
+ npx @veritasacta/verify receipt.json --key <public-key-hex>
287
+ # Exit 0 = valid, 1 = tampered, 2 = malformed
288
+ ```
289
+
249
290
  ## Standards & IP
250
291
 
251
- - **IETF Internet-Draft**: [draft-farley-acta-signed-receipts-01](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/) — Signed Decision Receipts for Machine-to-Machine Access Control
252
- - **Patent Status**: 4 Australian provisional patents pending (2025-2026) covering decision receipts with configurable disclosure, tool-calling gateway, agent manifests, and portable identity
253
- - **Verification**: Apache-2.0 `npx @veritasacta/verify --self-test`
254
- - **Microsoft AGT Integration**: [PR #667](https://github.com/microsoft/agent-governance-toolkit/pull/667) — Cedar policy bridge for Agent Governance Toolkit
292
+ - **IETF Internet-Draft**: [draft-farley-acta-signed-receipts-01](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/)
293
+ - **Patent Status**: 4 Australian provisional patents pending (2025-2026)
294
+ - **Cedar WASM**: [PR #64](https://github.com/cedar-policy/cedar-for-agents/pull/64) on cedar-for-agents (under review)
295
+
296
+ ## What's New in v0.5.3
297
+
298
+ - `quickstart --connect`: Auto-create dashboard sandbox and configure receipt upload
299
+ - `connect` subcommand: Link an existing setup to the ScopeBlind dashboard
300
+ - Anonymous install telemetry (opt-out: `PROTECT_MCP_TELEMETRY=off`)
301
+ - Improved Cedar WASM detection
302
+
303
+ ## Cybersecurity: Vulnerability Disclosure Receipts
304
+
305
+ protect-mcp provides the infrastructure for receipt-signed vulnerability disclosure workflows. When AI security agents (Claude Code Security, Mythos, or similar) discover vulnerabilities, every step of the disclosure lifecycle can produce a signed, chain-linked receipt:
306
+
307
+ ```
308
+ DISCOVER → DISCLOSE → PATCH → DEPLOY
309
+ (Each step: Ed25519-signed, chain-linked, Cedar policy-bound)
310
+ ```
311
+
312
+ Cedar policies govern what the scanning agent is allowed to do:
313
+ - **CAN**: scan code, report findings internally
314
+ - **CANNOT**: disclose externally or deploy patches without human approval
315
+ - **MUST**: escalate critical findings to humans
316
+
317
+ See the [security vulnerability disclosure example](https://github.com/ScopeBlind/examples/tree/main/security-vulnerability-disclosure) for a complete working implementation with Cedar policies and example receipt chains.
318
+
319
+ Related: [Vulnerability Disclosure Receipt Design](https://github.com/scopeblind/scopeblind-gateway/issues/2)
320
+
321
+ ## Examples
322
+
323
+ See complete working examples at [github.com/ScopeBlind/examples](https://github.com/ScopeBlind/examples):
324
+ - [Claude Code hooks](https://github.com/ScopeBlind/examples/tree/main/claude-code-hooks) — receipt signing for every tool call
325
+ - [Security vulnerability disclosure](https://github.com/ScopeBlind/examples/tree/main/security-vulnerability-disclosure) — receipt-signed disclosure lifecycle with Cedar governance
326
+ - [MCP server signing](https://github.com/ScopeBlind/examples/tree/main/mcp-server-signing) — Cedar WASM policy engine with audit bundles
327
+
328
+ ## ScopeBlind Dashboard
329
+
330
+ protect-mcp works fully offline, forever, for free. For teams that want visibility across agents, ScopeBlind offers a hosted dashboard:
331
+
332
+ ```bash
333
+ npx protect-mcp connect
334
+ ```
335
+
336
+ | | Free | Pro | Enterprise |
337
+ |---|---|---|---|
338
+ | Receipts/month | 20,000 | Pay-as-you-go | Annual commit |
339
+ | Price | $0 | $0.50 / 1K | $0.40 / 1K |
340
+ | Receipt explorer | Yes | Yes | Yes |
341
+ | Compliance reports | Yes | Yes | Yes |
342
+ | SSO / SAML | - | - | Yes |
343
+ | SLA | - | - | 99.9% |
344
+
345
+ No signup required for free tier. No card upfront.
346
+
347
+ [Dashboard](https://scopeblind.com) | [Docs](https://scopeblind.com/docs/protect-mcp) | [Pricing](https://scopeblind.com/pricing)
348
+
349
+ ## Telemetry
350
+
351
+ protect-mcp sends a single anonymous install beacon on first run (package name, version, OS, Node version). No PII. Disable with:
352
+
353
+ ```bash
354
+ PROTECT_MCP_TELEMETRY=off
355
+ ```
255
356
 
256
357
  ## License
257
358
 
258
359
  MIT — free to use, modify, distribute, and build upon without restriction.
259
360
 
260
- [scopeblind.com](https://scopeblind.com) · [npm](https://www.npmjs.com/package/protect-mcp) · [GitHub](https://github.com/scopeblind/scopeblind-gateway) · [IETF Draft](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/)
361
+ Built by [ScopeBlind](https://scopeblind.com) | [npm](https://www.npmjs.com/package/protect-mcp) | [GitHub](https://github.com/scopeblind/scopeblind-gateway) | [IETF Draft](https://datatracker.ietf.org/doc/draft-farley-acta-signed-receipts/)
@@ -35049,7 +35049,7 @@ function handleRequest(request) {
35049
35049
  id: request.id,
35050
35050
  result: {
35051
35051
  protocolVersion: "2024-11-05",
35052
- serverInfo: { name: "protect-mcp-demo", version: "0.2.0" },
35052
+ serverInfo: { name: "protect-mcp-demo", version: "0.5.3" },
35053
35053
  capabilities: { tools: {} }
35054
35054
  }
35055
35055
  });
@@ -696,48 +696,53 @@ async function startHookServer(options = {}) {
696
696
  }));
697
697
  });
698
698
  server.listen(port, "127.0.0.1", () => {
699
- process.stderr.write(`
699
+ const w = (s) => process.stderr.write(s);
700
+ const pad = (s, n = 46) => s.padEnd(n);
701
+ w(`
700
702
  `);
701
- process.stderr.write(`[PROTECT_MCP] \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
703
+ w(` protect-mcp v0.5.4
702
704
  `);
703
- process.stderr.write(`[PROTECT_MCP] \u2502 protect-mcp Hook Server v0.5.0 \u2502
705
+ w(` ScopeBlind \u2014 https://scopeblind.com
704
706
  `);
705
- process.stderr.write(`[PROTECT_MCP] \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
707
+ w(`
706
708
  `);
707
- process.stderr.write(`[PROTECT_MCP] \u2502 Listening: http://127.0.0.1:${String(port).padEnd(5)} \u2502
709
+ w(` Listening http://127.0.0.1:${port}
708
710
  `);
709
- process.stderr.write(`[PROTECT_MCP] \u2502 Mode: ${(enforce ? "enforce" : "shadow").padEnd(36)}\u2502
711
+ w(` Mode ${enforce ? "enforce" : "shadow"}
710
712
  `);
711
- process.stderr.write(`[PROTECT_MCP] \u2502 Policy: ${(cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none").padEnd(36)}\u2502
713
+ w(` Policy ${cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none"}
712
714
  `);
713
- process.stderr.write(`[PROTECT_MCP] \u2502 Signing: ${(isSigningEnabled() ? "Ed25519 \u2713" : "disabled").padEnd(36)}\u2502
715
+ w(` Signing ${isSigningEnabled() ? "Ed25519" : "disabled"}
714
716
  `);
715
- process.stderr.write(`[PROTECT_MCP] \u2502 Swarm: ${(state.swarmContext.team_name ? `${state.swarmContext.team_name} (${state.swarmContext.agent_type})` : "standalone").padEnd(36)}\u2502
717
+ if (state.swarmContext.team_name) {
718
+ w(` Swarm ${state.swarmContext.team_name} (${state.swarmContext.agent_type})
716
719
  `);
717
- process.stderr.write(`[PROTECT_MCP] \u2502 Sandbox: ${detectSandboxState().padEnd(36)}\u2502
720
+ }
721
+ w(`
718
722
  `);
719
- process.stderr.write(`[PROTECT_MCP] \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
723
+ w(` POST /hook Hook receiver
720
724
  `);
721
- process.stderr.write(`
725
+ w(` GET /health Health + signer info
722
726
  `);
723
- process.stderr.write(`[PROTECT_MCP] Endpoints:
727
+ w(` GET /receipts Signed receipts
724
728
  `);
725
- process.stderr.write(` POST /hook \u2014 Claude Code hook receiver
729
+ w(` GET /suggestions Cedar policy suggestions
726
730
  `);
727
- process.stderr.write(` GET /health \u2014 Health check + signer info
731
+ w(`
728
732
  `);
729
- process.stderr.write(` GET /receipts \u2014 Recent signed receipts
733
+ w(` deny is authoritative \u2014 cannot be overridden.
730
734
  `);
731
- process.stderr.write(` GET /suggestions \u2014 Auto-generated Cedar policy suggestions
735
+ w(`
732
736
  `);
733
- process.stderr.write(` GET /alerts \u2014 Config tamper alerts
737
+ const hasSlug = process.env.SCOPEBLIND_SLUG || existsSync(join(process.cwd(), ".scopeblind"));
738
+ if (!hasSlug) {
739
+ w(` Dashboard npx protect-mcp connect
734
740
  `);
735
- process.stderr.write(`
741
+ w(` Free up to 20,000 receipts/month
736
742
  `);
737
- process.stderr.write(`[PROTECT_MCP] deny decisions are AUTHORITATIVE \u2014 they cannot be overridden.
738
- `);
739
- process.stderr.write(`
743
+ w(`
740
744
  `);
745
+ }
741
746
  });
742
747
  const shutdown = () => {
743
748
  process.stderr.write("\n[PROTECT_MCP] Shutting down hook server...\n");
package/dist/cli.js CHANGED
@@ -5447,48 +5447,53 @@ async function startHookServer(options = {}) {
5447
5447
  }));
5448
5448
  });
5449
5449
  server.listen(port, "127.0.0.1", () => {
5450
- process.stderr.write(`
5450
+ const w = (s) => process.stderr.write(s);
5451
+ const pad = (s, n = 46) => s.padEnd(n);
5452
+ w(`
5451
5453
  `);
5452
- process.stderr.write(`[PROTECT_MCP] \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
5454
+ w(` protect-mcp v0.5.4
5453
5455
  `);
5454
- process.stderr.write(`[PROTECT_MCP] \u2502 protect-mcp Hook Server v0.5.0 \u2502
5456
+ w(` ScopeBlind \u2014 https://scopeblind.com
5455
5457
  `);
5456
- process.stderr.write(`[PROTECT_MCP] \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
5458
+ w(`
5457
5459
  `);
5458
- process.stderr.write(`[PROTECT_MCP] \u2502 Listening: http://127.0.0.1:${String(port).padEnd(5)} \u2502
5460
+ w(` Listening http://127.0.0.1:${port}
5459
5461
  `);
5460
- process.stderr.write(`[PROTECT_MCP] \u2502 Mode: ${(enforce ? "enforce" : "shadow").padEnd(36)}\u2502
5462
+ w(` Mode ${enforce ? "enforce" : "shadow"}
5461
5463
  `);
5462
- process.stderr.write(`[PROTECT_MCP] \u2502 Policy: ${(cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none").padEnd(36)}\u2502
5464
+ w(` Policy ${cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none"}
5463
5465
  `);
5464
- process.stderr.write(`[PROTECT_MCP] \u2502 Signing: ${(isSigningEnabled() ? "Ed25519 \u2713" : "disabled").padEnd(36)}\u2502
5466
+ w(` Signing ${isSigningEnabled() ? "Ed25519" : "disabled"}
5465
5467
  `);
5466
- process.stderr.write(`[PROTECT_MCP] \u2502 Swarm: ${(state.swarmContext.team_name ? `${state.swarmContext.team_name} (${state.swarmContext.agent_type})` : "standalone").padEnd(36)}\u2502
5468
+ if (state.swarmContext.team_name) {
5469
+ w(` Swarm ${state.swarmContext.team_name} (${state.swarmContext.agent_type})
5467
5470
  `);
5468
- process.stderr.write(`[PROTECT_MCP] \u2502 Sandbox: ${detectSandboxState().padEnd(36)}\u2502
5471
+ }
5472
+ w(`
5469
5473
  `);
5470
- process.stderr.write(`[PROTECT_MCP] \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
5474
+ w(` POST /hook Hook receiver
5471
5475
  `);
5472
- process.stderr.write(`
5476
+ w(` GET /health Health + signer info
5473
5477
  `);
5474
- process.stderr.write(`[PROTECT_MCP] Endpoints:
5478
+ w(` GET /receipts Signed receipts
5475
5479
  `);
5476
- process.stderr.write(` POST /hook \u2014 Claude Code hook receiver
5480
+ w(` GET /suggestions Cedar policy suggestions
5477
5481
  `);
5478
- process.stderr.write(` GET /health \u2014 Health check + signer info
5482
+ w(`
5479
5483
  `);
5480
- process.stderr.write(` GET /receipts \u2014 Recent signed receipts
5484
+ w(` deny is authoritative \u2014 cannot be overridden.
5481
5485
  `);
5482
- process.stderr.write(` GET /suggestions \u2014 Auto-generated Cedar policy suggestions
5486
+ w(`
5483
5487
  `);
5484
- process.stderr.write(` GET /alerts \u2014 Config tamper alerts
5488
+ const hasSlug = process.env.SCOPEBLIND_SLUG || (0, import_node_fs8.existsSync)((0, import_node_path5.join)(process.cwd(), ".scopeblind"));
5489
+ if (!hasSlug) {
5490
+ w(` Dashboard npx protect-mcp connect
5485
5491
  `);
5486
- process.stderr.write(`
5492
+ w(` Free up to 20,000 receipts/month
5487
5493
  `);
5488
- process.stderr.write(`[PROTECT_MCP] deny decisions are AUTHORITATIVE \u2014 they cannot be overridden.
5489
- `);
5490
- process.stderr.write(`
5494
+ w(`
5491
5495
  `);
5496
+ }
5492
5497
  });
5493
5498
  const shutdown = () => {
5494
5499
  process.stderr.write("\n[PROTECT_MCP] Shutting down hook server...\n");
@@ -6125,6 +6130,12 @@ Examples:
6125
6130
  protect-mcp status
6126
6131
  protect-mcp bundle --output audit.json
6127
6132
 
6133
+ Dashboard:
6134
+ npx protect-mcp connect Create a free ScopeBlind dashboard
6135
+ Free up to 20,000 receipts/month
6136
+
6137
+ https://scopeblind.com Docs, pricing, enterprise
6138
+
6128
6139
  `);
6129
6140
  }
6130
6141
  function parseArgs(argv) {
@@ -7312,7 +7323,7 @@ async function sendInstallTelemetry() {
7312
7323
  }
7313
7324
  writeFileSync2(markerFile, String(Date.now()), "utf-8");
7314
7325
  process.stderr.write(
7315
- "[protect-mcp] Anonymous install telemetry sent (disable: PROTECT_MCP_TELEMETRY=off)\n"
7326
+ "[protect-mcp] Thanks for installing! Anonymous telemetry sent (disable: PROTECT_MCP_TELEMETRY=off)\n[protect-mcp] Free dashboard: npx protect-mcp connect | https://scopeblind.com\n"
7316
7327
  );
7317
7328
  } catch {
7318
7329
  }
package/dist/cli.mjs CHANGED
@@ -75,6 +75,12 @@ Examples:
75
75
  protect-mcp status
76
76
  protect-mcp bundle --output audit.json
77
77
 
78
+ Dashboard:
79
+ npx protect-mcp connect Create a free ScopeBlind dashboard
80
+ Free up to 20,000 receipts/month
81
+
82
+ https://scopeblind.com Docs, pricing, enterprise
83
+
78
84
  `);
79
85
  }
80
86
  function parseArgs(argv) {
@@ -1262,7 +1268,7 @@ async function sendInstallTelemetry() {
1262
1268
  }
1263
1269
  writeFileSync(markerFile, String(Date.now()), "utf-8");
1264
1270
  process.stderr.write(
1265
- "[protect-mcp] Anonymous install telemetry sent (disable: PROTECT_MCP_TELEMETRY=off)\n"
1271
+ "[protect-mcp] Thanks for installing! Anonymous telemetry sent (disable: PROTECT_MCP_TELEMETRY=off)\n[protect-mcp] Free dashboard: npx protect-mcp connect | https://scopeblind.com\n"
1266
1272
  );
1267
1273
  } catch {
1268
1274
  }
@@ -35073,7 +35073,7 @@ function handleRequest(request) {
35073
35073
  id: request.id,
35074
35074
  result: {
35075
35075
  protocolVersion: "2024-11-05",
35076
- serverInfo: { name: "protect-mcp-demo", version: "0.2.0" },
35076
+ serverInfo: { name: "protect-mcp-demo", version: "0.5.3" },
35077
35077
  capabilities: { tools: {} }
35078
35078
  }
35079
35079
  });
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createSandboxServer
4
- } from "./chunk-SU2FZH7U.mjs";
4
+ } from "./chunk-J6L4XCTE.mjs";
5
5
  import "./chunk-PQJP2ZCI.mjs";
6
6
  export {
7
7
  createSandboxServer
@@ -1097,48 +1097,53 @@ async function startHookServer(options = {}) {
1097
1097
  }));
1098
1098
  });
1099
1099
  server.listen(port, "127.0.0.1", () => {
1100
- process.stderr.write(`
1100
+ const w = (s) => process.stderr.write(s);
1101
+ const pad = (s, n = 46) => s.padEnd(n);
1102
+ w(`
1101
1103
  `);
1102
- process.stderr.write(`[PROTECT_MCP] \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
1104
+ w(` protect-mcp v0.5.4
1103
1105
  `);
1104
- process.stderr.write(`[PROTECT_MCP] \u2502 protect-mcp Hook Server v0.5.0 \u2502
1106
+ w(` ScopeBlind \u2014 https://scopeblind.com
1105
1107
  `);
1106
- process.stderr.write(`[PROTECT_MCP] \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
1108
+ w(`
1107
1109
  `);
1108
- process.stderr.write(`[PROTECT_MCP] \u2502 Listening: http://127.0.0.1:${String(port).padEnd(5)} \u2502
1110
+ w(` Listening http://127.0.0.1:${port}
1109
1111
  `);
1110
- process.stderr.write(`[PROTECT_MCP] \u2502 Mode: ${(enforce ? "enforce" : "shadow").padEnd(36)}\u2502
1112
+ w(` Mode ${enforce ? "enforce" : "shadow"}
1111
1113
  `);
1112
- process.stderr.write(`[PROTECT_MCP] \u2502 Policy: ${(cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none").padEnd(36)}\u2502
1114
+ w(` Policy ${cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none"}
1113
1115
  `);
1114
- process.stderr.write(`[PROTECT_MCP] \u2502 Signing: ${(isSigningEnabled() ? "Ed25519 \u2713" : "disabled").padEnd(36)}\u2502
1116
+ w(` Signing ${isSigningEnabled() ? "Ed25519" : "disabled"}
1115
1117
  `);
1116
- process.stderr.write(`[PROTECT_MCP] \u2502 Swarm: ${(state.swarmContext.team_name ? `${state.swarmContext.team_name} (${state.swarmContext.agent_type})` : "standalone").padEnd(36)}\u2502
1118
+ if (state.swarmContext.team_name) {
1119
+ w(` Swarm ${state.swarmContext.team_name} (${state.swarmContext.agent_type})
1117
1120
  `);
1118
- process.stderr.write(`[PROTECT_MCP] \u2502 Sandbox: ${detectSandboxState().padEnd(36)}\u2502
1121
+ }
1122
+ w(`
1119
1123
  `);
1120
- process.stderr.write(`[PROTECT_MCP] \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
1124
+ w(` POST /hook Hook receiver
1121
1125
  `);
1122
- process.stderr.write(`
1126
+ w(` GET /health Health + signer info
1123
1127
  `);
1124
- process.stderr.write(`[PROTECT_MCP] Endpoints:
1128
+ w(` GET /receipts Signed receipts
1125
1129
  `);
1126
- process.stderr.write(` POST /hook \u2014 Claude Code hook receiver
1130
+ w(` GET /suggestions Cedar policy suggestions
1127
1131
  `);
1128
- process.stderr.write(` GET /health \u2014 Health check + signer info
1132
+ w(`
1129
1133
  `);
1130
- process.stderr.write(` GET /receipts \u2014 Recent signed receipts
1134
+ w(` deny is authoritative \u2014 cannot be overridden.
1131
1135
  `);
1132
- process.stderr.write(` GET /suggestions \u2014 Auto-generated Cedar policy suggestions
1136
+ w(`
1133
1137
  `);
1134
- process.stderr.write(` GET /alerts \u2014 Config tamper alerts
1138
+ const hasSlug = process.env.SCOPEBLIND_SLUG || (0, import_node_fs5.existsSync)((0, import_node_path3.join)(process.cwd(), ".scopeblind"));
1139
+ if (!hasSlug) {
1140
+ w(` Dashboard npx protect-mcp connect
1135
1141
  `);
1136
- process.stderr.write(`
1142
+ w(` Free up to 20,000 receipts/month
1137
1143
  `);
1138
- process.stderr.write(`[PROTECT_MCP] deny decisions are AUTHORITATIVE \u2014 they cannot be overridden.
1139
- `);
1140
- process.stderr.write(`
1144
+ w(`
1141
1145
  `);
1146
+ }
1142
1147
  });
1143
1148
  const shutdown = () => {
1144
1149
  process.stderr.write("\n[PROTECT_MCP] Shutting down hook server...\n");
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  startHookServer
3
- } from "./chunk-HFM6K7E4.mjs";
3
+ } from "./chunk-SPHLVRJ2.mjs";
4
4
  import "./chunk-YTBC72JJ.mjs";
5
5
  import "./chunk-PQJP2ZCI.mjs";
6
6
  export {
package/dist/index.d.mts CHANGED
@@ -2289,7 +2289,7 @@ declare function createAttestationField(attestation: EvidenceAttestation): {
2289
2289
  * // Create a C2PA manifest from an Acta receipt chain
2290
2290
  * const manifest = createC2PAManifest(receipts, {
2291
2291
  * title: 'AI-generated report',
2292
- * generator: 'protect-mcp v0.3.3',
2292
+ * generator: 'protect-mcp v0.5.3',
2293
2293
  * });
2294
2294
  *
2295
2295
  * // The manifest can be embedded in images, PDFs, or documents
package/dist/index.d.ts CHANGED
@@ -2289,7 +2289,7 @@ declare function createAttestationField(attestation: EvidenceAttestation): {
2289
2289
  * // Create a C2PA manifest from an Acta receipt chain
2290
2290
  * const manifest = createC2PAManifest(receipts, {
2291
2291
  * title: 'AI-generated report',
2292
- * generator: 'protect-mcp v0.3.3',
2292
+ * generator: 'protect-mcp v0.5.3',
2293
2293
  * });
2294
2294
  *
2295
2295
  * // The manifest can be embedded in images, PDFs, or documents
package/dist/index.js CHANGED
@@ -37962,48 +37962,53 @@ async function startHookServer(options = {}) {
37962
37962
  }));
37963
37963
  });
37964
37964
  server.listen(port, "127.0.0.1", () => {
37965
- process.stderr.write(`
37965
+ const w = (s) => process.stderr.write(s);
37966
+ const pad = (s, n = 46) => s.padEnd(n);
37967
+ w(`
37966
37968
  `);
37967
- process.stderr.write(`[PROTECT_MCP] \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510
37969
+ w(` protect-mcp v0.5.4
37968
37970
  `);
37969
- process.stderr.write(`[PROTECT_MCP] \u2502 protect-mcp Hook Server v0.5.0 \u2502
37971
+ w(` ScopeBlind \u2014 https://scopeblind.com
37970
37972
  `);
37971
- process.stderr.write(`[PROTECT_MCP] \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524
37973
+ w(`
37972
37974
  `);
37973
- process.stderr.write(`[PROTECT_MCP] \u2502 Listening: http://127.0.0.1:${String(port).padEnd(5)} \u2502
37975
+ w(` Listening http://127.0.0.1:${port}
37974
37976
  `);
37975
- process.stderr.write(`[PROTECT_MCP] \u2502 Mode: ${(enforce ? "enforce" : "shadow").padEnd(36)}\u2502
37977
+ w(` Mode ${enforce ? "enforce" : "shadow"}
37976
37978
  `);
37977
- process.stderr.write(`[PROTECT_MCP] \u2502 Policy: ${(cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none").padEnd(36)}\u2502
37979
+ w(` Policy ${cedarPolicies ? `Cedar (${cedarPolicies.fileCount} files)` : jsonPolicy ? "JSON" : "none"}
37978
37980
  `);
37979
- process.stderr.write(`[PROTECT_MCP] \u2502 Signing: ${(isSigningEnabled() ? "Ed25519 \u2713" : "disabled").padEnd(36)}\u2502
37981
+ w(` Signing ${isSigningEnabled() ? "Ed25519" : "disabled"}
37980
37982
  `);
37981
- process.stderr.write(`[PROTECT_MCP] \u2502 Swarm: ${(state.swarmContext.team_name ? `${state.swarmContext.team_name} (${state.swarmContext.agent_type})` : "standalone").padEnd(36)}\u2502
37983
+ if (state.swarmContext.team_name) {
37984
+ w(` Swarm ${state.swarmContext.team_name} (${state.swarmContext.agent_type})
37982
37985
  `);
37983
- process.stderr.write(`[PROTECT_MCP] \u2502 Sandbox: ${detectSandboxState().padEnd(36)}\u2502
37986
+ }
37987
+ w(`
37984
37988
  `);
37985
- process.stderr.write(`[PROTECT_MCP] \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518
37989
+ w(` POST /hook Hook receiver
37986
37990
  `);
37987
- process.stderr.write(`
37991
+ w(` GET /health Health + signer info
37988
37992
  `);
37989
- process.stderr.write(`[PROTECT_MCP] Endpoints:
37993
+ w(` GET /receipts Signed receipts
37990
37994
  `);
37991
- process.stderr.write(` POST /hook \u2014 Claude Code hook receiver
37995
+ w(` GET /suggestions Cedar policy suggestions
37992
37996
  `);
37993
- process.stderr.write(` GET /health \u2014 Health check + signer info
37997
+ w(`
37994
37998
  `);
37995
- process.stderr.write(` GET /receipts \u2014 Recent signed receipts
37999
+ w(` deny is authoritative \u2014 cannot be overridden.
37996
38000
  `);
37997
- process.stderr.write(` GET /suggestions \u2014 Auto-generated Cedar policy suggestions
38001
+ w(`
37998
38002
  `);
37999
- process.stderr.write(` GET /alerts \u2014 Config tamper alerts
38003
+ const hasSlug = process.env.SCOPEBLIND_SLUG || (0, import_node_fs9.existsSync)((0, import_node_path5.join)(process.cwd(), ".scopeblind"));
38004
+ if (!hasSlug) {
38005
+ w(` Dashboard npx protect-mcp connect
38000
38006
  `);
38001
- process.stderr.write(`
38007
+ w(` Free up to 20,000 receipts/month
38002
38008
  `);
38003
- process.stderr.write(`[PROTECT_MCP] deny decisions are AUTHORITATIVE \u2014 they cannot be overridden.
38004
- `);
38005
- process.stderr.write(`
38009
+ w(`
38006
38010
  `);
38011
+ }
38007
38012
  });
38008
38013
  const shutdown = () => {
38009
38014
  process.stderr.write("\n[PROTECT_MCP] Shutting down hook server...\n");
@@ -39961,7 +39966,7 @@ function handleRequest(request) {
39961
39966
  id: request.id,
39962
39967
  result: {
39963
39968
  protocolVersion: "2024-11-05",
39964
- serverInfo: { name: "protect-mcp-demo", version: "0.2.0" },
39969
+ serverInfo: { name: "protect-mcp-demo", version: "0.5.3" },
39965
39970
  capabilities: { tools: {} }
39966
39971
  }
39967
39972
  });
package/dist/index.mjs CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-BYYWYSHM.mjs";
22
22
  import {
23
23
  createSandboxServer
24
- } from "./chunk-SU2FZH7U.mjs";
24
+ } from "./chunk-J6L4XCTE.mjs";
25
25
  import {
26
26
  BUILTIN_PATTERNS,
27
27
  generateHookSettings,
@@ -30,7 +30,7 @@ import {
30
30
  } from "./chunk-NMZPXXL3.mjs";
31
31
  import {
32
32
  startHookServer
33
- } from "./chunk-HFM6K7E4.mjs";
33
+ } from "./chunk-SPHLVRJ2.mjs";
34
34
  import {
35
35
  checkRateLimit,
36
36
  evaluateCedar,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "protect-mcp",
3
- "version": "0.5.3",
4
- "mcpName": "io.github.tomjwxf/protect-mcp",
3
+ "version": "0.5.5",
4
+ "mcpName": "com.scopeblind/protect-mcp",
5
5
  "description": "Enterprise security gateway for MCP servers and Claude Code hooks. Cedar policies, Ed25519-signed receipts, swarm tracking, and tamper detection. Shadow or enforce mode.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",