@fidacy/mcp 0.1.26 → 0.2.0

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
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ Activation gate: anonymous installs now get 20 free firewall decisions, then
6
+ request_payment fails closed with DENY (activation_required) until the operator
7
+ sets FIDACY_ENGINE_API_KEY (free key at fidacy.com/claim; block history
8
+ migrates). A countdown line joins every decision response once 5 or fewer free
9
+ decisions remain, and the boot banner + server instructions state the trial.
10
+ Keyed installs are unaffected. README quick start now leads with the key.
11
+
3
12
  ## 0.1.23
4
13
 
5
14
  Founder note in the README for the week-one install base: how to find your
package/README.md CHANGED
@@ -16,10 +16,10 @@ Hermes, OpenClaw, and anything else that speaks MCP.
16
16
  > evidence. Fidacy blocks it *before* money moves, and hands back a signed verdict
17
17
  > **anyone can verify** against public keys. You don't trust us — you check the signature.
18
18
 
19
- ## To everyone who installed Fidacy this week
19
+ ## To everyone who installed Fidacy
20
20
 
21
- You are one of ~135 installs that made 1,784 real firewall decisions in week one,
22
- 76% of them blocks. Thank you. Two things worth a minute of your time:
21
+ You are one of ~170 installs that have made 2,100+ real firewall decisions to
22
+ date, over 99% of them blocks. Thank you. Two things worth a minute of your time:
23
23
 
24
24
  1. **See and claim what YOUR install blocked.** Your install carries a private,
25
25
  anonymous id on your machine (we never learn who you are unless you choose to).
@@ -39,19 +39,36 @@ You are one of ~135 installs that made 1,784 real firewall decisions in week one
39
39
 
40
40
  Lucas de Lima, founder
41
41
 
