brainchain-mcp 0.7.3 → 0.7.5
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 +12 -12
- package/dist/daily.js +11 -3
- package/dist/premiums.js +13 -6
- package/dist/server.js +1 -1
- package/dist/shipped.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Read the key without echoing it or leaving it in your shell history, then add th
|
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
printf 'Key: ' && read -rs BRAINCHAIN_PAYER_KEY && echo
|
|
19
|
-
claude mcp add brainchain --scope user -e BRAINCHAIN_PAYER_KEY="$BRAINCHAIN_PAYER_KEY" -- npx -y brainchain-mcp@0.7.
|
|
19
|
+
claude mcp add brainchain --scope user -e BRAINCHAIN_PAYER_KEY="$BRAINCHAIN_PAYER_KEY" -- npx -y brainchain-mcp@0.7.5
|
|
20
20
|
unset BRAINCHAIN_PAYER_KEY
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -27,7 +27,7 @@ unset BRAINCHAIN_PAYER_KEY
|
|
|
27
27
|
"mcpServers": {
|
|
28
28
|
"brainchain": {
|
|
29
29
|
"command": "npx",
|
|
30
|
-
"args": ["-y", "brainchain-mcp@0.7.
|
|
30
|
+
"args": ["-y", "brainchain-mcp@0.7.5"],
|
|
31
31
|
"env": { "BRAINCHAIN_PAYER_KEY": "${BRAINCHAIN_PAYER_KEY}" }
|
|
32
32
|
}
|
|
33
33
|
}
|
|
@@ -36,7 +36,7 @@ unset BRAINCHAIN_PAYER_KEY
|
|
|
36
36
|
|
|
37
37
|
### Cursor
|
|
38
38
|
|
|
39
|
-
[](https://cursor.com/en/install-mcp?name=brainchain&config=
|
|
39
|
+
[](https://cursor.com/en/install-mcp?name=brainchain&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsImJyYWluY2hhaW4tbWNwQDAuNy41Il0sImVudiI6eyJCUkFJTkNIQUlOX1BBWUVSX0tFWSI6IiR7ZW52OkJSQUlOQ0hBSU5fUEFZRVJfS0VZfSJ9fQ%3D%3D)
|
|
40
40
|
|
|
41
41
|
Or add the server to a project's `.cursor/mcp.json` (`~/.cursor/mcp.json` for every project):
|
|
42
42
|
|
|
@@ -45,7 +45,7 @@ Or add the server to a project's `.cursor/mcp.json` (`~/.cursor/mcp.json` for ev
|
|
|
45
45
|
"mcpServers": {
|
|
46
46
|
"brainchain": {
|
|
47
47
|
"command": "npx",
|
|
48
|
-
"args": ["-y", "brainchain-mcp@0.7.
|
|
48
|
+
"args": ["-y", "brainchain-mcp@0.7.5"],
|
|
49
49
|
"env": { "BRAINCHAIN_PAYER_KEY": "${env:BRAINCHAIN_PAYER_KEY}" }
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -63,7 +63,7 @@ Add the server to the client's `mcpServers` configuration. For Claude Desktop th
|
|
|
63
63
|
"mcpServers": {
|
|
64
64
|
"brainchain": {
|
|
65
65
|
"command": "npx",
|
|
66
|
-
"args": ["-y", "brainchain-mcp@0.7.
|
|
66
|
+
"args": ["-y", "brainchain-mcp@0.7.5"],
|
|
67
67
|
"env": { "BRAINCHAIN_PAYER_KEY": "0xYOUR_KEY" }
|
|
68
68
|
}
|
|
69
69
|
}
|
|
@@ -82,7 +82,7 @@ These clients keep the key in that file as plain text.
|
|
|
82
82
|
"brainchain": {
|
|
83
83
|
"type": "stdio",
|
|
84
84
|
"command": "npx",
|
|
85
|
-
"args": ["-y", "brainchain-mcp@0.7.
|
|
85
|
+
"args": ["-y", "brainchain-mcp@0.7.5"],
|
|
86
86
|
"env": { "BRAINCHAIN_PAYER_KEY": "${input:brainchain-key}" }
|
|
87
87
|
}
|
|
88
88
|
},
|
|
@@ -100,10 +100,10 @@ Save the key in a file only your account can read, then point the server at it:
|
|
|
100
100
|
mkdir -p ~/.brainchain
|
|
101
101
|
(umask 077; printf 'Key: ' && read -rs key && echo && printf '%s\n' "$key" > ~/.brainchain/payer.key)
|
|
102
102
|
chmod 600 ~/.brainchain/payer.key
|
|
103
|
-
openclaw mcp set brainchain '{"command":"npx","args":["-y","brainchain-mcp@0.7.
|
|
103
|
+
openclaw mcp set brainchain '{"command":"npx","args":["-y","brainchain-mcp@0.7.5"],"env":{"BRAINCHAIN_PAYER_KEY_FILE":"~/.brainchain/payer.key"}}'
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
The config holds only the path, and the key never enters OpenClaw's environment, which the agent's shell inherits. A key saved in `skills.entries.brainchain.apiKey` does not reach the server. `BRAINCHAIN_PAYER_KEY_FILE=~/.brainchain/payer.key npx -y brainchain-mcp@0.7.
|
|
106
|
+
The config holds only the path, and the key never enters OpenClaw's environment, which the agent's shell inherits. A key saved in `skills.entries.brainchain.apiKey` does not reach the server. `BRAINCHAIN_PAYER_KEY_FILE=~/.brainchain/payer.key npx -y brainchain-mcp@0.7.5 wallet` checks the file and prints the wallet it holds and its balance. [`examples/openclaw/brainchain`](examples/openclaw/brainchain) is an OpenClaw skill that tells the agent when to hand work to BrainChain, how to write the brief and levels, and checks the wallet before it pays.
|
|
107
107
|
|
|
108
108
|
Each setup above pays 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).
|
|
109
109
|
|
|
@@ -117,7 +117,7 @@ Each brief is posted on BrainChain and each result is served at a public link. K
|
|
|
117
117
|
|
|
118
118
|
```bash
|
|
119
119
|
printf 'Key: ' && read -rs BRAINCHAIN_PAYER_KEY && echo && export BRAINCHAIN_PAYER_KEY
|
|
120
|
-
npx -y brainchain-mcp@0.7.
|
|
120
|
+
npx -y brainchain-mcp@0.7.5 approve
|
|
121
121
|
unset BRAINCHAIN_PAYER_KEY
|
|
122
122
|
```
|
|
123
123
|
|
|
@@ -166,7 +166,7 @@ Every hire and grade is recorded on BrainChain and listed at [usebrainchain.com/
|
|
|
166
166
|
| `BRAINCHAIN_STATE_DIR` | `~/.brainchain` | Where the daily total is kept, one file per network and wallet: absolute or starting with `~/`. |
|
|
167
167
|
| `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`, and an https URL unless it is on localhost or 127.0.0.1. |
|
|
168
168
|
|
|
169
|
-
If a setting is invalid, the server says so once on stderr when it starts, and
|
|
169
|
+
If a setting is invalid, the server says so once on stderr when it starts, and the task and bond tools return the error; `brainchain_stock_premiums` keeps working. A key it cannot use is reported the same way, except that `brainchain_get_task` and `brainchain_stock_premiums` need no key and keep working, and so is a `BRAINCHAIN_STATE_DIR` that cannot hold the daily limit's record when `BRAINCHAIN_DAILY_UNITS` is set. `npx -y brainchain-mcp@0.7.5 wallet` checks the settings and the key, and prints the wallet that pays, what it holds and, for USDG, what Permit2 may spend. `--help` lists the commands and variables, and `--version` prints the version.
|
|
170
170
|
|
|
171
171
|
## Try it on testnet
|
|
172
172
|
|
|
@@ -174,7 +174,7 @@ Set `BRAINCHAIN_NETWORK=testnet` in the server's environment. Test tokens have n
|
|
|
174
174
|
|
|
175
175
|
```bash
|
|
176
176
|
printf 'Key: ' && read -rs BRAINCHAIN_PAYER_KEY && echo
|
|
177
|
-
claude mcp add brainchain --scope user -e BRAINCHAIN_NETWORK=testnet -e BRAINCHAIN_PAYER_KEY="$BRAINCHAIN_PAYER_KEY" -- npx -y brainchain-mcp@0.7.
|
|
177
|
+
claude mcp add brainchain --scope user -e BRAINCHAIN_NETWORK=testnet -e BRAINCHAIN_PAYER_KEY="$BRAINCHAIN_PAYER_KEY" -- npx -y brainchain-mcp@0.7.5
|
|
178
178
|
unset BRAINCHAIN_PAYER_KEY
|
|
179
179
|
```
|
|
180
180
|
|
|
@@ -193,7 +193,7 @@ unset BRAINCHAIN_PAYER_KEY
|
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
195
|
printf 'Key: ' && read -rs BRAINCHAIN_PAYER_KEY && echo && export BRAINCHAIN_PAYER_KEY
|
|
196
|
-
BRAINCHAIN_NETWORK=testnet npx -y brainchain-mcp@0.7.
|
|
196
|
+
BRAINCHAIN_NETWORK=testnet npx -y brainchain-mcp@0.7.5 approve
|
|
197
197
|
unset BRAINCHAIN_PAYER_KEY
|
|
198
198
|
```
|
|
199
199
|
|
package/dist/daily.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// The daily limit is kept on disk, so restarting the server, or a second server
|
|
2
2
|
// paying from the same wallet, does not reset what the wallet may spend today.
|
|
3
|
-
import { accessSync, constants, mkdirSync } from "node:fs";
|
|
3
|
+
import { accessSync, constants, existsSync, mkdirSync } from "node:fs";
|
|
4
4
|
import { mkdir, open, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
5
|
-
import { dirname } from "node:path";
|
|
5
|
+
import { dirname, resolve } from "node:path";
|
|
6
6
|
const LOCK_STALE_MS = 10_000;
|
|
7
7
|
const LOCK_WAIT_MS = 5_000;
|
|
8
8
|
/** Clearing a lock takes a few system calls, so a marker older than this was left by a crash. */
|
|
@@ -24,8 +24,16 @@ function stateDirMessage(dir, error) {
|
|
|
24
24
|
}
|
|
25
25
|
/** Why the daily limit's record cannot be kept in `dir`, creating the folder if it is missing; undefined when it can. */
|
|
26
26
|
export function stateDirProblem(dir) {
|
|
27
|
+
const full = resolve(dir);
|
|
28
|
+
// kernel folders accept odd writes or block on them; no record belongs there
|
|
29
|
+
if (/^\/(proc|sys|dev)(\/|$)/.test(full))
|
|
30
|
+
return `BRAINCHAIN_STATE_DIR is ${dir}, which is a system folder, so the daily limit's record cannot be kept there. Set it to a folder this account can write, then restart the server.`;
|
|
31
|
+
let existing = full;
|
|
32
|
+
while (!existsSync(existing) && dirname(existing) !== existing)
|
|
33
|
+
existing = dirname(existing);
|
|
27
34
|
try {
|
|
28
|
-
|
|
35
|
+
accessSync(existing, constants.W_OK);
|
|
36
|
+
mkdirSync(full, { recursive: true });
|
|
29
37
|
accessSync(dir, constants.W_OK);
|
|
30
38
|
return undefined;
|
|
31
39
|
}
|
package/dist/premiums.js
CHANGED
|
@@ -22,6 +22,7 @@ export const PREMIUMS_TOOL = {
|
|
|
22
22
|
description: "What tokenized US stocks cost on Robinhood Chain against their Chainlink price right now: pool price, Chainlink price, " +
|
|
23
23
|
"the premium in percent and the feed's age, for NVDA, SPY, AAPL, TSLA, GOOGL, META and MSFT. Read from the chain, free, no key " +
|
|
24
24
|
"and no payment. Outside US market hours no new tokens are minted, so the premium shows where the market clears on its own. " +
|
|
25
|
+
"usMarketOpen is true during the regular session, 09:30 to 16:00 New York time, Monday to Friday; it does not know exchange holidays or early closes. " +
|
|
25
26
|
"Prices are in USDG per token with each token's split multiplier applied. Not advice; stock tokens on Robinhood Chain are not " +
|
|
26
27
|
"available to US persons.",
|
|
27
28
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
@@ -29,15 +30,21 @@ export const PREMIUMS_TOOL = {
|
|
|
29
30
|
export function chainReader(rpc = ROBINHOOD_RPC) {
|
|
30
31
|
return createPublicClient({ transport: http(rpc) });
|
|
31
32
|
}
|
|
32
|
-
/**
|
|
33
|
+
/** The regular NYSE session, 09:30 to 16:00 New York time, Monday to Friday; exchange holidays are not known here. */
|
|
33
34
|
export function usMarketOpen(now) {
|
|
34
|
-
const
|
|
35
|
-
|
|
35
|
+
const parts = new Intl.DateTimeFormat("en-US", { timeZone: "America/New_York", weekday: "short", hour: "2-digit", minute: "2-digit", hour12: false }).formatToParts(now);
|
|
36
|
+
const part = (type) => parts.find((p) => p.type === type)?.value ?? "";
|
|
37
|
+
const weekday = part("weekday");
|
|
38
|
+
if (weekday === "Sat" || weekday === "Sun")
|
|
36
39
|
return false;
|
|
37
|
-
const minutes =
|
|
38
|
-
return minutes >=
|
|
40
|
+
const minutes = (Number(part("hour")) % 24) * 60 + Number(part("minute"));
|
|
41
|
+
return minutes >= 9 * 60 + 30 && minutes < 16 * 60;
|
|
39
42
|
}
|
|
40
|
-
|
|
43
|
+
/** USDG units (6 decimals) as dollars and cents, rounded half up. */
|
|
44
|
+
const usd = (units) => {
|
|
45
|
+
const cents = (units + 5000n) / 10000n;
|
|
46
|
+
return `${cents / 100n}.${(cents % 100n).toString().padStart(2, "0")}`;
|
|
47
|
+
};
|
|
41
48
|
/** USDG (6 decimals) for one whole stock token at the pool's current price. */
|
|
42
49
|
function spotFromSlot0(sqrtPriceX96, token0) {
|
|
43
50
|
const squared = sqrtPriceX96 * sqrtPriceX96;
|
package/dist/server.js
CHANGED
|
@@ -24,7 +24,7 @@ export const INSTRUCTIONS = `Post a task with ${POST_TASK_NAME}, then read it wi
|
|
|
24
24
|
`${BOND_TASK_NAME} locks USDG behind a BrainChain task this wallet will deliver as a worker, and ${BOND_STATUS_NAME} follows it; neither posts a task. ` +
|
|
25
25
|
`The paying wallet's key is for this server alone. Never read it, print it, write it down or pass it to a command. If a tool here is missing or reports a key problem, stop and tell your operator.`;
|
|
26
26
|
const KEY_HELP = `Add BRAINCHAIN_PAYER_KEY to this server's env in your MCP client config (in Claude Code, \`claude mcp add … -e BRAINCHAIN_PAYER_KEY=…\`), or BRAINCHAIN_PAYER_KEY_FILE with the path of a file holding it, then restart the server. ` +
|
|
27
|
-
`${GET_TASK_NAME}
|
|
27
|
+
`${GET_TASK_NAME} and ${PREMIUMS_NAME} work without a key; ${BOND_STATUS_NAME} reads this wallet's bonds, so it needs the key too. An agent reading this: stop and tell your operator. Do not look for the key.`;
|
|
28
28
|
const messageOf = (error) => (error instanceof Error ? error.message : String(error));
|
|
29
29
|
/** Read here and never echoed. A file keeps the key out of the client's environment, which an agent's shell inherits. */
|
|
30
30
|
function readKeyFile(given) {
|
package/dist/shipped.js
CHANGED
|
@@ -15,7 +15,8 @@ export const shippedAbi = parseAbi([
|
|
|
15
15
|
`event DeedCreated(uint256 indexed deedId, address indexed creator, address indexed project, ${TERMS} terms, uint256 deposit, uint16 feeBps)`,
|
|
16
16
|
]);
|
|
17
17
|
export const taskBoardAbi = parseAbi([
|
|
18
|
-
|
|
18
|
+
// TaskBoard.get as deployed in sets 3.4.0 and 3.5.0; the brief and result live off chain behind their hashes.
|
|
19
|
+
"function get(uint256 id) view returns ((address poster, uint128 bounty, uint64 deadline, uint8 status, bool accepted, bool disputed, bool disputedByModel, bytes32 model, bytes32 briefHash, bytes32 resultHash, uint64 submittedAt, uint64 gradedAt, uint64 disputedAt, uint64 postedAt, address payee, address feeRecipient, uint16 feeBps, uint16 hireThresholdBps, uint16 gradeThresholdBps, uint16 ruleThresholdBps, uint64 gradeWindow, uint64 disputeWindow, uint64 ruleWindow))",
|
|
19
20
|
]);
|
|
20
21
|
/** ShippedDeeds.Status and Ruling, as the contract declares them. */
|
|
21
22
|
export const DeedStatus = { None: 0, Open: 1, Ruled: 2, Appealed: 3, Settled: 4 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brainchain-mcp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "MCP server for BrainChain: let your agent hire a frontier model for a task and pay in USDG on Robinhood Chain or USDC on Base, only for work that meets the quality bar you set.",
|
|
5
5
|
"mcpName": "com.usebrainchain/brainchain",
|
|
6
6
|
"license": "MIT",
|