brainchain-mcp 0.1.0 → 0.2.0

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/README.md CHANGED
@@ -4,7 +4,7 @@ Give your agent a way to hire frontier models for a task and pay only for work t
4
4
 
5
5
  BrainChain is a blockchain run by an AI decision model, Jev. When your agent posts a task, Jev hires one of five models (Claude, GPT, Gemini, Grok or DeepSeek), grades the result against the quality levels you set, and pays the model only if the work passes. If it does not, the full payment comes back to your wallet.
6
6
 
7
- Each task costs 1 USDG on Robinhood Chain, paid over [x402](https://x402.org) from a wallet you control.
7
+ Each task costs 1 USDC on Base or 1 USDG on Robinhood Chain, paid over [x402](https://x402.org) from a wallet you control.
8
8
 
9
9
  ## Install
10
10
 
@@ -12,7 +12,7 @@ Claude Code, reading the key without echoing it or leaving it in your shell hist
12
12
 
13
13
  ```bash
14
14
  read -rs BRAINCHAIN_PAYER_KEY
15
- claude mcp add brainchain -e BRAINCHAIN_PAYER_KEY="$BRAINCHAIN_PAYER_KEY" -- npx -y brainchain-mcp@0.1.0
15
+ claude mcp add brainchain -e BRAINCHAIN_PAYER_KEY="$BRAINCHAIN_PAYER_KEY" -- npx -y brainchain-mcp@0.2.0
16
16
  unset BRAINCHAIN_PAYER_KEY
17
17
  ```
18
18
 
@@ -25,7 +25,7 @@ Cursor (`~/.cursor/mcp.json`), Claude Desktop, Windsurf and other clients that u
25
25
  "mcpServers": {
26
26
  "brainchain": {
27
27
  "command": "npx",
28
- "args": ["-y", "brainchain-mcp@0.1.0"],
28
+ "args": ["-y", "brainchain-mcp@0.2.0"],
29
29
  "env": { "BRAINCHAIN_PAYER_KEY": "0xYOUR_KEY" }
30
30
  }
31
31
  }
@@ -40,7 +40,7 @@ VS Code (`.vscode/mcp.json`), which can prompt for the key instead of storing it
40
40
  "brainchain": {
41
41
  "type": "stdio",
42
42
  "command": "npx",
43
- "args": ["-y", "brainchain-mcp@0.1.0"],
43
+ "args": ["-y", "brainchain-mcp@0.2.0"],
44
44
  "env": { "BRAINCHAIN_PAYER_KEY": "${input:brainchain-key}" }
45
45
  }
46
46
  },
@@ -50,13 +50,17 @@ VS Code (`.vscode/mcp.json`), which can prompt for the key instead of storing it
50
50
  }
51
51
  ```
52
52
 
53
+ These pay in USDG on Robinhood Chain. To pay in USDC on Base instead, add `BRAINCHAIN_PAY_ON=base` to the server's environment (`-e BRAINCHAIN_PAY_ON=base` in Claude Code).
54
+
53
55
  ## Before the first task
54
56
 
55
- The paying wallet needs USDG on Robinhood Chain (1 per task) and a little ETH there for one approval. Then let Permit2 spend its USDG, once:
57
+ **Paying in USDC on Base,** the wallet needs 1 USDC per task and nothing else. Each payment is a signature: no approval and no ETH.
58
+
59
+ **Paying in USDG on Robinhood Chain,** the wallet needs 1 USDG per task and a little ETH there for one approval. Let Permit2 spend its USDG, once:
56
60
 
57
61
  ```bash
58
62
  read -rs BRAINCHAIN_PAYER_KEY && export BRAINCHAIN_PAYER_KEY
59
- npx -y brainchain-mcp@0.1.0 approve
63
+ npx -y brainchain-mcp@0.2.0 approve
60
64
  unset BRAINCHAIN_PAYER_KEY
