@muhaven/mcp 0.2.1 → 0.2.3

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
@@ -7,6 +7,131 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.3] — 2026-05-23
11
+
12
+ ### Fixed
13
+
14
+ - **`BundlerClient` now sends an `Origin` header on every RPC.** ZeroDev
15
+ bundler URLs gate access via an IP+domain allowlist; browser requests
16
+ from `https://muhaven.app` pass because the project's allowlist
17
+ accepts that domain, but Node `fetch` (the MCP server's transport)
18
+ sends no `Origin` by default and so hit a `403 "Neither IP nor domain
19
+ is on the allowlist"` on every `eth_call` / `eth_gasPrice`. The MCP
20
+ server then surfaced this as `pathDFallbackReason:
21
+ bundler_setup_failed` and degraded to Path C. Fix: stamp `Origin:
22
+ <MUHAVEN_DASHBOARD_URL>` on every bundler RPC (defaults to
23
+ `https://muhaven.app`, threaded through from
24
+ `buildMcpServer({ dashboardBaseUrl })`). Mirrors how ethers.js + viem
25
+ stamp default Origins against EVM RPC providers; surfaces a single
26
+ knob (`MUHAVEN_DASHBOARD_URL`) for operators on a custom domain.
27
+ Diagnosed 2026-05-23 via direct curl reproduction (bare → 403; with
28
+ `Origin: https://muhaven.app` → `result: 0x66eee`).
29
+
30
+ Added 3 regression tests pinning the contract (Origin sent when set;
31
+ omitted when undefined; omitted when explicitly empty for test
32
+ injection).
33
+
34
+ ## [0.2.2] — 2026-05-23
35
+
36
+ ### Fixed
37
+
38
+ - **`tools/list.inputSchema` now exposes the per-field shape, not a
39
+ bare `{type:'object', additionalProperties:false}` placeholder.**
40
+ The 0.2.1 (and earlier) `toJsonInputSchema` was a stub: it returned
41
+ the object envelope with `additionalProperties:false` but no
42
+ `properties` block. JSON-Schema-compliant MCP hosts (Claude Code's
43
+ tool-call validator) interpret that combination as "no properties
44
+ allowed" and silently strip every argument before dispatch — every
45
+ call landed at the server as `{}`. Surfaced 2026-05-23 by an
46
+ operator-side `Buy TBILL1 $1` smoke. Fix: wire `zod-to-json-schema`
47
+ (`target: 'jsonSchema7'`, `$refStrategy: 'none'`,
48
+ `removeAdditionalStrategy: 'strict'`) so the real per-field shape
49
+ reaches the host. Drops the top-level `$schema` URL (host noise).
50
+ Added 14 unit + 48 registry-wide regression cases pinning the
51
+ contract per tool, plus a recursive nested-strict walker that fails
52
+ if a future contributor adds a nested `z.object(...)` without
53
+ `.strict()` (Security Engineer MED, absorbed inline).
54
+
55
+ ### Dependencies
56
+
57
+ - **Added `zod-to-json-schema@^3.24.0`** as a runtime dep (~30KB, zero
58
+ transitive deps). Required by the inputSchema fix above; previously
59
+ the converter was a placeholder stub per the original commit's note
60
+ to "avoid runtime dep for hackathon scope."
61
+ - **Bumped `zod` dep range from `^3.24.0` to `^3.25.0`** to match
62
+ `@modelcontextprotocol/sdk@^1.0.4`'s peer-dep declaration
63
+ (`zod: ^3.25 || ^4.0`). The installed tree already resolves to
64
+ 3.25.x so prod runtime is unchanged, but the declared range avoids
65
+ a peer-dep warning for consumers running `npm i @muhaven/mcp` with
66
+ an older zod hoisted in their tree (Code Reviewer HIGH, absorbed
67
+ inline).
68
+
69
+ ### Notes
70
+
71
+ - **`tool-hashes.json` does NOT need regenerating for 0.2.2.** The
72
+ hashed surface is the tool descriptor (name + description +
73
+ sensitive flag, see `descriptions.ts::hashToolDescriptor`); the
74
+ JSON-Schema export is downstream of that and not part of the hash.
75
+ `pnpm verify-tool-hashes -- --check` continues to pass against the
76
+ existing pin from 0.2.0.
77
+
78
+ ### Added — Wave 5 Path D Slice 1 (in flight)
79
+
80
+ - **Broker protocol verb `get_active_session_id`** (additive over 0.4.0).
81
+ Narrow "which session is live?" probe — returns the sessionId of the
82
+ single non-expired snapshot bound to the broker's loaded signer, or
83
+ null on zero / 2+ matches. Backs the MCP server's bootstrap of Path
84
+ D's broker-side signing path before Slice 2's backend-mirror
85
+ `agent_scoped_sessions` table lands. Intentionally narrower than
86
+ `list()` so RD-3 (no IPC enumeration) stays honoured.
87
+ - **`BrokerClient.preflight()` + semver gate (Backend Architect H-2).**
88
+ Detects stale 0.3.x daemons before any sign_userop call, surfacing
89
+ `version_too_old` / `session_key_unavailable` / `broker_unreachable`
90
+ with structured remediation hints instead of an opaque
91
+ `unsupported_type`.
92
+ - **`BundlerClient` (NEW, `src/clients/bundler-client.ts`).** ERC-4337
93
+ v0.7 JSON-RPC client surface — `sendUserOp` + `getReceipt` +
94
+ `waitForReceipt` + `assertChainId`. Lives MCP-server-side (network
95
+ egress), not in the broker (R-1 zero-egress invariant preserved).
96
+ Configured via new `MUHAVEN_BUNDLER_URL` + `MUHAVEN_CHAIN_ID` env
97
+ vars (manifest.json user_config block extended). The UserOp BUILD +
98
+ SIGN path remains DEFERRED to a later release (FHE encrypt + kernel-
99
+ execute encode have unresolved design points); the bundler-client
100
+ surface ships now with full test coverage.
101
+ - **`positionBuy` Path D probe.** When BOTH bundler and broker are
102
+ configured, the handler runs a preflight chain
103
+ (preflight → getActiveSessionId → getPolicySnapshot → selector-cap
104
+ match → shares cap) BEFORE building the Path C deep-link. Every gate
105
+ failure surfaces as a structured non-retryable
106
+ `pathDFallbackReason` in the echo while still returning a valid
107
+ Path C URL — single affordance for the user, full structured
108
+ observability for the LLM. The "all gates pass" terminal state
109
+ returns `path_d_userop_build_pending` until the UserOp build path
110
+ lands.
111
+ - **`/agent/policy/state` extension** (backend): top-level
112
+ `accountAddress` field (= JWT subject = kernel smart-account
113
+ address). Backward-compatible; older callers ignore the new field.
114
+ Lays foundation for the Commit 3.5 UserOp builder's kernel-address
115
+ lookup without needing a separate /me endpoint.
116
+
117
+ ### Internal — Wave 5 Path D Slice 1
118
+
119
+ - `IPolicyStore.activeSessionId(activeSignerAddress, nowSec)` method —
120
+ enumerates daemon-internal snapshots, returns the unique active
121
+ sessionId or null. File-backed + memory implementations both honour
122
+ the same "zero or ambiguous → null" semantics.
123
+ - 65 new vitest cases across protocol / policy-snapshot / daemon-handler
124
+ / bundler-client / broker-client-preflight / position-deeplink test
125
+ files. Total 474 MCP vitest cases (up from 409). Three-agent parallel
126
+ pre-commit review (Code Reviewer + MCP Builder + Security Engineer
127
+ fresh) absorbed: 4 HIGH addressed inline (BrokerClientError gains
128
+ typed `brokerCode` field with `unsupported_type → version_too_old`
129
+ remap; `attemptPathD` adds signer-mismatch guard + splits
130
+ selector-uncapped vs selector-not-in-snapshot; test stubs replaced
131
+ with Proxy-based throw-on-unstubbed-access); MED-1 closed (semverGte
132
+ regex tightened to reject leading zeros per SemVer 2.0 §2). Security
133
+ Engineer approved with no HIGH findings.
134
+
10
135
  ## [0.2.0] — 2026-05-18
11
136
 
12
137
  **Minor bump signals a breaking change to `position.buy`'s input