@floatonnear/mcp 0.6.0 → 0.6.1

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/dist/rpc.d.ts CHANGED
@@ -17,6 +17,34 @@
17
17
  * https://docs.near.org/api/rpc/providers
18
18
  */
19
19
  export declare const DEFAULT_RPC_URL = "https://test.rpc.fastnear.com";
20
+ /**
21
+ * The RPC to use for a given NETWORK.
22
+ *
23
+ * WHY THIS EXISTS. `vault_create` takes a `network` argument, resolved the
24
+ * right factory for it, and then asked `cfg.rpcUrl` — a single value
25
+ * defaulting to testnet. So a user asking for a mainnet vault got:
26
+ *
27
+ * account usefloat.near does not exist while viewing
28
+ *
29
+ * about an account that demonstrably does exist. The factory was right and
30
+ * the chain was wrong, which reads as "the factory is broken" rather than
31
+ * "you asked the wrong network". Shipped in 0.6.0 and found by driving the
32
+ * published package instead of reading its diff.
33
+ */
34
+ export declare const RPC_BY_NETWORK: Record<string, string>;
35
+ /**
36
+ * Pick an RPC for `net`, honouring an operator override ONLY where it applies.
37
+ *
38
+ * An explicit NEAR_VAULT_RPC_URL is configured for ONE network — whichever the
39
+ * operator set NEAR_VAULT_NETWORK to. Applying it to the other network is the
40
+ * same bug in a new place: it would send a mainnet question to a testnet
41
+ * endpoint and report the answer as fact. So the override wins only when the
42
+ * requested network is the one it was configured for.
43
+ */
44
+ export declare function rpcForNetwork(net: string, opts?: {
45
+ configuredNetwork?: string;
46
+ override?: string;
47
+ }): string;
20
48
  export declare function encodeArgs(args: unknown): string;
21
49
  interface RawViewResponse {
22
50
  result?: number[];
package/dist/rpc.js CHANGED
@@ -18,6 +18,38 @@ import { randomUUID } from "node:crypto";
18
18
  * https://docs.near.org/api/rpc/providers
19
19
  */
20
20
  export const DEFAULT_RPC_URL = "https://test.rpc.fastnear.com";
21
+ /**
22
+ * The RPC to use for a given NETWORK.
23
+ *
24
+ * WHY THIS EXISTS. `vault_create` takes a `network` argument, resolved the
25
+ * right factory for it, and then asked `cfg.rpcUrl` — a single value
26
+ * defaulting to testnet. So a user asking for a mainnet vault got:
27
+ *
28
+ * account usefloat.near does not exist while viewing
29
+ *
30
+ * about an account that demonstrably does exist. The factory was right and
31
+ * the chain was wrong, which reads as "the factory is broken" rather than
32
+ * "you asked the wrong network". Shipped in 0.6.0 and found by driving the
33
+ * published package instead of reading its diff.
34
+ */
35
+ export const RPC_BY_NETWORK = {
36
+ testnet: "https://test.rpc.fastnear.com",
37
+ mainnet: "https://free.rpc.fastnear.com",
38
+ };
39
+ /**
40
+ * Pick an RPC for `net`, honouring an operator override ONLY where it applies.
41
+ *
42
+ * An explicit NEAR_VAULT_RPC_URL is configured for ONE network — whichever the
43
+ * operator set NEAR_VAULT_NETWORK to. Applying it to the other network is the
44
+ * same bug in a new place: it would send a mainnet question to a testnet
45
+ * endpoint and report the answer as fact. So the override wins only when the
46
+ * requested network is the one it was configured for.
47
+ */
48
+ export function rpcForNetwork(net, opts = {}) {
49
+ if (opts.override && net === opts.configuredNetwork)
50
+ return opts.override;
51
+ return RPC_BY_NETWORK[net] ?? DEFAULT_RPC_URL;
52
+ }
21
53
  export function encodeArgs(args) {
22
54
  // Explicit utf8: a memo is free text, goes on-chain, and a latin-1
23
55
  // truncation here would corrupt it silently.
package/dist/server.js CHANGED
@@ -49,7 +49,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
49
49
  import { z } from "zod";
50
50
  import { fromBaseUnits, toBaseUnits } from "./amounts.js";
51
51
  import { DEFAULT_GAS_TGAS, planAddNode, planAddRole, planBindVirtualAgent, planUnbindVirtualAgent, planFreezeNode, planPurgeSettled, planSetCooldown, planSetNodeCaps, planSetPaused, planSetRecipients, toCliCommand, planSetApprovalThreshold, planApprovePayment, planRejectPayment, planWithdraw, } from "./payloads.js";
52
- import { accountExists, DEFAULT_RPC_URL, newRequestId, requireAgentKey, viewAccessKeys, viewAccount, viewFunction, } from "./rpc.js";
52
+ import { accountExists, rpcForNetwork, DEFAULT_RPC_URL, newRequestId, requireAgentKey, viewAccessKeys, viewAccount, viewFunction, } from "./rpc.js";
53
53
  import { AGENT_NODE_ID, generateAgentKey } from "./agent-key.js";
54
54
  import { resolveKeySource } from "./key-file.js";
55
55
  import { dirname } from "node:path";
@@ -233,7 +233,7 @@ WORTH KNOWING
233
233
  An implicit account (a 64-character hex id) cannot own a vault at all. Tell the user to use a
234
234
  named account rather than retrying.
235
235
  Amounts are whole tokens in these tools (1.5 means 1.5 USDC), never base units.`;
236
- const server = new McpServer({ name: "float", version: "0.6.0" }, { instructions: INSTRUCTIONS });
236
+ const server = new McpServer({ name: "float", version: "0.6.1" }, { instructions: INSTRUCTIONS });
237
237
  // ----------------------------------------------------------------- reads
238
238
  server.tool("vault_tree", "Read the whole budget tree: every node, its caps, parent, bound agent account, cooldown and freeze state. No key required.", {}, async () => json(await viewFunction(cfg.rpcUrl, requireVault(), "get_tree", {})));
239
239
  server.tool("vault_budget", "Read one node's budget for a UTC day: cap, executed, in-flight (pending) and available, in human units. Omit `day` for today. No key required.", {
@@ -352,7 +352,14 @@ server.tool("vault_create", "For a user who has NO vault yet. Works out where th
352
352
  `NEAR_VAULT_FACTORY. There is deliberately no built-in mainnet default: ` +
353
353
  `guessing it wrong would send a real deposit somewhere unverified.`);
354
354
  }
355
- const rpc = cfg.rpcUrl;
355
+ // THE RPC MUST FOLLOW THE NETWORK, not the process's default. 0.6.0
356
+ // resolved the right factory for `net` and then asked the testnet RPC
357
+ // about it, so a mainnet request answered "usefloat.near does not exist"
358
+ // about an account that does.
359
+ const rpc = rpcForNetwork(net, {
360
+ configuredNetwork: cfg.network,
361
+ override: process.env.NEAR_VAULT_RPC_URL,
362
+ });
356
363
  // Only ask the factory to derive an id when there IS an owner. With none,
357
364
  // the address is decided by whichever wallet signs, and inventing one here
358
365
  // would print a plausible address next to a real deposit figure.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floatonnear/mcp",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "description": "MCP server for the hierarchical budget vault. The agent key signs request_payment only; owner methods emit unsigned payloads for wallet approval.",
6
6
  "license": "MIT",