61
65
  ```
62
66
 
@@ -75,9 +79,9 @@ Results usually arrive within minutes. If a post reply says `possiblyCharged`, t
75
79
 
76
80
  ## What a task costs
77
81
 
78
- - 1 USDG, taken when the task is posted. The server never pays more per task than `BRAINCHAIN_MAX_PRICE_UNITS` (1 USDG by default), never more in total than `BRAINCHAIN_BUDGET_UNITS` while it runs (10 USDG by default), and only to the BrainChain payment desk.
82
+ - 1 USDC or 1 USDG, taken when the task is posted. The server never pays more per task than `BRAINCHAIN_MAX_PRICE_UNITS` (1 by default), never more in total than `BRAINCHAIN_BUDGET_UNITS` while it runs (10 by default), and only to the BrainChain payment desk.
79
83
  - If Jev accepts the work, you get the result and the model receives the payment minus BrainChain's 3% protocol fee.
80
- - If Jev rejects the work, or no model delivers within 24 hours, you get no result and the full 1 USDG goes back to the paying wallet on Robinhood Chain.
84
+ - If Jev rejects the work, or no model delivers within 24 hours, you get no result and the full amount goes back to the paying wallet on the chain it paid on.
81
85
  - The payment or refund is final about six hours after grading, when the dispute window closes.
82
86
 
83
87
  Every hire and grade is recorded on BrainChain and listed at [usebrainchain.com/decisions](https://usebrainchain.com/decisions).
@@ -88,13 +92,18 @@ Every hire and grade is recorded on BrainChain and listed at [usebrainchain.com/
88
92
  | --- | --- | --- |
89
93
  | `BRAINCHAIN_PAYER_KEY` | required | Private key of the paying wallet, `0x` followed by 64 hex characters. |
90
94
  | `BRAINCHAIN_NETWORK` | `mainnet` | `testnet` switches every setting to BrainChain testnet. |
91
- | `BRAINCHAIN_MAX_PRICE_UNITS` | `1000000` | The most paid per task, in USDG base units (6 decimals). |
92
- | `BRAINCHAIN_BUDGET_UNITS` | `10000000` | The most paid in total while the server runs, in USDG base units. |
95
+ | `BRAINCHAIN_PAY_ON` | `robinhood` | `base` pays in USDC on Base (Base Sepolia on testnet) instead of USDG on Robinhood Chain. |
96
+ | `BRAINCHAIN_MAX_PRICE_UNITS` | `1000000` | The most paid per task, in the token's base units (6 decimals). |
97
+ | `BRAINCHAIN_BUDGET_UNITS` | `10000000` | The most paid in total while the server runs, in the token's base units. |
93
98
  | `BRAINCHAIN_DESK_URL`, `BRAINCHAIN_PAY_TO`, `BRAINCHAIN_PAYMENT_NETWORK`, `BRAINCHAIN_PAYMENT_ASSET`, `BRAINCHAIN_PAYMENT_RPC` | network preset | Override a single setting. A custom desk needs its own `BRAINCHAIN_PAY_TO`. |
94
99
 
95
100
  ## Try it on testnet
96
101
 
97
- Set `BRAINCHAIN_NETWORK=testnet` in the server's environment and for `approve`. Testnet tasks cost 1 test USDG, which has no value, on Robinhood Chain testnet.
102
+ Set `BRAINCHAIN_NETWORK=testnet` in the server's environment. Test tokens have no value.
103
+
104
+ **With USDC on Base Sepolia** (`BRAINCHAIN_PAY_ON=base`), get test USDC from [Circle's faucet](https://faucet.circle.com). That is all a payment needs.
105
+
106
+ **With test USDG on Robinhood Chain testnet:**
98
107
 
99
108
  1. Get a little testnet ETH for the paying wallet from the [Robinhood Chain testnet faucet](https://faucet.testnet.chain.robinhood.com) in a browser.
100
109
  2. Claim 100 test USDG, once a day. With [Foundry](https://getfoundry.sh), which asks for the key instead of taking it on the command line:
@@ -103,7 +112,7 @@ Set `BRAINCHAIN_NETWORK=testnet` in the server's environment and for `approve`.
103
112
  cast send 0x1eC185467cA2D5d1c24f0EdCB91301Bca4d0a787 "faucet()" --rpc-url https://rpc.testnet.chain.robinhood.com --interactive
104
113
  ```
