@fidacy/mcp 0.1.9 → 0.1.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/CHANGELOG.md CHANGED
@@ -74,3 +74,24 @@ semantic versioning.
74
74
  - One install delivers both the signed verdict (assess_action) and the
75
75
  non-custodial payment firewall (request_payment), with the same signed,
76
76
  publicly verifiable proof as the SDK.
77
+
78
+ ## 0.1.10 — 2026-07-02
79
+
80
+ - Telemetry: `shell` channel attribution (mcp | openclaw-plugin | crabtrap | sdk)
81
+ and `client_version` injected from package.json at build time (0.1.5 had shipped
82
+ stale through 0.1.9 in telemetry AND provision).
83
+ - DENY responses now point to the `upgrade` tool (free account, signed anchored
84
+ proof of every block).
85
+ - Onboarding: first-run `~/.fidacy/config.json` now writes the mandate template
86
+ explicitly (payees/categories/currency/caps) — adding a trusted payee is a
87
+ visible one-line edit; friendlier first-boot message (no more "dev mode" scare).
88
+
89
+ ## 0.1.11 — 2026-07-02
90
+
91
+ - Upgrade micro-triggers, elegant by doctrine: fire only at value-proven moments
92
+ (first block, first duplicate-invoice/BEC catch, 10th gated action, one week
93
+ protected), each ONCE per install ever (persisted in config.json) — the free
94
+ tier stays fully usable in silence. The 0.1.10 every-DENY nudge is replaced.
95
+ - verify_mandate/get_audit_proof gain one informational closing line each;
96
+ assess_action's missing-key error now offers the free-key path.
97
+ - config.json gains created_at + nudge/decision state (preserved on read).
package/dist/core.js CHANGED
@@ -213,7 +213,7 @@ var DevFidacyCore = class {
213
213
  this.priv = kp.privateKey;
214
214
  this.pubPem = publicKeyPem(kp.publicKey);
215
215
  if (kp.ephemeral)
216
- console.error("[fidacy] dev mode: ephemeral signing key. Production: set FIDACY_SIGNING_KEY_B64, or FIDACY_MODE=http + FIDACY_API_URL + FIDACY_API_KEY to use the live core.");
216
+ console.error("[fidacy] local firewall active, deny-by-default. Grants are signed with a per-session key (fine for local use); set FIDACY_SIGNING_KEY_B64 for a stable key, or FIDACY_MODE=http to use the hosted core.");
217
217
  this.mandate = opts.mandate;
218
218
  this.store = new FileAuditStore(opts.auditLogPath ?? "./fidacy-audit.log");
219
219
  this.onDecision = opts.onDecision;
@@ -337,7 +337,12 @@ function readConfig() {
337
337
  anon_id: raw.anon_id,
338
338
  tier: raw.tier === "paid" ? "paid" : "free",
339
339
  api_key: typeof raw.api_key === "string" ? raw.api_key : null,
340
- mandate: raw.mandate
340
+ mandate: raw.mandate,
341
+ // Install-state passthrough: dropping these on a read→write cycle would
342
+ // reset every once-per-install nudge into an every-time nag.
343
+ created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
344
+ nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
345
+ decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
341
346
  };
342
347
  } catch {
343
348
  return null;
@@ -357,7 +362,8 @@ function resolveMandateRules(cfg) {
357
362
  }
358
363
 
359
364
  // src/telemetry.ts
360
- var CLIENT_VERSION = "0.1.5";
365
+ var CLIENT_VERSION = true ? "0.1.11" : "dev";
366
+ var currentShell = "mcp";
361
367
  function telemetryEnabled() {
362
368
  const v = (process.env.FIDACY_DISABLE_TELEMETRY ?? "").trim().toLowerCase();
363
369
  return !(v === "1" || v === "true" || v === "yes");
@@ -383,7 +389,7 @@ function resultOf(status, violatedRule) {
383
389
  }
384
390
  function record(type, result) {
385
391
  if (!telemetryEnabled()) return;
386
- buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, ...result ? { result } : {} });
392
+ buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, shell: currentShell, ...result ? { result } : {} });
387
393
  if (!flushTimer) {
388
394
  flushTimer = setTimeout(() => {
389
395
  void flush();
package/dist/index.js CHANGED
@@ -220,7 +220,7 @@ var DevFidacyCore = class {
220
220
  this.priv = kp.privateKey;
221
221
  this.pubPem = publicKeyPem(kp.publicKey);
222
222
  if (kp.ephemeral)
223
- console.error("[fidacy] dev mode: ephemeral signing key. Production: set FIDACY_SIGNING_KEY_B64, or FIDACY_MODE=http + FIDACY_API_URL + FIDACY_API_KEY to use the live core.");
223
+ console.error("[fidacy] local firewall active, deny-by-default. Grants are signed with a per-session key (fine for local use); set FIDACY_SIGNING_KEY_B64 for a stable key, or FIDACY_MODE=http to use the hosted core.");
224
224
  this.mandate = opts.mandate;
225
225
  this.store = new FileAuditStore(opts.auditLogPath ?? "./fidacy-audit.log");
226
226
  this.onDecision = opts.onDecision;
@@ -345,7 +345,12 @@ function readConfig() {
345
345
  anon_id: raw.anon_id,
346
346
  tier: raw.tier === "paid" ? "paid" : "free",
347
347
  api_key: typeof raw.api_key === "string" ? raw.api_key : null,
348
- mandate: raw.mandate
348
+ mandate: raw.mandate,
349
+ // Install-state passthrough: dropping these on a read→write cycle would
350
+ // reset every once-per-install nudge into an every-time nag.
351
+ created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
352
+ nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
353
+ decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
349
354
  };
350
355
  } catch {
351
356
  return null;
@@ -359,7 +364,13 @@ function writeConfig(cfg) {
359
364
  function ensureState() {
360
365
  const existing = readConfig();
361
366
  if (existing) return { config: existing, firstRun: false };
362
- const config = { anon_id: randomUUID2(), tier: "free", api_key: null };
367
+ const config = {
368
+ anon_id: randomUUID2(),
369
+ tier: "free",
370
+ api_key: null,
371
+ mandate: { payees: [], categories: ["*"], currency: "USD", perTxMax: 2500, maxTotal: 1e4 },
372
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
373
+ };
363
374
  try {
364
375
  writeConfig(config);
365
376
  } catch {
@@ -380,7 +391,8 @@ function resolveMandateRules(cfg) {
380
391
  }
381
392
 
382
393
  // src/telemetry.ts
383
- var CLIENT_VERSION = "0.1.5";
394
+ var CLIENT_VERSION = true ? "0.1.11" : "dev";
395
+ var currentShell = "mcp";
384
396
  function telemetryEnabled() {
385
397
  const v = (process.env.FIDACY_DISABLE_TELEMETRY ?? "").trim().toLowerCase();
386
398
  return !(v === "1" || v === "true" || v === "yes");
@@ -406,7 +418,7 @@ function resultOf(status, violatedRule) {
406
418
  }
407
419
  function record(type, result) {
408
420
  if (!telemetryEnabled()) return;
409
- buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, ...result ? { result } : {} });
421
+ buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, shell: currentShell, ...result ? { result } : {} });
410
422
  if (!flushTimer) {
411
423
  flushTimer = setTimeout(() => {
412
424
  void flush();
@@ -603,7 +615,7 @@ async function postOnce(fetchImpl, url, headers, payload, timeoutMs) {
603
615
  }
604
616
 
605
617
  // src/provision.ts
606
- var CLIENT_VERSION2 = "0.1.5";
618
+ var CLIENT_VERSION2 = true ? "0.1.11" : "dev";
607
619
  function provisionEnabled() {
608
620
  const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
609
621
  return !(v === "1" || v === "true" || v === "yes");
@@ -650,6 +662,55 @@ function requestUpgrade() {
650
662
  return { url: upgradeUrl(), anonId: anonId2 };
651
663
  }
652
664
 
665
+ // src/nudges.ts
666
+ function nudgeOnce(key) {
667
+ const cfg = readConfig();
668
+ if (!cfg) return false;
669
+ if (cfg.nudges?.[key]) return false;
670
+ cfg.nudges = { ...cfg.nudges ?? {}, [key]: true };
671
+ try {
672
+ writeConfig(cfg);
673
+ } catch {
674
+ return false;
675
+ }
676
+ return true;
677
+ }
678
+ function bumpDecisionCount() {
679
+ const cfg = readConfig();
680
+ if (!cfg) return 0;
681
+ const n = (cfg.decisions_count ?? 0) + 1;
682
+ cfg.decisions_count = n;
683
+ try {
684
+ writeConfig(cfg);
685
+ } catch {
686
+ }
687
+ return n;
688
+ }
689
+ function installAgeDays() {
690
+ const t = Date.parse(readConfig()?.created_at ?? "");
691
+ if (Number.isNaN(t)) return 0;
692
+ return Math.floor((Date.now() - t) / 864e5);
693
+ }
694
+ function decisionNudge(status, violatedRule, upgradeToolName) {
695
+ const count = bumpDecisionCount();
696
+ if (status === "DENY" && violatedRule?.startsWith("duplicate_invoice") && nudgeOnce("bec_catch")) {
697
+ return `That was a duplicate-invoice (BEC) catch \u2014 the #1 payment fraud. On a free account every block like this is server-signed and anchored to Bitcoin: court-grade evidence. Call the ${upgradeToolName} tool to start.`;
698
+ }
699
+ if (status === "DENY" && nudgeOnce("first_deny")) {
700
+ return `Fidacy just blocked this for you \u2014 for server-signed, anchored proof of every block (free account, local history migrates), call the ${upgradeToolName} tool.`;
701
+ }
702
+ if (count === 10 && nudgeOnce("milestone_10")) {
703
+ return `That's 10 actions gated on this install. For a signed, Bitcoin-anchored history of all of them (free account), call the ${upgradeToolName} tool.`;
704
+ }
705
+ return null;
706
+ }
707
+ function weekOneBootNudge(upgradeToolName) {
708
+ if (installAgeDays() >= 7 && nudgeOnce("week_1")) {
709
+ return ` One week protected \u2014 anchor your history to Bitcoin with a free account: the ${upgradeToolName} tool starts it.`;
710
+ }
711
+ return null;
712
+ }
713
+
653
714
  // src/index.ts
654
715
  var state = ensureState();
655
716
  var core = makeCore();
@@ -683,8 +744,10 @@ server.registerTool(
683
744
  const req = args;
684
745
  const d = await core.decide(req, subject);
685
746
  const out = { status: d.status, decisionId: d.decisionId, grant: d.grant, violatedRule: d.violatedRule };
686
- const human = d.status === "ALLOW" ? `ALLOW (decision ${d.decisionId})${req.invoiceRef ? ` for invoice ${req.invoiceRef}` : ""}. To settle, call execute_payment with the SAME payee, amount, currency, and idempotencyKey, and set "grant" to EXACTLY this signed value:
747
+ const base = d.status === "ALLOW" ? `ALLOW (decision ${d.decisionId})${req.invoiceRef ? ` for invoice ${req.invoiceRef}` : ""}. To settle, call execute_payment with the SAME payee, amount, currency, and idempotencyKey, and set "grant" to EXACTLY this signed value:
687
748
  ${d.grant}` : `DENY (decision ${d.decisionId}). Rule violated: ${d.violatedRule}. No grant issued, this payment cannot proceed. The denial itself is recorded in the tamper-evident, hash-chained audit: call get_audit_proof with decisionId ${d.decisionId} for the proof of what was blocked.`;
749
+ const nudge = decisionNudge(d.status, d.violatedRule, "upgrade");
750
+ const human = nudge ? `${base} ${nudge}` : base;
688
751
  return { content: [{ type: "text", text: human }], structuredContent: out };
689
752
  }
690
753
  );
@@ -699,7 +762,8 @@ server.registerTool(
699
762
  async () => {
700
763
  const m = await core.getMandate(subject);
701
764
  const payload = { mandate: m, fidacyPublicKey: core.publicKey() };
702
- return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }], structuredContent: payload };
765
+ const text = JSON.stringify(payload, null, 2) + "\n\nThis mandate is local (free tier). Hosted mandates add team governance and server-signed verdicts \u2014 the upgrade tool starts a free account.";
766
+ return { content: [{ type: "text", text }], structuredContent: payload };
703
767
  }
704
768
  );
705
769
  server.registerTool(
@@ -713,7 +777,8 @@ server.registerTool(
713
777
  async ({ decisionId }) => {
714
778
  const proof = await core.getProof(decisionId);
715
779
  if (!proof) return { content: [{ type: "text", text: `No proof found for ${decisionId}` }], isError: true };
716
- return { content: [{ type: "text", text: JSON.stringify(proof, null, 2) }], structuredContent: proof };
780
+ const text = JSON.stringify(proof, null, 2) + "\n\nThis proof lives on this machine. On a free hosted account the chain is anchored to Bitcoin \u2014 verifiable by anyone, forever, even against Fidacy (the upgrade tool starts it).";
781
+ return { content: [{ type: "text", text }], structuredContent: proof };
717
782
  }
718
783
  );
719
784
  server.registerTool(
@@ -739,7 +804,7 @@ server.registerTool(
739
804
  content: [
740
805
  {
741
806
  type: "text",
742
- text: "assess_action requires FIDACY_ENGINE_API_KEY (an fky_live_/fky_test_ key with assess:write). Set it to enable signed verdicts."
807
+ text: "assess_action needs an engine key \u2014 free in about a minute: call the upgrade tool (your usage history migrates), or set FIDACY_ENGINE_API_KEY if you already have one."
743
808
  }
744
809
  ],
745
810
  isError: true
@@ -799,7 +864,8 @@ async function main() {
799
864
  void autoProvision();
800
865
  const verdictHint = process.env.FIDACY_ENGINE_API_KEY ? "" : " Set FIDACY_ENGINE_API_KEY to enable verdicts (assess_action).";
801
866
  const tierHint = state.firstRun ? " First run: free local tier active (deny-unknown payee + cap). Add trusted payees in ~/.fidacy/config.json." : ` Tier: ${state.config.tier} (local-first).`;
802
- console.error("[fidacy] @fidacy/mcp ready on stdio: signed verdict + payment firewall." + tierHint + verdictHint);
867
+ const weekNudge = weekOneBootNudge("upgrade") ?? "";
868
+ console.error("[fidacy] @fidacy/mcp ready on stdio: signed verdict + payment firewall." + tierHint + verdictHint + weekNudge);
803
869
  }
804
870
  main().catch((e) => {
805
871
  console.error("[fidacy] fatal:", e);
package/dist/lib.js CHANGED
@@ -339,7 +339,7 @@ var DevFidacyCore = class {
339
339
  this.priv = kp.privateKey;
340
340
  this.pubPem = publicKeyPem(kp.publicKey);
341
341
  if (kp.ephemeral)
342
- console.error("[fidacy] dev mode: ephemeral signing key. Production: set FIDACY_SIGNING_KEY_B64, or FIDACY_MODE=http + FIDACY_API_URL + FIDACY_API_KEY to use the live core.");
342
+ console.error("[fidacy] local firewall active, deny-by-default. Grants are signed with a per-session key (fine for local use); set FIDACY_SIGNING_KEY_B64 for a stable key, or FIDACY_MODE=http to use the hosted core.");
343
343
  this.mandate = opts.mandate;
344
344
  this.store = new FileAuditStore(opts.auditLogPath ?? "./fidacy-audit.log");
345
345
  this.onDecision = opts.onDecision;
@@ -430,6 +430,7 @@ var HttpFidacyCore = class {
430
430
  };
431
431
 
432
432
  // src/config.ts
433
+ import { randomUUID as randomUUID3 } from "node:crypto";
433
434
  import { homedir } from "node:os";
434
435
  import { join } from "node:path";
435
436
  import {
@@ -463,12 +464,38 @@ function readConfig() {
463
464
  anon_id: raw.anon_id,
464
465
  tier: raw.tier === "paid" ? "paid" : "free",
465
466
  api_key: typeof raw.api_key === "string" ? raw.api_key : null,
466
- mandate: raw.mandate
467
+ mandate: raw.mandate,
468
+ // Install-state passthrough: dropping these on a read→write cycle would
469
+ // reset every once-per-install nudge into an every-time nag.
470
+ created_at: typeof raw.created_at === "string" ? raw.created_at : void 0,
471
+ nudges: raw.nudges && typeof raw.nudges === "object" ? raw.nudges : void 0,
472
+ decisions_count: typeof raw.decisions_count === "number" ? raw.decisions_count : void 0
467
473
  };
468
474
  } catch {
469
475
  return null;
470
476
  }
471
477
  }
478
+ function writeConfig(cfg) {
479
+ const dir = configDir();
480
+ mkdirSync(dir, { recursive: true, mode: 448 });
481
+ writeFileSync(configPath(), JSON.stringify(cfg, null, 2), { mode: 384 });
482
+ }
483
+ function ensureState() {
484
+ const existing = readConfig();
485
+ if (existing) return { config: existing, firstRun: false };
486
+ const config = {
487
+ anon_id: randomUUID3(),
488
+ tier: "free",
489
+ api_key: null,
490
+ mandate: { payees: [], categories: ["*"], currency: "USD", perTxMax: 2500, maxTotal: 1e4 },
491
+ created_at: (/* @__PURE__ */ new Date()).toISOString()
492
+ };
493
+ try {
494
+ writeConfig(config);
495
+ } catch {
496
+ }
497
+ return { config, firstRun: true };
498
+ }
472
499
  function resolveMandateRules(cfg) {
473
500
  const m = cfg?.mandate ?? {};
474
501
  const envList = (v) => v === void 0 ? void 0 : v.split(",").map((s) => s.trim()).filter(Boolean);
@@ -483,7 +510,11 @@ function resolveMandateRules(cfg) {
483
510
  }
484
511
 
485
512
  // src/telemetry.ts
486
- var CLIENT_VERSION = "0.1.5";
513
+ var CLIENT_VERSION = true ? "0.1.11" : "dev";
514
+ var currentShell = "mcp";
515
+ function setTelemetryShell(shell) {
516
+ currentShell = shell;
517
+ }
487
518
  function telemetryEnabled() {
488
519
  const v = (process.env.FIDACY_DISABLE_TELEMETRY ?? "").trim().toLowerCase();
489
520
  return !(v === "1" || v === "true" || v === "yes");
@@ -509,7 +540,7 @@ function resultOf(status, violatedRule) {
509
540
  }
510
541
  function record(type, result) {
511
542
  if (!telemetryEnabled()) return;
512
- buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, ...result ? { result } : {} });
543
+ buffer.push({ type, ts: (/* @__PURE__ */ new Date()).toISOString(), client_version: CLIENT_VERSION, shell: currentShell, ...result ? { result } : {} });
513
544
  if (!flushTimer) {
514
545
  flushTimer = setTimeout(() => {
515
546
  void flush();
@@ -517,7 +548,10 @@ function record(type, result) {
517
548
  if (typeof flushTimer.unref === "function") flushTimer.unref();
518
549
  }
519
550
  }
551
+ var recordInstall = () => record("install");
552
+ var recordAgentActive = () => record("agent_active");
520
553
  var recordDecision = (status, violatedRule) => record("decision", resultOf(status, violatedRule));
554
+ var recordUpgradeIntent = () => record("upgrade_intent");
521
555
  async function flush() {
522
556
  if (flushTimer) {
523
557
  clearTimeout(flushTimer);
@@ -585,24 +619,133 @@ function makeCore() {
585
619
  onDecision: (d) => recordDecision(d.status, d.violatedRule)
586
620
  });
587
621
  }
622
+
623
+ // src/upgrade.ts
624
+ function upgradeUrl() {
625
+ const base = (process.env.FIDACY_APP_URL ?? "https://app.fidacy.com").replace(/\/$/, "");
626
+ const anon = readConfig()?.anon_id ?? "";
627
+ return `${base}/upgrade?anon=${encodeURIComponent(anon)}`;
628
+ }
629
+ function requestUpgrade() {
630
+ recordUpgradeIntent();
631
+ const anonId2 = readConfig()?.anon_id ?? "";
632
+ return { url: upgradeUrl(), anonId: anonId2 };
633
+ }
634
+
635
+ // src/provision.ts
636
+ var CLIENT_VERSION2 = true ? "0.1.11" : "dev";
637
+ function provisionEnabled() {
638
+ const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
639
+ return !(v === "1" || v === "true" || v === "yes");
640
+ }
641
+ function endpoint2() {
642
+ const base = (process.env.FIDACY_ENGINE_URL ?? "https://api.fidacy.com").replace(/\/$/, "");
643
+ return `${base}/v1/provision`;
644
+ }
645
+ async function autoProvision() {
646
+ if (!provisionEnabled()) return "skipped";
647
+ const cfg = readConfig();
648
+ if (!cfg) return "skipped";
649
+ if (cfg.api_key) return "skipped";
650
+ try {
651
+ const res = await fetch(endpoint2(), {
652
+ method: "POST",
653
+ headers: { "content-type": "application/json" },
654
+ body: JSON.stringify({ anon_id: cfg.anon_id, client_version: CLIENT_VERSION2 })
655
+ });
656
+ if (res.status === 429) return "rate_limited";
657
+ if (!res.ok) return "failed";
658
+ const data = await res.json();
659
+ if (typeof data.api_key !== "string" || !data.api_key) return "failed";
660
+ writeConfig({
661
+ ...cfg,
662
+ api_key: data.api_key,
663
+ tier: data.tier === "paid" ? "paid" : "free"
664
+ });
665
+ return "provisioned";
666
+ } catch {
667
+ return "failed";
668
+ }
669
+ }
670
+
671
+ // src/nudges.ts
672
+ function nudgeOnce(key) {
673
+ const cfg = readConfig();
674
+ if (!cfg) return false;
675
+ if (cfg.nudges?.[key]) return false;
676
+ cfg.nudges = { ...cfg.nudges ?? {}, [key]: true };
677
+ try {
678
+ writeConfig(cfg);
679
+ } catch {
680
+ return false;
681
+ }
682
+ return true;
683
+ }
684
+ function bumpDecisionCount() {
685
+ const cfg = readConfig();
686
+ if (!cfg) return 0;
687
+ const n = (cfg.decisions_count ?? 0) + 1;
688
+ cfg.decisions_count = n;
689
+ try {
690
+ writeConfig(cfg);
691
+ } catch {
692
+ }
693
+ return n;
694
+ }
695
+ function installAgeDays() {
696
+ const t = Date.parse(readConfig()?.created_at ?? "");
697
+ if (Number.isNaN(t)) return 0;
698
+ return Math.floor((Date.now() - t) / 864e5);
699
+ }
700
+ function decisionNudge(status, violatedRule, upgradeToolName) {
701
+ const count = bumpDecisionCount();
702
+ if (status === "DENY" && violatedRule?.startsWith("duplicate_invoice") && nudgeOnce("bec_catch")) {
703
+ return `That was a duplicate-invoice (BEC) catch \u2014 the #1 payment fraud. On a free account every block like this is server-signed and anchored to Bitcoin: court-grade evidence. Call the ${upgradeToolName} tool to start.`;
704
+ }
705
+ if (status === "DENY" && nudgeOnce("first_deny")) {
706
+ return `Fidacy just blocked this for you \u2014 for server-signed, anchored proof of every block (free account, local history migrates), call the ${upgradeToolName} tool.`;
707
+ }
708
+ if (count === 10 && nudgeOnce("milestone_10")) {
709
+ return `That's 10 actions gated on this install. For a signed, Bitcoin-anchored history of all of them (free account), call the ${upgradeToolName} tool.`;
710
+ }
711
+ return null;
712
+ }
713
+ function weekOneBootNudge(upgradeToolName) {
714
+ if (installAgeDays() >= 7 && nudgeOnce("week_1")) {
715
+ return ` One week protected \u2014 anchor your history to Bitcoin with a free account: the ${upgradeToolName} tool starts it.`;
716
+ }
717
+ return null;
718
+ }
588
719
  export {
589
720
  DevFidacyCore,
590
721
  FileAuditStore,
591
722
  GrantEnforcingExecutor,
592
723
  HttpFidacyCore,
593
724
  ReferenceRail,
725
+ autoProvision,
594
726
  canonInvoice,
727
+ decisionNudge,
728
+ ensureState,
595
729
  evaluate,
596
730
  httpRedeem,
731
+ installAgeDays,
597
732
  loadOrGenerateKeyPair,
598
733
  lookalikePayee,
599
734
  makeCore,
735
+ nudgeOnce,
600
736
  publicKeyPem,
737
+ readConfig,
738
+ recordAgentActive,
739
+ recordInstall,
740
+ requestUpgrade,
601
741
  requireHttpsBase,
742
+ setTelemetryShell,
602
743
  sha256,
603
744
  sign,
604
745
  stableStringify,
746
+ upgradeUrl,
605
747
  validateRequest,
606
748
  verify,
607
- verifyGrant
749
+ verifyGrant,
750
+ weekOneBootNudge
608
751
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fidacy/mcp",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Fidacy action firewall for AI agents. Mandate-gated payment authorization as an MCP server.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://fidacy.com",
@@ -36,12 +36,6 @@
36
36
  "publishConfig": {
37
37
  "access": "public"
38
38
  },
39
- "scripts": {
40
- "build": "node scripts/bundle.mjs",
41
- "dev": "tsx watch src/index.ts",
42
- "start": "node dist/index.js",
43
- "prepublishOnly": "npm run build"
44
- },
45
39
  "engines": {
46
40
  "node": ">=18"
47
41
  },
@@ -50,14 +44,19 @@
50
44
  "zod": "^3.25.0"
51
45
  },
52
46
  "devDependencies": {
53
- "@fidacy/firewall": "workspace:*",
54
47
  "@types/node": "^22.10.0",
55
48
  "tsx": "^4.19.2",
56
- "typescript": "^5.7.2"
49
+ "typescript": "^5.7.2",
50
+ "@fidacy/firewall": "0.1.0"
57
51
  },
58
52
  "mcpName": "com.fidacy/mcp",
59
53
  "repository": {
60
54
  "type": "git",
61
55
  "url": "git+https://github.com/lucaslubi/fidacy-mcp.git"
56
+ },
57
+ "scripts": {
58
+ "build": "node scripts/bundle.mjs",
59
+ "dev": "tsx watch src/index.ts",
60
+ "start": "node dist/index.js"
62
61
  }
63
- }
62
+ }