@muhaven/mcp 0.4.2 → 0.4.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,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.3] — 2026-05-24
11
+
12
+ ### Changed
13
+
14
+ - **`muhaven-broker setup` no longer silently uses an opaque env key.** When
15
+ `MUHAVEN_BROKER_SESSION_KEY` is set (its "scriptable" precedence over the
16
+ interactive prompt), setup now (a) **validates the key's shape up front**
17
+ — a malformed value fails with a clear error + an unset hint instead of a
18
+ confusing daemon crash later — and (b) **prints the derived signer
19
+ address**: `Session key: using MUHAVEN_BROKER_SESSION_KEY from env (signer
20
+ 0x…)`, plus a one-line "unset it to paste a dashboard key instead" hint. So
21
+ a STALE/unintended lingering env key is obvious rather than silently
22
+ adopted. The pasted-key and self-mint paths print the signer too, matching
23
+ `start`/`update`'s `Broker signer: 0x…`. New exported `deriveSignerAddress`
24
+ helper (display-only; never logs the private key). Operator-found on 0.4.2.
25
+
10
26
  ## [0.4.2] — 2026-05-24
11
27
 
12
28
  ### Fixed
package/dist/broker.cjs CHANGED
@@ -2457,6 +2457,13 @@ function applyEnvDefaults(input) {
2457
2457
  function mintSessionKey() {
2458
2458
  return accounts.generatePrivateKey();
2459
2459
  }
2460
+ function deriveSignerAddress(privateKeyHex) {
2461
+ try {
2462
+ return accounts.privateKeyToAccount(privateKeyHex).address;
2463
+ } catch {
2464
+ return null;
2465
+ }
2466
+ }
2460
2467
  function decideSetupAction(input) {
2461
2468
  if (input.hello === null) return "spawn_and_login";
2462
2469
  if (!input.hello.hasJwt) return "login_only";
@@ -2793,7 +2800,21 @@ async function runSetup(argv, deps) {
2793
2800
  let sessionKey = effectiveEnv.MUHAVEN_BROKER_SESSION_KEY;
2794
2801
  let mintedKey = false;
2795
2802
  if (sessionKey && sessionKey.length > 0) {
2796
- deps.print("Session key: using MUHAVEN_BROKER_SESSION_KEY from env.");
2803
+ const shapeErr = validateSessionKeyShape(sessionKey);
2804
+ if (shapeErr) {
2805
+ deps.printErr(`error: MUHAVEN_BROKER_SESSION_KEY is set but invalid \u2014 ${shapeErr}`);
2806
+ deps.printErr(
2807
+ " Unset MUHAVEN_BROKER_SESSION_KEY to paste a dashboard key (or fix the value), then re-run setup."
2808
+ );
2809
+ return 2;
2810
+ }
2811
+ const signer = deriveSignerAddress(sessionKey);
2812
+ deps.print(
2813
+ `Session key: using MUHAVEN_BROKER_SESSION_KEY from env${signer ? ` (signer ${signer})` : ""}.`
2814
+ );
2815
+ deps.print(
2816
+ " To paste a dashboard-minted key instead, unset MUHAVEN_BROKER_SESSION_KEY first."
2817
+ );
2797
2818
  } else {
2798
2819
  const sessionInput = deps.sessionInput ?? {
2799
2820
  isTty: false,
@@ -2812,11 +2833,17 @@ async function runSetup(argv, deps) {
2812
2833
  }
2813
2834
  if (resolution.kind === "key") {
2814
2835
  sessionKey = resolution.key;
2815
- deps.print("Session key: using the pasted dashboard key.");
2836
+ const signer = deriveSignerAddress(sessionKey);
2837
+ deps.print(
2838
+ `Session key: using the pasted dashboard key${signer ? ` (signer ${signer})` : ""}.`
2839
+ );
2816
2840
  } else {
2817
2841
  sessionKey = deps.mintSessionKey();
2818
2842
  mintedKey = true;
2819
- deps.print("Session key: minted fresh (secp256k1, ephemeral to this daemon).");
2843
+ const signer = deriveSignerAddress(sessionKey);
2844
+ deps.print(
2845
+ `Session key: minted fresh (secp256k1, ephemeral to this daemon)${signer ? ` \u2014 signer ${signer}` : ""}.`
2846
+ );
2820
2847
  }
2821
2848
  }
2822
2849
  effectiveEnv.MUHAVEN_BROKER_SESSION_KEY = sessionKey;
@@ -3591,7 +3618,7 @@ function printUsage() {
3591
3618
  }
3592
3619
  function getBrokerPackageVersion() {
3593
3620
  {
3594
- return "0.4.2";
3621
+ return "0.4.3";
3595
3622
  }
3596
3623
  }
3597
3624
  function printVersion() {
package/dist/broker.js CHANGED
@@ -2459,6 +2459,13 @@ function applyEnvDefaults(input) {
2459
2459
  function mintSessionKey() {
2460
2460
  return generatePrivateKey();
2461
2461
  }
2462
+ function deriveSignerAddress(privateKeyHex) {
2463
+ try {
2464
+ return privateKeyToAccount(privateKeyHex).address;
2465
+ } catch {
2466
+ return null;
2467
+ }
2468
+ }
2462
2469
  function decideSetupAction(input) {
2463
2470
  if (input.hello === null) return "spawn_and_login";
2464
2471
  if (!input.hello.hasJwt) return "login_only";
@@ -2795,7 +2802,21 @@ async function runSetup(argv, deps) {
2795
2802
  let sessionKey = effectiveEnv.MUHAVEN_BROKER_SESSION_KEY;
2796
2803
  let mintedKey = false;
2797
2804
  if (sessionKey && sessionKey.length > 0) {
2798
- deps.print("Session key: using MUHAVEN_BROKER_SESSION_KEY from env.");
2805
+ const shapeErr = validateSessionKeyShape(sessionKey);
2806
+ if (shapeErr) {
2807
+ deps.printErr(`error: MUHAVEN_BROKER_SESSION_KEY is set but invalid \u2014 ${shapeErr}`);
2808
+ deps.printErr(
2809
+ " Unset MUHAVEN_BROKER_SESSION_KEY to paste a dashboard key (or fix the value), then re-run setup."
2810
+ );
2811
+ return 2;
2812
+ }
2813
+ const signer = deriveSignerAddress(sessionKey);
2814
+ deps.print(
2815
+ `Session key: using MUHAVEN_BROKER_SESSION_KEY from env${signer ? ` (signer ${signer})` : ""}.`
2816
+ );
2817
+ deps.print(
2818
+ " To paste a dashboard-minted key instead, unset MUHAVEN_BROKER_SESSION_KEY first."
2819
+ );
2799
2820
  } else {
2800
2821
  const sessionInput = deps.sessionInput ?? {
2801
2822
  isTty: false,
@@ -2814,11 +2835,17 @@ async function runSetup(argv, deps) {
2814
2835
  }
2815
2836
  if (resolution.kind === "key") {
2816
2837
  sessionKey = resolution.key;
2817
- deps.print("Session key: using the pasted dashboard key.");
2838
+ const signer = deriveSignerAddress(sessionKey);
2839
+ deps.print(
2840
+ `Session key: using the pasted dashboard key${signer ? ` (signer ${signer})` : ""}.`
2841
+ );
2818
2842
  } else {
2819
2843
  sessionKey = deps.mintSessionKey();
2820
2844
  mintedKey = true;
2821
- deps.print("Session key: minted fresh (secp256k1, ephemeral to this daemon).");
2845
+ const signer = deriveSignerAddress(sessionKey);
2846
+ deps.print(
2847
+ `Session key: minted fresh (secp256k1, ephemeral to this daemon)${signer ? ` \u2014 signer ${signer}` : ""}.`
2848
+ );
2822
2849
  }
2823
2850
  }
2824
2851
  effectiveEnv.MUHAVEN_BROKER_SESSION_KEY = sessionKey;
@@ -3593,7 +3620,7 @@ function printUsage() {
3593
3620
  }
3594
3621
  function getBrokerPackageVersion() {
3595
3622
  {
3596
- return "0.4.2";
3623
+ return "0.4.3";
3597
3624
  }
3598
3625
  }
3599
3626
  function printVersion() {
package/dist/index.cjs CHANGED
@@ -3695,7 +3695,7 @@ var SERVER_NAME = "@muhaven/mcp";
3695
3695
  var SERVER_VERSION = resolveServerVersion();
3696
3696
  function resolveServerVersion() {
3697
3697
  {
3698
- return "0.4.2";
3698
+ return "0.4.3";
3699
3699
  }
3700
3700
  }
3701
3701
  function toJsonInputSchema(schema) {
package/dist/index.js CHANGED
@@ -3691,7 +3691,7 @@ var SERVER_NAME = "@muhaven/mcp";
3691
3691
  var SERVER_VERSION = resolveServerVersion();
3692
3692
  function resolveServerVersion() {
3693
3693
  {
3694
- return "0.4.2";
3694
+ return "0.4.3";
3695
3695
  }
3696
3696
  }
3697
3697
  function toJsonInputSchema(schema) {
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.4.2",
6
+ "version": "0.4.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.4.2",
3
+ "version": "0.4.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": {