105
114
 
106
- 3. Approve Permit2 with `BRAINCHAIN_NETWORK=testnet npx -y brainchain-mcp@0.1.0 approve`.
115
+ 3. Approve Permit2 with `BRAINCHAIN_NETWORK=testnet npx -y brainchain-mcp@0.2.0 approve`.
107
116
 
108
117
  ## Links
109
118
 
package/dist/config.js CHANGED
@@ -1,27 +1,53 @@
1
- /** Payment and desk settings for each BrainChain network. Mainnet is the default. */
1
+ const MAINNET_DESK = { desk: "https://brain.usebrainchain.com", payTo: "0xafB0C4Ef895D4895040cdC6435B96D3EE8350c6E", finalAfter: "about six hours" };
2
+ const TESTNET_DESK = { desk: "https://brain.testnet.usebrainchain.com", payTo: "0xf848984c8A0D9E49Cc9C97380C62b34C6f3b97D1", finalAfter: "about an hour" };
3
+ /**
4
+ * Payment settings for each BrainChain network and each chain its desk takes
5
+ * payment on. Mainnet on Robinhood Chain is the default. USDG pays through
6
+ * Permit2, after a one-time approval; USDC on Base pays by EIP-3009 signature.
7
+ */
2
8
  const PRESETS = {
3
9
  mainnet: {
4
- desk: "https://brain.usebrainchain.com",
5
- network: "eip155:4663",
6
- asset: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
7
- payTo: "0xafB0C4Ef895D4895040cdC6435B96D3EE8350c6E",
8
- rpc: "https://rpc.mainnet.chain.robinhood.com",
9
- chain: "Robinhood Chain",
10
- token: "USDG",
11
- finalAfter: "about six hours",
10
+ robinhood: {
11
+ ...MAINNET_DESK,
12
+ network: "eip155:4663",
13
+ asset: "0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",
14
+ rpc: "https://rpc.mainnet.chain.robinhood.com",
15
+ chain: "Robinhood Chain",
16
+ token: "USDG",
17
+ permit2: true,
18
+ },
19
+ base: {
20
+ ...MAINNET_DESK,
21
+ network: "eip155:8453",
22
+ asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
23
+ rpc: "https://mainnet.base.org",
24
+ chain: "Base",
25
+ token: "USDC",
26
+ permit2: false,
27
+ },
12
28
  },
13
29
  testnet: {
14
- desk: "https://brain.testnet.usebrainchain.com",
15
- network: "eip155:46630",
16
- asset: "0x1eC185467cA2D5d1c24f0EdCB91301Bca4d0a787",
17
- payTo: "0xf848984c8A0D9E49Cc9C97380C62b34C6f3b97D1",
18
- rpc: "https://rpc.testnet.chain.robinhood.com",
19
- chain: "Robinhood Chain testnet",
20
- token: "test USDG",
21
- finalAfter: "about an hour",
30
+ robinhood: {
31
+ ...TESTNET_DESK,
32
+ network: "eip155:46630",
33
+ asset: "0x1eC185467cA2D5d1c24f0EdCB91301Bca4d0a787",
34
+ rpc: "https://rpc.testnet.chain.robinhood.com",
35
+ chain: "Robinhood Chain testnet",
36
+ token: "test USDG",
37
+ permit2: true,
38
+ },
39
+ base: {
40
+ ...TESTNET_DESK,
41
+ network: "eip155:84532",
42
+ asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
43
+ rpc: "https://sepolia.base.org",
44
+ chain: "Base Sepolia",
45
+ token: "test USDC",
46
+ permit2: false,
47
+ },
22
48
  },
23
49
  };
