@fidacy/mcp 0.1.17 → 0.1.18
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 +18 -0
- package/dist/assess.js +1 -1
- package/dist/core.js +4 -1
- package/dist/index.js +10 -5
- package/dist/lib.js +9 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,6 +73,9 @@ Mental model: `assess_action` -> **engine** (signed verdict);
|
|
|
73
73
|
| `request_payment` | core | Authorize a payment action. ALLOW + grant, or DENY + rule. |
|
|
74
74
|
| `verify_mandate` | core | Read the mandate envelope + Fidacy public key. |
|
|
75
75
|
| `get_audit_proof` | core | Hash-chained proof for a decision id. |
|
|
76
|
+
| `anchor_artifact` | engine | Bitcoin-anchored integrity proof for any file (contract, invoice, prescription, claim, image, audio, video, conversation). Hashed locally; only the SHA-256 leaves. Returns a signed receipt. |
|
|
77
|
+
| `check_artifact` | engine | Check whether a file (or hash) was anchored, and its Bitcoin checkpoint state. A mismatch is the tampering signal. |
|
|
78
|
+
| `upgrade` | — | Start upgrading this local install to a real Fidacy account; preserves and migrates anonymous usage. |
|
|
76
79
|
|
|
77
80
|
### `assess_action`
|
|
78
81
|
|
|
@@ -145,6 +148,21 @@ repository stays private. Set `FIDACY_MODE=http` and implement three endpoints:
|
|
|
145
148
|
|
|
146
149
|
No change to the MCP layer is needed.
|
|
147
150
|
|
|
151
|
+
## Telemetry
|
|
152
|
+
|
|
153
|
+
The install emits **anonymous, opt-out** usage telemetry so we can measure
|
|
154
|
+
traction (installs, active agents, decision counts, deny-rate). It is
|
|
155
|
+
best-effort and never on the decision critical path, so it can never block or
|
|
156
|
+
slow a verdict.
|
|
157
|
+
|
|
158
|
+
- It carries an anonymous install id and counters only. It **never** includes
|
|
159
|
+
payment content — no payee, amount, invoice, or mandate ever leaves your
|
|
160
|
+
machine. Payload-carrying types are rejected by a strict schema.
|
|
161
|
+
- Turn it off completely with `FIDACY_DISABLE_TELEMETRY=1` (or `true`).
|
|
162
|
+
|
|
163
|
+
Consistent with the product: you don't have to trust us, you can verify. The
|
|
164
|
+
firewall runs fully with telemetry disabled.
|
|
165
|
+
|
|
148
166
|
## Dev
|
|
149
167
|
|
|
150
168
|
```bash
|
package/dist/assess.js
CHANGED
|
@@ -88,7 +88,7 @@ async function postOnce(fetchImpl, url, headers, payload, timeoutMs) {
|
|
|
88
88
|
body: payload,
|
|
89
89
|
signal: controller.signal
|
|
90
90
|
});
|
|
91
|
-
} catch
|
|
91
|
+
} catch {
|
|
92
92
|
const aborted = controller.signal.aborted;
|
|
93
93
|
throw new AssessError({ type: aborted ? "timeout" : "network_error", status: 0 });
|
|
94
94
|
} finally {
|
package/dist/core.js
CHANGED
|
@@ -347,6 +347,9 @@ var FileAuditStore = class {
|
|
|
347
347
|
const digest = sha256(stableStringify({ decisionId: decision.decisionId, status: decision.status, request: decision.request, violatedRule: decision.violatedRule ?? null }));
|
|
348
348
|
const hash = sha256(`${prevHash}|${digest}|${seq}|${ts}`);
|
|
349
349
|
const record2 = { seq, decisionId: decision.decisionId, status: decision.status, subject: decision.subject, digest, prevHash, hash, ts };
|
|
350
|
+
if (typeof decision.request?.purpose === "string" && decision.request.purpose.trim()) {
|
|
351
|
+
record2.purpose = decision.request.purpose.slice(0, 500);
|
|
352
|
+
}
|
|
350
353
|
if (decision.status === "ALLOW") {
|
|
351
354
|
const req = decision.request;
|
|
352
355
|
if (typeof req?.amount === "number" && Number.isFinite(req.amount))
|
|
@@ -439,7 +442,7 @@ function resolveMandateRules(cfg) {
|
|
|
439
442
|
}
|
|
440
443
|
|
|
441
444
|
// src/telemetry.ts
|
|
442
|
-
var CLIENT_VERSION = true ? "0.1.
|
|
445
|
+
var CLIENT_VERSION = true ? "0.1.18" : "dev";
|
|
443
446
|
var currentShell = "mcp";
|
|
444
447
|
function telemetryEnabled() {
|
|
445
448
|
const v = (process.env.FIDACY_DISABLE_TELEMETRY ?? "").trim().toLowerCase();
|
package/dist/index.js
CHANGED
|
@@ -354,6 +354,9 @@ var FileAuditStore = class {
|
|
|
354
354
|
const digest = sha256(stableStringify({ decisionId: decision.decisionId, status: decision.status, request: decision.request, violatedRule: decision.violatedRule ?? null }));
|
|
355
355
|
const hash = sha256(`${prevHash}|${digest}|${seq}|${ts}`);
|
|
356
356
|
const record2 = { seq, decisionId: decision.decisionId, status: decision.status, subject: decision.subject, digest, prevHash, hash, ts };
|
|
357
|
+
if (typeof decision.request?.purpose === "string" && decision.request.purpose.trim()) {
|
|
358
|
+
record2.purpose = decision.request.purpose.slice(0, 500);
|
|
359
|
+
}
|
|
357
360
|
if (decision.status === "ALLOW") {
|
|
358
361
|
const req = decision.request;
|
|
359
362
|
if (typeof req?.amount === "number" && Number.isFinite(req.amount))
|
|
@@ -468,7 +471,7 @@ function resolveMandateRules(cfg) {
|
|
|
468
471
|
}
|
|
469
472
|
|
|
470
473
|
// src/telemetry.ts
|
|
471
|
-
var CLIENT_VERSION = true ? "0.1.
|
|
474
|
+
var CLIENT_VERSION = true ? "0.1.18" : "dev";
|
|
472
475
|
var currentShell = "mcp";
|
|
473
476
|
function telemetryEnabled() {
|
|
474
477
|
const v = (process.env.FIDACY_DISABLE_TELEMETRY ?? "").trim().toLowerCase();
|
|
@@ -691,7 +694,7 @@ async function postOnce(fetchImpl, url, headers, payload, timeoutMs) {
|
|
|
691
694
|
body: payload,
|
|
692
695
|
signal: controller.signal
|
|
693
696
|
});
|
|
694
|
-
} catch
|
|
697
|
+
} catch {
|
|
695
698
|
const aborted = controller.signal.aborted;
|
|
696
699
|
throw new AssessError({ type: aborted ? "timeout" : "network_error", status: 0 });
|
|
697
700
|
} finally {
|
|
@@ -783,7 +786,7 @@ async function findArtifacts(sha2562, cfg) {
|
|
|
783
786
|
}
|
|
784
787
|
|
|
785
788
|
// src/provision.ts
|
|
786
|
-
var CLIENT_VERSION2 = true ? "0.1.
|
|
789
|
+
var CLIENT_VERSION2 = true ? "0.1.18" : "dev";
|
|
787
790
|
function provisionEnabled() {
|
|
788
791
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
789
792
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -883,7 +886,7 @@ function weekOneBootNudge(upgradeToolName) {
|
|
|
883
886
|
var state = ensureState();
|
|
884
887
|
var core = makeCore();
|
|
885
888
|
var subject = process.env.FIDACY_SUBJECT ?? "agent:demo";
|
|
886
|
-
var SERVER_VERSION = true ? "0.1.
|
|
889
|
+
var SERVER_VERSION = true ? "0.1.18" : "dev";
|
|
887
890
|
var server = new McpServer({ name: "fidacy", version: SERVER_VERSION });
|
|
888
891
|
server.registerTool(
|
|
889
892
|
"request_payment",
|
|
@@ -894,7 +897,9 @@ server.registerTool(
|
|
|
894
897
|
payee: z.string().describe("Payee identifier"),
|
|
895
898
|
amount: z.number().positive().describe("Amount in the mandate currency"),
|
|
896
899
|
currency: z.string().length(3).describe("ISO 4217 currency code"),
|
|
897
|
-
purpose: z.string().describe(
|
|
900
|
+
purpose: z.string().describe(
|
|
901
|
+
"Your stated reason for this payment, in your own words. It is persisted readably on the tamper-evident audit record (ALLOW and DENY alike) and becomes part of the after-the-fact proof, so write the real reason."
|
|
902
|
+
),
|
|
898
903
|
category: z.string().describe("Purpose category (must be allowed by the mandate)"),
|
|
899
904
|
idempotencyKey: z.string().describe("Caller-supplied idempotency key"),
|
|
900
905
|
invoiceRef: z.string().describe(
|
package/dist/lib.js
CHANGED
|
@@ -385,6 +385,9 @@ var FileAuditStore = class {
|
|
|
385
385
|
const digest = sha256(stableStringify({ decisionId: decision.decisionId, status: decision.status, request: decision.request, violatedRule: decision.violatedRule ?? null }));
|
|
386
386
|
const hash = sha256(`${prevHash}|${digest}|${seq}|${ts}`);
|
|
387
387
|
const record2 = { seq, decisionId: decision.decisionId, status: decision.status, subject: decision.subject, digest, prevHash, hash, ts };
|
|
388
|
+
if (typeof decision.request?.purpose === "string" && decision.request.purpose.trim()) {
|
|
389
|
+
record2.purpose = decision.request.purpose.slice(0, 500);
|
|
390
|
+
}
|
|
388
391
|
if (decision.status === "ALLOW") {
|
|
389
392
|
const req = decision.request;
|
|
390
393
|
if (typeof req?.amount === "number" && Number.isFinite(req.amount))
|
|
@@ -457,6 +460,10 @@ var GrantEnforcingExecutor = class {
|
|
|
457
460
|
this.rail = rail;
|
|
458
461
|
this.pub = createPublicKey(publicKeyPem2);
|
|
459
462
|
this.redeem = opts?.redeem;
|
|
463
|
+
const isProd = typeof process !== "undefined" && process.env?.NODE_ENV === "production";
|
|
464
|
+
if (isProd && !this.redeem && !opts?.allowUnsafeInMemorySingleUse) {
|
|
465
|
+
throw new Error("GrantEnforcingExecutor in production requires a durable `redeem` (single-use across instances). Wire httpRedeem(coreUrl, apiKey), or pass allowUnsafeInMemorySingleUse:true only for a true single-process deployment.");
|
|
466
|
+
}
|
|
460
467
|
}
|
|
461
468
|
async execute(req, grant) {
|
|
462
469
|
if (!grant)
|
|
@@ -587,7 +594,7 @@ function resolveMandateRules(cfg) {
|
|
|
587
594
|
}
|
|
588
595
|
|
|
589
596
|
// src/telemetry.ts
|
|
590
|
-
var CLIENT_VERSION = true ? "0.1.
|
|
597
|
+
var CLIENT_VERSION = true ? "0.1.18" : "dev";
|
|
591
598
|
var currentShell = "mcp";
|
|
592
599
|
function setTelemetryShell(shell) {
|
|
593
600
|
currentShell = shell;
|
|
@@ -736,7 +743,7 @@ function requestUpgrade() {
|
|
|
736
743
|
}
|
|
737
744
|
|
|
738
745
|
// src/provision.ts
|
|
739
|
-
var CLIENT_VERSION2 = true ? "0.1.
|
|
746
|
+
var CLIENT_VERSION2 = true ? "0.1.18" : "dev";
|
|
740
747
|
function provisionEnabled() {
|
|
741
748
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
742
749
|
return !(v === "1" || v === "true" || v === "yes");
|
package/package.json
CHANGED