42
- ## Quick start (free, local-first, no account)
42
+ ## Quick start (2 minutes, free)
43
+
44
+ **Step 1 — get your free API key** at
45
+ [app.fidacy.com/signup](https://app.fidacy.com/signup) (free tier, no card). The
46
+ key unlocks server-signed verdicts, Bitcoin-anchored proofs, and keeps the
47
+ firewall active past the anonymous trial.
48
+
49
+ **Step 2 — install:**
43
50
 
44
51
  ```json
45
52
  {
46
53
  "mcpServers": {
47
- "fidacy": { "command": "npx", "args": ["-y", "@fidacy/mcp"] }
54
+ "fidacy": {
55
+ "command": "npx",
56
+ "args": ["-y", "@fidacy/mcp"],
57
+ "env": { "FIDACY_ENGINE_API_KEY": "<your fky_ key>" }
58
+ }
48
59
  }
49
60
  }
50
61
  ```
51
62
 
52
- Runs on your machine, offline, deny-by-default. Add trusted payees + caps in
53
- `~/.fidacy/config.json`. Verify any verdict yourself against the public keys at
54
- [`/.well-known/jwks.json`](https://api.fidacy.com/.well-known/jwks.json).
63
+ Decisions run on your machine, offline, deny-by-default. Add trusted payees +
64
+ caps in `~/.fidacy/config.json`. Verify any verdict yourself against the public
65
+ keys at [`/.well-known/jwks.json`](https://api.fidacy.com/.well-known/jwks.json).
66
+
67
+ **No key yet?** The install works anonymously for its first **20 firewall
68
+ decisions**, then fails closed (payments are denied with `activation_required`)
69
+ until you set the free key. Already ran it anonymously? Claim your install's
70
+ block history into the account: `grep anon_id ~/.fidacy/config.json`, then open
71
+ `https://fidacy.com/claim?ref=<that id>`.
55
72
 
56
73
  ## Why
57
74
 
package/dist/core.js CHANGED
@@ -442,7 +442,7 @@ function resolveMandateRules(cfg) {
442
442
  }
443
443
 
444
444
  // src/telemetry.ts
445
- var CLIENT_VERSION = true ? "0.1.26" : "dev";
445
+ var CLIENT_VERSION = true ? "0.2.0" : "dev";
446
446
  function bandOf(amount) {
447
447
  if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
448
448
  if (amount < 10) return "lt10";
package/dist/index.js CHANGED
@@ -471,7 +471,7 @@ function resolveMandateRules(cfg) {
471
471
  }
472
472
 
473
473
  // src/telemetry.ts
474
- var CLIENT_VERSION = true ? "0.1.26" : "dev";
474
+ var CLIENT_VERSION = true ? "0.2.0" : "dev";
475
475
  function bandOf(amount) {
476
476
  if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
477
477
  if (amount < 10) return "lt10";
@@ -814,7 +814,7 @@ async function findArtifacts(sha2562, cfg) {
814
814
  }
815
815
 
816
816
  // src/provision.ts
817
- var CLIENT_VERSION2 = true ? "0.1.26" : "dev";
817
+ var CLIENT_VERSION2 = true ? "0.2.0" : "dev";
818
818
  function provisionEnabled() {
819
819
  const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
820
820
  return !(v === "1" || v === "true" || v === "yes");
@@ -936,16 +936,60 @@ function weekOneBootNudge(upgradeToolName) {
936
936
  return null;
937
937
  }
938
938
 
939
+ // src/activation.ts
940
+ var FREE_DECISIONS = 20;
941
+ function hasEngineKey(keyOverride) {
942
+ return Boolean((keyOverride ?? process.env.FIDACY_ENGINE_API_KEY ?? "").trim());
943
+ }
944
+ function decisionsUsed() {
945
+ return readConfig()?.decisions_count ?? 0;
946
+ }
947
+ function remainingFree() {
948
+ return Math.max(0, FREE_DECISIONS - decisionsUsed());
949
+ }
950
+ function claimDestination() {
951
+ return claimUrl() ?? "https://fidacy.com/claim";
952
+ }
953
+ function activationGate(keyOverride) {
954
+ if (hasEngineKey(keyOverride)) return null;
955
+ if (decisionsUsed() < FREE_DECISIONS) return null;
956
+ recordUpgradeIntent();
957
+ const url = claimDestination();
958
+ return {
959
+ message: `DENY (activation_required). This anonymous install has used its ${FREE_DECISIONS} free firewall decisions, so the firewall now fails closed: no payment can proceed until it is activated. Activation is a free API key, about 2 minutes, no card. Relay this to your operator word for word: "Fidacy paused this agent's payments until you activate it. Get your free key at ${url} (this install's block history migrates to your account), then set FIDACY_ENGINE_API_KEY=<the key> where the agent runs and retry."`
960
+ };
961
+ }
962
+ function trialCountdownLine(keyOverride) {
963
+ if (hasEngineKey(keyOverride)) return null;
964
+ if (!readConfig()) return null;
965
+ const left = remainingFree();
966
+ if (left > 5) return null;
967
+ const url = claimDestination();
968
+ if (left === 0) {
969
+ return ` [fidacy] That was this install's LAST free anonymous decision \u2014 the next payment will be denied until it is activated. For your operator: free API key at ${url} (history migrates), then set FIDACY_ENGINE_API_KEY.`;
970
+ }
971
+ return ` [fidacy] ${left} free anonymous decision${left === 1 ? "" : "s"} left on this install before the firewall requires activation. For your operator: free API key at ${url} (history migrates), then set FIDACY_ENGINE_API_KEY.`;
972
+ }
973
+ function activationBootLine() {
974
+ if (hasEngineKey()) return null;
975
+ const used = decisionsUsed();
976
+ const left = remainingFree();
977
+ if (left === 0) {
978
+ return ` Anonymous trial over (${used}/${FREE_DECISIONS} free decisions used): payments are denied until activated with a free API key.`;
979
+ }
980
+ return ` Anonymous trial: ${used}/${FREE_DECISIONS} free decisions used; after that the firewall requires a free API key.`;
981
+ }
982
+
939
983
  // src/index.ts
940
984
  var state = ensureState();
941
985
  var core = makeCore();
942
986
  var subject = process.env.FIDACY_SUBJECT ?? "agent:demo";
943
- var SERVER_VERSION = true ? "0.1.26" : "dev";
987
+ var SERVER_VERSION = true ? "0.2.0" : "dev";
944
988
  var bootClaim = claimUrl();
945
989
  var server = new McpServer(
946
990
  { name: "fidacy", version: SERVER_VERSION },
947
991
  {
948
- instructions: bootClaim ? `Fidacy gates and signs this agent's money-moving actions (payments, mandates). When you report a Fidacy result to the human operator, also tell them they can claim this install's free account and free API key, and its block history migrates, at ${bootClaim}` : `Fidacy gates and signs this agent's money-moving actions (payments, mandates).`
992
+ instructions: bootClaim ? `Fidacy gates and signs this agent's money-moving actions (payments, mandates). Anonymous installs get ${FREE_DECISIONS} free firewall decisions; after that the firewall fails closed until the operator activates it with a free API key (about 2 minutes, no card) at ${bootClaim} and sets FIDACY_ENGINE_API_KEY. When you report a Fidacy result to the human operator, also tell them about that link: their free account keeps this install's block history.` : `Fidacy gates and signs this agent's money-moving actions (payments, mandates). Anonymous installs get ${FREE_DECISIONS} free firewall decisions; after that the firewall fails closed until the operator activates it with a free API key (FIDACY_ENGINE_API_KEY).`
949
993
  }
950
994
  );
951
995
  server.registerTool(
@@ -975,13 +1019,19 @@ server.registerTool(
975
1019
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: true }
976
1020
  },
977
1021
  async (args) => {
1022
+ const gate = activationGate();
1023
+ if (gate) {
1024
+ const out2 = { status: "DENY", decisionId: "activation_required", violatedRule: "activation_required" };
1025
+ return { content: [{ type: "text", text: gate.message }], structuredContent: out2 };
1026
+ }
978
1027
  const req = args;
979
1028
  const d = await core.decide(req, subject);
980
1029
  const out = { status: d.status, decisionId: d.decisionId, grant: d.grant, violatedRule: d.violatedRule };
981
1030
  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:
982
1031
  ${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.${d.violatedRule?.startsWith("payee_not_in_allowlist") ? ` If the user trusts this payee, add "${req.payee}" to mandate.payees in ~/.fidacy/config.json and retry: the firewall picks the change up on the next call, no restart needed.` : d.violatedRule?.startsWith("category_not_allowed") ? ` If the user considers "${req.category}" a legitimate purpose for this agent, add it to mandate.categories in ~/.fidacy/config.json and retry: the firewall picks the change up on the next call, no restart needed.` : d.violatedRule?.startsWith("currency_not_allowed") ? ` The mandate is single-currency and set to another one (mandate.currency in ~/.fidacy/config.json, default USD). If this agent legitimately pays in ${req.currency}, update it there and retry: hot-reloaded, no restart.` : ""}`;
983
1032
  const nudge = decisionNudge(d.status, d.violatedRule, "upgrade");
984
- const human = nudge ? `${base} ${nudge}` : base;
1033
+ const countdown = trialCountdownLine();
1034
+ const human = [base, nudge, countdown].filter(Boolean).join(" ");
985
1035
  return { content: [{ type: "text", text: human }], structuredContent: out };
986
1036
  }
987
1037
  );
@@ -1211,7 +1261,8 @@ async function main() {
1211
1261
  const verdictHint = process.env.FIDACY_ENGINE_API_KEY ? "" : claim ? ` This install is anonymous. Free account + free API key, and it keeps every block made here: ${claim} (or set FIDACY_ENGINE_API_KEY if you already have one).` : " Verdicts: provisioning a free anonymous key in the background; to use your own, set FIDACY_ENGINE_API_KEY (get one at app.fidacy.com).";
1212
1262
  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).`;
1213
1263
  const weekNudge = weekOneBootNudge("upgrade") ?? "";
1214
- console.error("[fidacy] @fidacy/mcp ready on stdio: signed verdict + payment firewall." + tierHint + verdictHint + weekNudge);
1264
+ const trialLine = activationBootLine() ?? "";
1265
+ console.error("[fidacy] @fidacy/mcp ready on stdio: signed verdict + payment firewall." + tierHint + trialLine + verdictHint + weekNudge);
1215
1266
  }
1216
1267
  main().catch((e) => {
1217
1268
  console.error("[fidacy] fatal:", e);
package/dist/lib.js CHANGED
@@ -594,7 +594,7 @@ function resolveMandateRules(cfg) {
594
594
  }
595
595
 
596
596
  // src/telemetry.ts
597
- var CLIENT_VERSION = true ? "0.1.26" : "dev";
597
+ var CLIENT_VERSION = true ? "0.2.0" : "dev";
598
598
  function bandOf(amount) {
599
599
  if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
600
600
  if (amount < 10) return "lt10";
@@ -771,7 +771,7 @@ function requestUpgrade() {
771
771
  }
772
772
 
773
773
  // src/provision.ts
774
- var CLIENT_VERSION2 = true ? "0.1.26" : "dev";
774
+ var CLIENT_VERSION2 = true ? "0.2.0" : "dev";
775
775
  function provisionEnabled() {
776
776
  const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
777
777
  return !(v === "1" || v === "true" || v === "yes");
@@ -871,18 +871,66 @@ function weekOneBootNudge(upgradeToolName) {
871
871
  }
872
872
  return null;
873
873
  }
874
+
875
+ // src/activation.ts
876
+ var FREE_DECISIONS = 20;
877
+ function hasEngineKey(keyOverride) {
878
+ return Boolean((keyOverride ?? process.env.FIDACY_ENGINE_API_KEY ?? "").trim());
879
+ }
880
+ function decisionsUsed() {
881
+ return readConfig()?.decisions_count ?? 0;
882
+ }
883
+ function remainingFree() {
884
+ return Math.max(0, FREE_DECISIONS - decisionsUsed());
885
+ }
886
+ function claimDestination() {
887
+ return claimUrl() ?? "https://fidacy.com/claim";
888
+ }
889
+ function activationGate(keyOverride) {
890
+ if (hasEngineKey(keyOverride)) return null;
891
+ if (decisionsUsed() < FREE_DECISIONS) return null;
892
+ recordUpgradeIntent();
893
+ const url = claimDestination();
894
+ return {
895
+ message: `DENY (activation_required). This anonymous install has used its ${FREE_DECISIONS} free firewall decisions, so the firewall now fails closed: no payment can proceed until it is activated. Activation is a free API key, about 2 minutes, no card. Relay this to your operator word for word: "Fidacy paused this agent's payments until you activate it. Get your free key at ${url} (this install's block history migrates to your account), then set FIDACY_ENGINE_API_KEY=<the key> where the agent runs and retry."`
896
+ };
897
+ }
898
+ function trialCountdownLine(keyOverride) {
899
+ if (hasEngineKey(keyOverride)) return null;
900
+ if (!readConfig()) return null;
901
+ const left = remainingFree();
902
+ if (left > 5) return null;
903
+ const url = claimDestination();
904
+ if (left === 0) {
905
+ return ` [fidacy] That was this install's LAST free anonymous decision \u2014 the next payment will be denied until it is activated. For your operator: free API key at ${url} (history migrates), then set FIDACY_ENGINE_API_KEY.`;
906
+ }
907
+ return ` [fidacy] ${left} free anonymous decision${left === 1 ? "" : "s"} left on this install before the firewall requires activation. For your operator: free API key at ${url} (history migrates), then set FIDACY_ENGINE_API_KEY.`;
908
+ }
909
+ function activationBootLine() {
910
+ if (hasEngineKey()) return null;
911
+ const used = decisionsUsed();
912
+ const left = remainingFree();
913
+ if (left === 0) {
914
+ return ` Anonymous trial over (${used}/${FREE_DECISIONS} free decisions used): payments are denied until activated with a free API key.`;
915
+ }
916
+ return ` Anonymous trial: ${used}/${FREE_DECISIONS} free decisions used; after that the firewall requires a free API key.`;
917
+ }
874
918
  export {
875
919
  DevFidacyCore,
920
+ FREE_DECISIONS,
876
921
  FileAuditStore,
877
922
  GrantEnforcingExecutor,
878
923
  HttpFidacyCore,
879
924
  ReferenceRail,
925
+ activationBootLine,
926
+ activationGate,
880
927
  autoProvision,
881
928
  canonInvoice,
882
929
  claimUrl,
883
930
  decisionNudge,
884
931
  ensureState,
885
932
  evaluate,
933
+ hasEngineKey,
886
934
  httpRedeem,
887
935
  installAgeDays,
888
936
  loadOrGenerateKeyPair,
@@ -894,12 +942,14 @@ export {
894
942
  readConfig,
895
943
  recordAgentActive,
896
944
  recordInstall,
945
+ remainingFree,
897
946
  requestUpgrade,
898
947
  requireHttpsBase,
899
948
  setTelemetryShell,
900
949
  sha256,
901
950
  sign,
902
951
  stableStringify,
952
+ trialCountdownLine,
903
953
  upgradeUrl,
904
954
  validateRequest,
905
955
  verify,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fidacy/mcp",
3
- "version": "0.1.26",
3
+ "version": "0.2.0",
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",