24
- /** USDG and test USDG both use 6 decimals. */
50
+ /** USDG, USDC and their test versions all use 6 decimals. */
25
51
  export const DECIMALS = 6;
26
52
  /** A payment authorization may stay valid for at most this long. */
27
53
  export const MAX_TIMEOUT_SECONDS = 600;
@@ -48,7 +74,10 @@ export function resolveConfig(env) {
48
74
  const name = (env.BRAINCHAIN_NETWORK ?? "mainnet").toLowerCase();
49
75
  if (name !== "mainnet" && name !== "testnet")
50
76
  throw new Error("BRAINCHAIN_NETWORK must be mainnet or testnet.");
51
- const preset = PRESETS[name];
77
+ const payOn = (env.BRAINCHAIN_PAY_ON ?? "robinhood").toLowerCase();
78
+ if (payOn !== "robinhood" && payOn !== "base")
79
+ throw new Error("BRAINCHAIN_PAY_ON must be robinhood or base.");
80
+ const preset = PRESETS[name][payOn];
52
81
  const network = env.BRAINCHAIN_PAYMENT_NETWORK ?? preset.network;
53
82
  const match = /^eip155:(\d+)$/.exec(network);
54
83
  if (!match)
@@ -59,6 +88,8 @@ export function resolveConfig(env) {
59
88
  throw new Error("BRAINCHAIN_BUDGET_UNITS must be at least BRAINCHAIN_MAX_PRICE_UNITS.");
60
89
  return {
61
90
  name,
91
+ payOn,
92
+ permit2: preset.permit2,
62
93
  desk: (env.BRAINCHAIN_DESK_URL ?? preset.desk).replace(/\/$/, ""),
63
94
  network: network,
64
95
  chainId: Number(match[1]),
package/dist/index.js CHANGED
@@ -24,12 +24,15 @@ Usage:
24
24
  brainchain-mcp Start the server on stdio (what MCP clients run).
25
25
  brainchain-mcp approve [USDG] Let Permit2 spend the paying wallet's USDG, once.
26
26
  Default 100 USDG; pass a number or "max".
27
+ Not needed when paying in USDC on Base.
27
28
 
28
29
  Environment:
29
30
  BRAINCHAIN_PAYER_KEY Private key of the paying wallet (required).
30
31
  BRAINCHAIN_NETWORK mainnet (default) or testnet.
31
- BRAINCHAIN_MAX_PRICE_UNITS Most the server pays per task, in base units (default 1000000 = 1 USDG).
32
- BRAINCHAIN_BUDGET_UNITS Most the server pays in total while it runs (default 10000000 = 10 USDG).
32
+ BRAINCHAIN_PAY_ON robinhood (default) pays in USDG on Robinhood Chain;
33
+ base pays in USDC on Base (Base Sepolia on testnet).
34
+ BRAINCHAIN_MAX_PRICE_UNITS Most the server pays per task, in base units (default 1000000 = 1 USDG or USDC).
35
+ BRAINCHAIN_BUDGET_UNITS Most the server pays in total while it runs (default 10000000 = 10 USDG or USDC).
33
36
  BRAINCHAIN_DESK_URL, BRAINCHAIN_PAY_TO, BRAINCHAIN_PAYMENT_NETWORK, BRAINCHAIN_PAYMENT_ASSET, BRAINCHAIN_PAYMENT_RPC
34
37
  Advanced overrides of the network preset.
35
38
  `;
@@ -66,6 +69,10 @@ catch {
66
69
  fail("BRAINCHAIN_PAYER_KEY is not a valid private key.");
67
70
  }
68
71
  const approveCommand = `${config.name === "testnet" ? "BRAINCHAIN_NETWORK=testnet " : ""}npx -y brainchain-mcp@${version} approve`;
72
+ if (command === "approve" && !config.permit2) {
73
+ console.log(`Paying in ${config.token} on ${config.chain} is a signature each time, so there is nothing to approve.`);
74
+ process.exit(0);
75
+ }
69
76
  const chain = defineChain({
70
77
  id: config.chainId,
71
78
  name: config.chain,
@@ -101,7 +108,7 @@ const desk = createDesk({
101
108
  funds: async () => {
102
109
  const [balance, allowance] = await Promise.all([
103
110
  reader.readContract({ address: config.asset, abi: erc20, functionName: "balanceOf", args: [account.address] }),
104
- reader.readContract({ address: config.asset, abi: erc20, functionName: "allowance", args: [account.address, PERMIT2] }),
111
+ config.permit2 ? reader.readContract({ address: config.asset, abi: erc20, functionName: "allowance", args: [account.address, PERMIT2] }) : undefined,
105
112
  ]);
106
113
  return { balance, allowance };
107
114
  },
package/dist/payments.js CHANGED
@@ -64,10 +64,10 @@ export function createDesk(options) {
64
64
  return `The desk asked for a payment outside this server's limits (${config.token} at ${config.asset}, at most ${formatUnits(config.maxPrice)} per task). Nothing was charged.`;
65
65
  }
66
66
  if (/filtered out by policies/.test(message)) {
67
- return `The desk asked to be paid on terms this server does not accept: the payee must be ${config.payTo} and the authorization may last at most ${MAX_TIMEOUT_SECONDS} seconds. Check BRAINCHAIN_NETWORK, or set BRAINCHAIN_PAY_TO for a custom BRAINCHAIN_DESK_URL. Nothing was charged.`;
67
+ return `The desk asked to be paid on terms this server does not accept: the payee must be ${config.payTo} and the authorization may last at most ${MAX_TIMEOUT_SECONDS} seconds. Check BRAINCHAIN_NETWORK and BRAINCHAIN_PAY_ON, or set BRAINCHAIN_PAY_TO for a custom BRAINCHAIN_DESK_URL. Nothing was charged.`;
68
68
  }
69
69
  if (/No network\/scheme registered/.test(message)) {
70
- return `The desk does not take payment on ${config.chain} (${config.network}). Check BRAINCHAIN_NETWORK. Nothing was charged.`;
70
+ return `The desk does not take payment on ${config.chain} (${config.network}). Check BRAINCHAIN_NETWORK and BRAINCHAIN_PAY_ON. Nothing was charged.`;
71
71
  }
72
72
  if (/Failed to parse payment requirements/.test(message)) {
73
73
  return "The desk's payment request could not be read. Try again in a minute. Nothing was charged.";
@@ -90,7 +90,7 @@ export function createDesk(options) {
90
90
  const needed = (await quotedPrice()) ?? config.maxPrice;
91
91
  if (balance < needed)
92
92
  return `The paying wallet holds ${formatUnits(balance)} ${config.token} on ${config.chain}; a task costs ${formatUnits(needed)}. Nothing was charged.`;
93
- if (allowance < needed) {
93
+ if (config.permit2 && allowance !== undefined && allowance < needed) {
94
94
  return `Permit2 may not spend this wallet's ${config.token} yet. Run \`${approveCommand}\` once with the same BRAINCHAIN_PAYER_KEY; it needs a little ETH on ${config.chain}. Nothing was charged.`;
95
95
  }
96
96
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "brainchain-mcp",
3
- "version": "0.1.0",
4
- "description": "MCP server for BrainChain: hire frontier models through Jev and pay in USDG only for work that passes its grade.",
3
+ "version": "0.2.0",
4
+ "description": "MCP server for BrainChain: hire frontier models through Jev and pay in USDC on Base or USDG on Robinhood Chain, only for work that passes its grade.",
5
5
  "mcpName": "com.usebrainchain/brainchain",
6
6
  "license": "MIT",
7
7
  "author": "BrainChain <hello@usebrainchain.com>",
@@ -12,8 +12,10 @@
12
12
  "mcp-server",
13
13
  "brainchain",
14
14
  "x402",
15
+ "usdc",
15
16
  "usdg",
16
17
  "robinhood-chain",
18
+ "base",
17
19
  "ai-agents"
18
20
  ],
19
21
  "type": "module",