@muhaven/mcp 0.2.2 → 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 +24 -0
- package/dist/broker.cjs +1 -1
- package/dist/broker.js +1 -1
- package/dist/index.cjs +16 -3
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +16 -3
- package/manifest.json +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,30 @@ 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
|
+
|
|
10
34
|
## [0.2.2] — 2026-05-23
|
|
11
35
|
|
|
12
36
|
### Fixed
|
package/dist/broker.cjs
CHANGED
package/dist/broker.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1194,9 +1194,16 @@ var BundlerClient = class {
|
|
|
1194
1194
|
const timer = setTimeout(() => ctrl.abort(), this.options.requestTimeoutMs);
|
|
1195
1195
|
let res;
|
|
1196
1196
|
try {
|
|
1197
|
+
const headers = {
|
|
1198
|
+
"content-type": "application/json",
|
|
1199
|
+
accept: "application/json"
|
|
1200
|
+
};
|
|
1201
|
+
if (this.options.originHeader) {
|
|
1202
|
+
headers["origin"] = this.options.originHeader;
|
|
1203
|
+
}
|
|
1197
1204
|
res = await this.fetchImpl(this.options.endpoint, {
|
|
1198
1205
|
method: "POST",
|
|
1199
|
-
headers
|
|
1206
|
+
headers,
|
|
1200
1207
|
body,
|
|
1201
1208
|
signal: ctrl.signal
|
|
1202
1209
|
});
|
|
@@ -3025,7 +3032,7 @@ var SERVER_NAME = "@muhaven/mcp";
|
|
|
3025
3032
|
var SERVER_VERSION = resolveServerVersion();
|
|
3026
3033
|
function resolveServerVersion() {
|
|
3027
3034
|
{
|
|
3028
|
-
return "0.2.
|
|
3035
|
+
return "0.2.3";
|
|
3029
3036
|
}
|
|
3030
3037
|
}
|
|
3031
3038
|
function toJsonInputSchema(schema) {
|
|
@@ -3166,7 +3173,13 @@ async function runMcpStdioCli(opts = {}) {
|
|
|
3166
3173
|
const bundler = config.bundlerUrl ? new BundlerClient({
|
|
3167
3174
|
endpoint: config.bundlerUrl,
|
|
3168
3175
|
requestTimeoutMs: config.bundlerTimeoutMs,
|
|
3169
|
-
expectedChainId: config.chainId
|
|
3176
|
+
expectedChainId: config.chainId,
|
|
3177
|
+
// Wave 5 Path D 0.2.3 — Origin defaults to the dashboard URL
|
|
3178
|
+
// so ZeroDev's domain-allowlist accepts the MCP server's RPC
|
|
3179
|
+
// traffic. The dashboard URL is the natural match because it's
|
|
3180
|
+
// also the SIWE / passkey origin the project already trusts
|
|
3181
|
+
// for browser-side traffic.
|
|
3182
|
+
originHeader: config.dashboardBaseUrl
|
|
3170
3183
|
}) : void 0;
|
|
3171
3184
|
const baseRegistry = selectRegistry(config.readOnly);
|
|
3172
3185
|
const registry = opts.filterRegistry ? opts.filterRegistry(baseRegistry) : baseRegistry;
|
package/dist/index.d.cts
CHANGED
|
@@ -753,6 +753,24 @@ interface BundlerClientOptions {
|
|
|
753
753
|
/** Expected chain id (Arb Sepolia = 421614). When set, `assertChainId()`
|
|
754
754
|
* refuses to proceed if the bundler reports a different chain. */
|
|
755
755
|
readonly expectedChainId?: number;
|
|
756
|
+
/**
|
|
757
|
+
* Wave 5 Path D 0.2.3 — `Origin` header sent on every bundler RPC.
|
|
758
|
+
*
|
|
759
|
+
* Why: ZeroDev's bundler URLs gate access via an IP+domain allowlist.
|
|
760
|
+
* Browser requests from `https://muhaven.app` pass because the
|
|
761
|
+
* project's allowlist includes that domain; Node `fetch` (the MCP
|
|
762
|
+
* server's transport) sends no `Origin` header by default and so
|
|
763
|
+
* hits a 403 "Neither IP nor domain is on the allowlist". Sending
|
|
764
|
+
* an `Origin` matching the project's allowlisted domain unblocks
|
|
765
|
+
* the MCP server without requiring an operator-side ZeroDev
|
|
766
|
+
* dashboard edit. Mirrors how ethers.js + viem's HTTP transports
|
|
767
|
+
* stamp a default `Origin` against EVM RPC providers.
|
|
768
|
+
*
|
|
769
|
+
* Defaults to `https://muhaven.app` at the call site
|
|
770
|
+
* (`server.ts::buildMcpServer`) — operators on a custom dashboard
|
|
771
|
+
* URL override via `MUHAVEN_DASHBOARD_URL`.
|
|
772
|
+
*/
|
|
773
|
+
readonly originHeader?: string;
|
|
756
774
|
/** Inject for tests. */
|
|
757
775
|
readonly fetchImpl?: typeof fetch;
|
|
758
776
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -753,6 +753,24 @@ interface BundlerClientOptions {
|
|
|
753
753
|
/** Expected chain id (Arb Sepolia = 421614). When set, `assertChainId()`
|
|
754
754
|
* refuses to proceed if the bundler reports a different chain. */
|
|
755
755
|
readonly expectedChainId?: number;
|
|
756
|
+
/**
|
|
757
|
+
* Wave 5 Path D 0.2.3 — `Origin` header sent on every bundler RPC.
|
|
758
|
+
*
|
|
759
|
+
* Why: ZeroDev's bundler URLs gate access via an IP+domain allowlist.
|
|
760
|
+
* Browser requests from `https://muhaven.app` pass because the
|
|
761
|
+
* project's allowlist includes that domain; Node `fetch` (the MCP
|
|
762
|
+
* server's transport) sends no `Origin` header by default and so
|
|
763
|
+
* hits a 403 "Neither IP nor domain is on the allowlist". Sending
|
|
764
|
+
* an `Origin` matching the project's allowlisted domain unblocks
|
|
765
|
+
* the MCP server without requiring an operator-side ZeroDev
|
|
766
|
+
* dashboard edit. Mirrors how ethers.js + viem's HTTP transports
|
|
767
|
+
* stamp a default `Origin` against EVM RPC providers.
|
|
768
|
+
*
|
|
769
|
+
* Defaults to `https://muhaven.app` at the call site
|
|
770
|
+
* (`server.ts::buildMcpServer`) — operators on a custom dashboard
|
|
771
|
+
* URL override via `MUHAVEN_DASHBOARD_URL`.
|
|
772
|
+
*/
|
|
773
|
+
readonly originHeader?: string;
|
|
756
774
|
/** Inject for tests. */
|
|
757
775
|
readonly fetchImpl?: typeof fetch;
|
|
758
776
|
}
|
package/dist/index.js
CHANGED
|
@@ -1190,9 +1190,16 @@ var BundlerClient = class {
|
|
|
1190
1190
|
const timer = setTimeout(() => ctrl.abort(), this.options.requestTimeoutMs);
|
|
1191
1191
|
let res;
|
|
1192
1192
|
try {
|
|
1193
|
+
const headers = {
|
|
1194
|
+
"content-type": "application/json",
|
|
1195
|
+
accept: "application/json"
|
|
1196
|
+
};
|
|
1197
|
+
if (this.options.originHeader) {
|
|
1198
|
+
headers["origin"] = this.options.originHeader;
|
|
1199
|
+
}
|
|
1193
1200
|
res = await this.fetchImpl(this.options.endpoint, {
|
|
1194
1201
|
method: "POST",
|
|
1195
|
-
headers
|
|
1202
|
+
headers,
|
|
1196
1203
|
body,
|
|
1197
1204
|
signal: ctrl.signal
|
|
1198
1205
|
});
|
|
@@ -3021,7 +3028,7 @@ var SERVER_NAME = "@muhaven/mcp";
|
|
|
3021
3028
|
var SERVER_VERSION = resolveServerVersion();
|
|
3022
3029
|
function resolveServerVersion() {
|
|
3023
3030
|
{
|
|
3024
|
-
return "0.2.
|
|
3031
|
+
return "0.2.3";
|
|
3025
3032
|
}
|
|
3026
3033
|
}
|
|
3027
3034
|
function toJsonInputSchema(schema) {
|
|
@@ -3162,7 +3169,13 @@ async function runMcpStdioCli(opts = {}) {
|
|
|
3162
3169
|
const bundler = config.bundlerUrl ? new BundlerClient({
|
|
3163
3170
|
endpoint: config.bundlerUrl,
|
|
3164
3171
|
requestTimeoutMs: config.bundlerTimeoutMs,
|
|
3165
|
-
expectedChainId: config.chainId
|
|
3172
|
+
expectedChainId: config.chainId,
|
|
3173
|
+
// Wave 5 Path D 0.2.3 — Origin defaults to the dashboard URL
|
|
3174
|
+
// so ZeroDev's domain-allowlist accepts the MCP server's RPC
|
|
3175
|
+
// traffic. The dashboard URL is the natural match because it's
|
|
3176
|
+
// also the SIWE / passkey origin the project already trusts
|
|
3177
|
+
// for browser-side traffic.
|
|
3178
|
+
originHeader: config.dashboardBaseUrl
|
|
3166
3179
|
}) : void 0;
|
|
3167
3180
|
const baseRegistry = selectRegistry(config.readOnly);
|
|
3168
3181
|
const registry = opts.filterRegistry ? opts.filterRegistry(baseRegistry) : baseRegistry;
|
package/manifest.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"manifest_version": "0.2",
|
|
4
4
|
"name": "muhaven-mcp",
|
|
5
5
|
"display_name": "MuHaven (RWA portfolio)",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.3",
|
|
7
7
|
"description": "Confidential RWA portfolio management on Fhenix CoFHE. Read your encrypted balances, propose yield claims and policy changes — all signing happens in a sibling broker daemon, the LLM never sees your private key.",
|
|
8
8
|
"long_description": "MuHaven MCP exposes 24 tools across read.* / position.* / policy.* / issuer.* / governance.* groups for managing real-world asset (RWA) tokens with FHE-encrypted balances. Authentication uses a one-time device-code ceremony (run `muhaven-broker login`); subsequent tool calls fetch the JWT from the broker over a Unix socket. Position / governance tools deep-link to the dashboard for passkey signing — they NEVER auto-submit to a bundler. The companion `muhaven-broker` daemon must be running before tools can be invoked. See README for setup.",
|
|
9
9
|
"author": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@muhaven/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "MuHaven MCP server — read/position/policy toolsets bridging Claude Desktop / Cursor / Claude Code to the MuHaven backend, with a sibling muhaven-broker daemon holding the session-key private half over a local IPC socket",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|