@muhaven/mcp 0.4.1 → 0.4.2

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,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.4.2] — 2026-05-24
11
+
12
+ ### Fixed
13
+
14
+ - **Revoke kill-switch — MCP-side gate (defense-in-depth).** A revoked
15
+ Scoped session let an already-running broker keep buying autonomously
16
+ (the broker signs from a local snapshot with no "revoked" concept and the
17
+ on-chain validator stays installed). `position.buy` Path D now hard-gates
18
+ on the backend mirror: when the broker hands over an active snapshot but
19
+ `GET /agent/policy/scoped-session` reports NO active session (= revoked or
20
+ expired on the dashboard), the buy refuses with the new
21
+ `pathDFallbackReason: 'session_revoked'`, best-effort calls the broker's
22
+ `clear_policy_snapshot` to purge the dormant key-backed snapshot, and
23
+ falls back to the Path C deep-link. A transient mirror-fetch ERROR is
24
+ still treated as best-effort (not "revoked") so a backend blip doesn't
25
+ break Path D. The authoritative enforcement is the server-side
26
+ `encrypt-shares` gate (backend change, same release window); this MCP
27
+ check is the fast, clear fail before the encrypt round-trip. SecEng
28
+ investigation 2026-05-24.
29
+
10
30
  ## [0.4.1] — 2026-05-24
11
31
 
12
32
  ### Added
package/dist/broker.cjs CHANGED
@@ -3591,7 +3591,7 @@ function printUsage() {
3591
3591
  }
3592
3592
  function getBrokerPackageVersion() {
3593
3593
  {
3594
- return "0.4.1";
3594
+ return "0.4.2";
3595
3595
  }
3596
3596
  }
3597
3597
  function printVersion() {
package/dist/broker.js CHANGED
@@ -3593,7 +3593,7 @@ function printUsage() {
3593
3593
  }
3594
3594
  function getBrokerPackageVersion() {
3595
3595
  {
3596
- return "0.4.1";
3596
+ return "0.4.2";
3597
3597
  }
3598
3598
  }
3599
3599
  function printVersion() {
package/dist/index.cjs CHANGED
@@ -2799,18 +2799,33 @@ async function attemptPathD(args, deps) {
2799
2799
  message: `backend /agent/policy/state lookup failed: ${err2 instanceof Error ? err2.message : String(err2)}`
2800
2800
  };
2801
2801
  }
2802
+ let mirrorFetchOk = false;
2803
+ let mirrorHadActiveSession = false;
2802
2804
  try {
2803
2805
  const mirror = await deps.backend.get(
2804
2806
  "/api/v1/agent/policy/scoped-session",
2805
2807
  { surface: "mcp" }
2806
2808
  );
2809
+ mirrorFetchOk = true;
2807
2810
  if (mirror?.session) {
2811
+ mirrorHadActiveSession = true;
2808
2812
  mirrorSessionRow = mirror.session;
2809
2813
  mirrorEnableStatus = mirror.session.enableStatus ?? null;
2810
2814
  mirrorValidatorNonce = mirror.session.validatorNonce ?? null;
2811
2815
  }
2812
2816
  } catch (err2) {
2813
2817
  }
2818
+ if (mirrorFetchOk && !mirrorHadActiveSession) {
2819
+ try {
2820
+ await deps.broker.clearPolicySnapshot(activeId);
2821
+ } catch {
2822
+ }
2823
+ return {
2824
+ kind: "fallback",
2825
+ reason: "session_revoked",
2826
+ message: "the Scoped session was revoked (or expired) on the dashboard \u2014 the broker snapshot is stale; purged it and falling back to Path C. Re-mint a Scoped session to resume autonomous buys."
2827
+ };
2828
+ }
2814
2829
  if (!snapshot.permissionId) {
2815
2830
  return {
2816
2831
  kind: "fallback",
@@ -3680,7 +3695,7 @@ var SERVER_NAME = "@muhaven/mcp";
3680
3695
  var SERVER_VERSION = resolveServerVersion();
3681
3696
  function resolveServerVersion() {
3682
3697
  {
3683
- return "0.4.1";
3698
+ return "0.4.2";
3684
3699
  }
3685
3700
  }
3686
3701
  function toJsonInputSchema(schema) {
package/dist/index.js CHANGED
@@ -2795,18 +2795,33 @@ async function attemptPathD(args, deps) {
2795
2795
  message: `backend /agent/policy/state lookup failed: ${err2 instanceof Error ? err2.message : String(err2)}`
2796
2796
  };
2797
2797
  }
2798
+ let mirrorFetchOk = false;
2799
+ let mirrorHadActiveSession = false;
2798
2800
  try {
2799
2801
  const mirror = await deps.backend.get(
2800
2802
  "/api/v1/agent/policy/scoped-session",
2801
2803
  { surface: "mcp" }
2802
2804
  );
2805
+ mirrorFetchOk = true;
2803
2806
  if (mirror?.session) {
2807
+ mirrorHadActiveSession = true;
2804
2808
  mirrorSessionRow = mirror.session;
2805
2809
  mirrorEnableStatus = mirror.session.enableStatus ?? null;
2806
2810
  mirrorValidatorNonce = mirror.session.validatorNonce ?? null;
2807
2811
  }
2808
2812
  } catch (err2) {
2809
2813
  }
2814
+ if (mirrorFetchOk && !mirrorHadActiveSession) {
2815
+ try {
2816
+ await deps.broker.clearPolicySnapshot(activeId);
2817
+ } catch {
2818
+ }
2819
+ return {
2820
+ kind: "fallback",
2821
+ reason: "session_revoked",
2822
+ message: "the Scoped session was revoked (or expired) on the dashboard \u2014 the broker snapshot is stale; purged it and falling back to Path C. Re-mint a Scoped session to resume autonomous buys."
2823
+ };
2824
+ }
2810
2825
  if (!snapshot.permissionId) {
2811
2826
  return {
2812
2827
  kind: "fallback",
@@ -3676,7 +3691,7 @@ var SERVER_NAME = "@muhaven/mcp";
3676
3691
  var SERVER_VERSION = resolveServerVersion();
3677
3692
  function resolveServerVersion() {
3678
3693
  {
3679
- return "0.4.1";
3694
+ return "0.4.2";
3680
3695
  }
3681
3696
  }
3682
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.1",
6
+ "version": "0.4.2",
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.1",
3
+ "version": "0.4.2",
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": {