@fidacy/openclaw-plugin 0.5.6 → 0.5.8
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 +26 -0
- package/README.md +54 -26
- package/dist/index.js +52 -9
- package/openclaw.plugin.json +5 -5
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 59bd236: Complete and reconcile the privacy disclosure. The ClawHub security audit put this plugin in Review for "inconsistent privacy disclosures about local storage and outbound metadata", and it was right on both counts.
|
|
8
|
+
|
|
9
|
+
- **Local storage.** The README claimed local state was `config.json` plus `audit/audit.log` and ended with "Nothing else". `~/.fidacy/pending-anchors.jsonl` was never disclosed. A separate line promised a session log at `~/.fidacy/sessions/`, which belongs to the MCP-plus-hooks install and not to this plugin. Both are now stated once, accurately, as a complete list.
|
|
10
|
+
- **Outbound metadata.** The README named two network calls. The plugin makes five: `/v1/telemetry`, `/v1/provision`, `/v1/artifacts`, `/v1/assess` and `/v1/register`. All five are now listed with what each one sends and what turns it off, in one place instead of two copies that had drifted apart.
|
|
11
|
+
- **The static-analysis flag.** `suspicious.env_credential_access` is described accurately now: reading your key and sending it to your engine is what a bearer token is, and every tool that accepts an API key matches that pattern. The old text gave a different and wrong reason ("the identifier is named like a secret"), in a second copy that contradicted the first.
|
|
12
|
+
- The "verify it yourself" pointer aimed at a mirror repo while releases are provenance-linked to `lucaslubi/fidacy`. It now points where the code actually is, so the instruction works.
|
|
13
|
+
|
|
14
|
+
No behaviour changed. This release is documentation only, and every claim in it was checked against the code rather than against the previous README.
|
|
15
|
+
|
|
16
|
+
## 0.5.7
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Four configuration mistakes that presented themselves as security verdicts, so the firewall looked broken and stopped real payments for reasons nobody could see.
|
|
21
|
+
|
|
22
|
+
- `FIDACY_MANDATE_JSON` was the last human-authored surface returned verbatim, with no validation of its caps. `"perTxMax": "10000"` built a mandate the engine had to refuse, so **every** payment came back `invalid_mandate_cap:perTxMax=10000` — a message naming 10000 as the invalid cap, when 10000 is a perfectly good number and the quotes were the whole problem. It now honours a quoted number (which means exactly one thing) and refuses anything that would need a guess, loudly, saying that the payees and caps in force are not the ones you wrote.
|
|
23
|
+
- **Fail-open, now closed:** both window checks are `now < Date.parse(...)` and `now > Date.parse(...)`, and a date that does not parse yields NaN, which makes both comparisons false. An unreadable window was not a narrow window, it was no window: the mandate never expired. An unenforceable window now denies, at the engine as well as at the override.
|
|
24
|
+
- A quoted cap in `config.json` was discarded silently, so the 2500 default applied and a 5000 payment came back `per_tx_cap_exceeded:5000>2500`, quoting a cap the operator had never set. It now follows the same rule as the environment variables, which had warned since 2026-07-24.
|
|
25
|
+
- `"currency": "usd"` denied every payment with `currency_not_allowed:USD`, naming as forbidden the exact currency it had allowed. ISO 4217 codes are case-insensitive; case was never a policy decision.
|
|
26
|
+
|
|
27
|
+
Nothing was loosened. Caps still cap, a genuinely different currency is still denied, a payee off the allowlist is still denied, and an unreadable value still falls back to the safe default rather than to no limit at all.
|
|
28
|
+
|
|
3
29
|
## 0.5.5
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -15,16 +15,35 @@ a hash digest anyone can recompute.
|
|
|
15
15
|
Stays on your machine, always:
|
|
16
16
|
|
|
17
17
|
- the command, file path and arguments of every tool call
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
- your mandate and config (`~/.fidacy/`), which is yours to delete
|
|
19
|
+
|
|
20
|
+
Written to disk, and this is the complete list:
|
|
21
|
+
|
|
22
|
+
- `~/.fidacy/config.json` (mode 0600): the anonymous install id, tier, and your
|
|
23
|
+
mandate rules
|
|
24
|
+
- `~/.fidacy/audit/audit.log`: the hash-chained decision log
|
|
25
|
+
- `~/.fidacy/pending-anchors.jsonl`: session digests waiting to be anchored,
|
|
26
|
+
written only while an anchor is queued and cleared once it lands
|
|
27
|
+
|
|
28
|
+
Leaves your machine, and this is the complete list of hosts and paths. Every one
|
|
29
|
+
goes to your configured engine (`https://api.fidacy.com` by default) and nowhere
|
|
30
|
+
else:
|
|
31
|
+
|
|
32
|
+
- `/v1/telemetry`: anonymous usage events (install, session, decision counts; a
|
|
33
|
+
random UUID, never a name or hostname). Off with `FIDACY_DISABLE_TELEMETRY=1`.
|
|
34
|
+
- `/v1/provision`: a background free-key request. Off with
|
|
35
|
+
`FIDACY_DISABLE_PROVISION=1`.
|
|
36
|
+
- `/v1/artifacts`: per-category counts (for example `shell: 9, file: 4`) and the
|
|
37
|
+
session digest, plus any hash you anchor with `anchor_artifact`. Hashes and
|
|
38
|
+
counts only; no file content and no command text.
|
|
39
|
+
- `/v1/assess`: only when you call `assess_action` yourself, and only if you set
|
|
40
|
+
an engine API key. Sends the action you passed to the tool.
|
|
41
|
+
- `/v1/register`: only if you set `operatorEmail`, which is opt-in and removable.
|
|
42
|
+
Sends that email and nothing else.
|
|
43
|
+
|
|
44
|
+
With `FIDACY_DISABLE_TELEMETRY=1`, `FIDACY_DISABLE_PROVISION=1`, no engine key
|
|
45
|
+
and no `operatorEmail`, the plugin makes no network calls at all and gates
|
|
46
|
+
payments entirely offline.
|
|
28
47
|
|
|
29
48
|
## The tools
|
|
30
49
|
|
|
@@ -103,22 +122,32 @@ Verify any verdict yourself: https://api.fidacy.com/.well-known/jwks.json
|
|
|
103
122
|
|
|
104
123
|
This is a payment-control plugin, so audit it like one. What it actually does:
|
|
105
124
|
|
|
106
|
-
- **Network calls it makes:**
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
- **Network calls it makes:** the five endpoints listed under "what leaves your
|
|
126
|
+
machine" above, all on your configured engine and nowhere else. That list is
|
|
127
|
+
stated once, at the top, on purpose: this section used to carry a second,
|
|
128
|
+
shorter copy naming only two of them, and a privacy disclosure that
|
|
129
|
+
contradicts itself is worse than a long one. None of the five is ever on the
|
|
130
|
+
decision path; payment gating works fully offline.
|
|
131
|
+
- **Local state:** the three files listed above, and nothing else. This bullet
|
|
132
|
+
used to name two of them and end with "Nothing else", which was not true:
|
|
133
|
+
`pending-anchors.jsonl` was never disclosed. Delete `~/.fidacy` to clear all
|
|
134
|
+
of it.
|
|
113
135
|
- **`FIDACY_SIGNING_KEY_B64`:** an OPTIONAL env var the operator sets to pin a
|
|
114
136
|
stable local Ed25519 signing key for grants. If unset, a per-session key is
|
|
115
137
|
generated. The plugin reads it; it never writes or transmits it.
|
|
116
138
|
- **API keys:** read from your plugin config (`engineApiKey`) or the
|
|
117
139
|
`FIDACY_ENGINE_API_KEY` env var, sent only to your configured engine URL
|
|
118
140
|
(default `api.fidacy.com`) as a bearer token. There are no hardcoded keys or
|
|
119
|
-
secrets in the published bundle
|
|
120
|
-
|
|
121
|
-
|
|
141
|
+
secrets in the published bundle. A static analyser will flag this as
|
|
142
|
+
`suspicious.env_credential_access` ("environment variable access combined with
|
|
143
|
+
network send"), and that description is accurate: reading your key and sending
|
|
144
|
+
it to your engine is what a bearer token IS, and every tool that takes an API
|
|
145
|
+
key matches the same pattern. What the rule cannot tell you is WHOSE key and
|
|
146
|
+
WHICH host, so check both yourself: the bundle ships unminified, the source is
|
|
147
|
+
at github.com/lucaslubi/fidacy (`packages/openclaw-plugin`), and every release
|
|
148
|
+
is provenance-linked to the commit it was built from. The command below settles
|
|
149
|
+
the "hardcoded secret" question in one line, and the test suite fails the build
|
|
150
|
+
if a literal ever gets in.
|
|
122
151
|
- **Verify our signatures, not our word:** every verdict checks against the public
|
|
123
152
|
JWKS at `api.fidacy.com/.well-known/jwks.json` with the open-source
|
|
124
153
|
[`@fidacy/verify`](https://www.npmjs.com/package/@fidacy/verify).
|
|
@@ -141,15 +170,14 @@ published package, in any version. Check it yourself:
|
|
|
141
170
|
cd $(mktemp -d) && curl -sL $(npm view @fidacy/openclaw-plugin dist.tarball) | tar xz && grep -rE "fky_(live|test)_[A-Za-z0-9]{8,}|BEGIN [A-Z ]*PRIVATE KEY" package/ || echo "no credential literals found"
|
|
142
171
|
```
|
|
143
172
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
above is what settles the question, and the test suite fails the build if a literal ever
|
|
148
|
-
does get in.
|
|
173
|
+
On the `suspicious.env_credential_access` finding a static analyser reports here, see
|
|
174
|
+
the "API keys" bullet above. It is stated in one place rather than two, because the
|
|
175
|
+
two copies had drifted into giving different reasons for the same flag.
|
|
149
176
|
|
|
150
177
|
**Turning the network off.** `FIDACY_DISABLE_TELEMETRY=1` stops anonymous install and
|
|
151
178
|
usage telemetry. `FIDACY_DISABLE_PROVISION=1` stops the background free-key provisioning.
|
|
152
|
-
With both set
|
|
179
|
+
With both set, no engine credential and no `operatorEmail`, the plugin decides locally
|
|
180
|
+
and contacts nothing: those four switches cover all five endpoints listed at the top.
|
|
153
181
|
|
|
154
182
|
**Where the history lives.** Decisions go to a hash-chained log under `~/.fidacy` on your
|
|
155
183
|
machine. That local chain is what makes `spend_summary`, `list_decisions` and
|
package/dist/index.js
CHANGED
|
@@ -4320,14 +4320,24 @@ function resolveMandateRules(cfg) {
|
|
|
4320
4320
|
}
|
|
4321
4321
|
return n;
|
|
4322
4322
|
};
|
|
4323
|
-
const fileNum = (v) =>
|
|
4323
|
+
const fileNum = (name, v) => {
|
|
4324
|
+
if (v === void 0 || v === null) return void 0;
|
|
4325
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v.trim()) : NaN;
|
|
4326
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
4327
|
+
console.error(
|
|
4328
|
+
`[fidacy] mandate.${name} in config.json is ${JSON.stringify(v)}, which is not a positive number, so it cannot be enforced as a cap. Ignoring it and using the safe default. Write it as a bare JSON number, with no quotes, thousands separator, currency symbol or unit (e.g. "${name}": 2500).`
|
|
4329
|
+
);
|
|
4330
|
+
return void 0;
|
|
4331
|
+
}
|
|
4332
|
+
return n;
|
|
4333
|
+
};
|
|
4324
4334
|
const payees = envList(process.env.FIDACY_ALLOW_PAYEES) ?? m.payees ?? [];
|
|
4325
4335
|
return {
|
|
4326
4336
|
payees: payees.includes(DEMO_PAYEE) ? payees : [...payees, DEMO_PAYEE],
|
|
4327
4337
|
categories: envList(process.env.FIDACY_ALLOW_CATEGORIES) ?? m.categories ?? ["*"],
|
|
4328
4338
|
currency: process.env.FIDACY_CURRENCY ?? m.currency ?? "USD",
|
|
4329
|
-
perTxMax: envNum("FIDACY_PER_TX_MAX", process.env.FIDACY_PER_TX_MAX) ?? fileNum(m.perTxMax) ?? 2500,
|
|
4330
|
-
maxTotal: envNum("FIDACY_MAX_TOTAL", process.env.FIDACY_MAX_TOTAL) ?? fileNum(m.maxTotal) ?? 1e4
|
|
4339
|
+
perTxMax: envNum("FIDACY_PER_TX_MAX", process.env.FIDACY_PER_TX_MAX) ?? fileNum("perTxMax", m.perTxMax) ?? 2500,
|
|
4340
|
+
maxTotal: envNum("FIDACY_MAX_TOTAL", process.env.FIDACY_MAX_TOTAL) ?? fileNum("maxTotal", m.maxTotal) ?? 1e4
|
|
4331
4341
|
};
|
|
4332
4342
|
}
|
|
4333
4343
|
|
|
@@ -4759,6 +4769,13 @@ function validateMandateCaps(mandate) {
|
|
|
4759
4769
|
return `invalid_mandate_cap:perTxMax=${String(mandate.allow.perTxMax)}`;
|
|
4760
4770
|
if (bad(mandate.allow.maxTotal))
|
|
4761
4771
|
return `invalid_mandate_cap:maxTotal=${String(mandate.allow.maxTotal)}`;
|
|
4772
|
+
if (!mandate.window || typeof mandate.window !== "object")
|
|
4773
|
+
return "invalid_mandate:missing_window";
|
|
4774
|
+
for (const campo of ["notBefore", "notAfter"]) {
|
|
4775
|
+
const v = mandate.window[campo];
|
|
4776
|
+
if (typeof v !== "string" || Number.isNaN(Date.parse(v)))
|
|
4777
|
+
return `invalid_mandate_window:${campo}=${String(v)}`;
|
|
4778
|
+
}
|
|
4762
4779
|
return null;
|
|
4763
4780
|
}
|
|
4764
4781
|
function evaluate(mandate, req, spentSoFar) {
|
|
@@ -4772,7 +4789,7 @@ function evaluate(mandate, req, spentSoFar) {
|
|
|
4772
4789
|
return "before_mandate_window";
|
|
4773
4790
|
if (now > Date.parse(mandate.window.notAfter))
|
|
4774
4791
|
return "after_mandate_window";
|
|
4775
|
-
if (req.currency !== mandate.allow.currency)
|
|
4792
|
+
if (req.currency.toUpperCase() !== mandate.allow.currency.toUpperCase())
|
|
4776
4793
|
return `currency_not_allowed:${req.currency}`;
|
|
4777
4794
|
if (req.amount <= 0)
|
|
4778
4795
|
return "non_positive_amount";
|
|
@@ -5085,7 +5102,7 @@ var FileAuditStore = class {
|
|
|
5085
5102
|
import { statSync } from "node:fs";
|
|
5086
5103
|
|
|
5087
5104
|
// ../mcp/src/telemetry.ts
|
|
5088
|
-
var CLIENT_VERSION = true ? "0.5.
|
|
5105
|
+
var CLIENT_VERSION = true ? "0.5.8" : "dev";
|
|
5089
5106
|
function bandOf(amount) {
|
|
5090
5107
|
if (typeof amount !== "number" || !Number.isFinite(amount) || amount <= 0) return void 0;
|
|
5091
5108
|
if (amount < 10) return "lt10";
|
|
@@ -5193,12 +5210,38 @@ async function flush() {
|
|
|
5193
5210
|
}
|
|
5194
5211
|
|
|
5195
5212
|
// ../mcp/src/core.ts
|
|
5213
|
+
function normalizaMandatoDeEnv(m) {
|
|
5214
|
+
const allow = m.allow;
|
|
5215
|
+
for (const campo of ["perTxMax", "maxTotal"]) {
|
|
5216
|
+
const v = allow[campo];
|
|
5217
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v.trim()) : NaN;
|
|
5218
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
5219
|
+
return `has allow.${campo} = ${JSON.stringify(v)}, which is not a positive number, so that cap cannot be enforced. Write it as a bare JSON number, with no quotes, thousands separator, currency symbol or unit (e.g. "${campo}": 2500).`;
|
|
5220
|
+
}
|
|
5221
|
+
allow[campo] = n;
|
|
5222
|
+
}
|
|
5223
|
+
const window = m.window;
|
|
5224
|
+
for (const campo of ["notBefore", "notAfter"]) {
|
|
5225
|
+
const v = window[campo];
|
|
5226
|
+
if (typeof v !== "string" || Number.isNaN(Date.parse(v))) {
|
|
5227
|
+
return `has window.${campo} = ${JSON.stringify(v)}, which is not a readable date, so the mandate's time window cannot be enforced. Use an ISO 8601 timestamp (e.g. "${campo}": "2026-01-01T00:00:00Z").`;
|
|
5228
|
+
}
|
|
5229
|
+
}
|
|
5230
|
+
return null;
|
|
5231
|
+
}
|
|
5196
5232
|
function buildMandate() {
|
|
5197
5233
|
if (process.env.FIDACY_MANDATE_JSON) {
|
|
5198
5234
|
try {
|
|
5199
5235
|
const parsed = JSON.parse(process.env.FIDACY_MANDATE_JSON);
|
|
5200
|
-
if (parsed && typeof parsed === "object" && parsed.allow && parsed.window)
|
|
5201
|
-
|
|
5236
|
+
if (parsed && typeof parsed === "object" && parsed.allow && parsed.window) {
|
|
5237
|
+
const problema = normalizaMandatoDeEnv(parsed);
|
|
5238
|
+
if (!problema) return parsed;
|
|
5239
|
+
console.error(
|
|
5240
|
+
`[fidacy] FIDACY_MANDATE_JSON ${problema} The override is being IGNORED and the safe default mandate is in force instead, so your payees and caps are NOT the ones you wrote.`
|
|
5241
|
+
);
|
|
5242
|
+
} else {
|
|
5243
|
+
console.error("[fidacy] FIDACY_MANDATE_JSON is missing allow/window; ignoring it and using the safe default mandate.");
|
|
5244
|
+
}
|
|
5202
5245
|
} catch (err) {
|
|
5203
5246
|
console.error(`[fidacy] FIDACY_MANDATE_JSON is not valid JSON (${err.message}); ignoring it and using the safe default mandate.`);
|
|
5204
5247
|
}
|
|
@@ -5274,7 +5317,7 @@ function requestUpgrade() {
|
|
|
5274
5317
|
}
|
|
5275
5318
|
|
|
5276
5319
|
// ../mcp/src/provision.ts
|
|
5277
|
-
var CLIENT_VERSION2 = true ? "0.5.
|
|
5320
|
+
var CLIENT_VERSION2 = true ? "0.5.8" : "dev";
|
|
5278
5321
|
function provisionEnabled() {
|
|
5279
5322
|
const v = (process.env.FIDACY_DISABLE_PROVISION ?? "").trim().toLowerCase();
|
|
5280
5323
|
return !(v === "1" || v === "true" || v === "yes");
|
|
@@ -5417,7 +5460,7 @@ function trialCountdownLine(keyOverride) {
|
|
|
5417
5460
|
}
|
|
5418
5461
|
|
|
5419
5462
|
// ../mcp/src/register.ts
|
|
5420
|
-
var CLIENT_VERSION3 = true ? "0.5.
|
|
5463
|
+
var CLIENT_VERSION3 = true ? "0.5.8" : "dev";
|
|
5421
5464
|
function endpoint3() {
|
|
5422
5465
|
const base = (process.env.FIDACY_ENGINE_URL ?? "https://api.fidacy.com").replace(/\/$/, "");
|
|
5423
5466
|
return `${base}/v1/register`;
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "Fidacy AI Agent Firewall",
|
|
4
4
|
"description": "Firewall for AI agents. Watches every action the agent takes and ends each session in a digest anyone can recompute; commands, paths and arguments never leave your machine, only counts and a hash. Blocks wrong/lookalike payee, over-cap and duplicate-invoice fraud before money moves. Non-custodial, local-first, deny-by-default. Anonymous telemetry (counts only) can be disabled with FIDACY_DISABLE_TELEMETRY=1.",
|
|
5
5
|
"icon": "https://fidacy.com/logo.png",
|
|
6
|
-
"version": "0.5.
|
|
6
|
+
"version": "0.5.8",
|
|
7
7
|
"contracts": {
|
|
8
8
|
"tools": [
|
|
9
9
|
"request_payment",
|
|
@@ -25,19 +25,19 @@
|
|
|
25
25
|
"properties": {
|
|
26
26
|
"operatorEmail": {
|
|
27
27
|
"type": "string",
|
|
28
|
-
"description": "Your email (optional). Ties this agent's protection history to you so it can move into a free account, and lets Fidacy reach you about this install. Never shared; remove any time.
|
|
28
|
+
"description": "Your email (optional). Ties this agent's protection history to you so it can move into a free account, and lets Fidacy reach you about this install. Never shared; remove any time."
|
|
29
29
|
},
|
|
30
30
|
"engineApiKey": {
|
|
31
31
|
"type": "string",
|
|
32
|
-
"description": "Fidacy engine API key (fky_live_/fky_test_) enabling signed verdicts via assess_action. Falls back to FIDACY_ENGINE_API_KEY.
|
|
32
|
+
"description": "Fidacy engine API key (fky_live_/fky_test_) enabling signed verdicts via assess_action. Falls back to FIDACY_ENGINE_API_KEY."
|
|
33
33
|
},
|
|
34
34
|
"engineUrl": {
|
|
35
35
|
"type": "string",
|
|
36
|
-
"description": "Fidacy engine base URL. Defaults to https://api.fidacy.com (or FIDACY_ENGINE_URL).
|
|
36
|
+
"description": "Fidacy engine base URL. Defaults to https://api.fidacy.com (or FIDACY_ENGINE_URL)."
|
|
37
37
|
},
|
|
38
38
|
"subject": {
|
|
39
39
|
"type": "string",
|
|
40
|
-
"description": "Mandate subject identity for this agent. Defaults to agent:demo (or FIDACY_SUBJECT).
|
|
40
|
+
"description": "Mandate subject identity for this agent. Defaults to agent:demo (or FIDACY_SUBJECT)."
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fidacy/openclaw-plugin",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
4
4
|
"description": "Fidacy payment firewall as a native OpenClaw plugin: signed, verifiable verdicts on every money-moving agent action, in-process (no MCP subprocess).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fidacy (ZeepCode Group Technology LLC) <hello@fidacy.com> (https://fidacy.com)",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"typebox": "1.1.39",
|
|
58
58
|
"typescript": "^5.6.3",
|
|
59
59
|
"@fidacy/firewall": "0.1.1",
|
|
60
|
-
"@fidacy/mcp": "0.7.
|
|
60
|
+
"@fidacy/mcp": "0.7.4"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "node scripts/bundle.mjs",
|