@blockrun/mcp 0.21.5 → 0.22.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 +56 -4
- package/dist/index.js +130 -51
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -14,6 +14,15 @@ Wallet auto-created. Fund with $5 USDC. Ask Claude anything.
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
+
## Documentation
|
|
18
|
+
|
|
19
|
+
Full docs: **https://blockrun.ai/docs**
|
|
20
|
+
|
|
21
|
+
- MCP tools & setup: https://blockrun.ai/docs/mcp/blockrun-mcp
|
|
22
|
+
- All BlockRun SDKs & APIs: https://blockrun.ai/docs
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
17
26
|
## What changes
|
|
18
27
|
|
|
19
28
|
Before BlockRun, Claude can't answer:
|
|
@@ -84,6 +93,25 @@ claude mcp add blockrun -s user -- npx -y @blockrun/mcp@latest
|
|
|
84
93
|
The `-s user` flag installs globally (available in every project). The `--` separator
|
|
85
94
|
ensures `-y` is passed to `npx`, not parsed by `claude mcp add`.
|
|
86
95
|
|
|
96
|
+
**Tool profiles** — expose a trimmed tool set so the client loads fewer schemas into
|
|
97
|
+
context. Pass `--profile <name>` (or set `BLOCKRUN_MCP_PROFILE`); omit it for the full set.
|
|
98
|
+
|
|
99
|
+
| Profile | Tools |
|
|
100
|
+
|---------|-------|
|
|
101
|
+
| `full` *(default)* | everything |
|
|
102
|
+
| `media` | `wallet` `models` `image` `video` `realface` `music` `speech` |
|
|
103
|
+
| `trading` | `wallet` `price` `dex` `markets` `surf` `defi` `rpc` |
|
|
104
|
+
| `research` | `wallet` `models` `chat` `search` `exa` `surf` |
|
|
105
|
+
| `chat` | `wallet` `models` `chat` |
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# e.g. a media-only install
|
|
109
|
+
claude mcp add blockrun-media -s user -- npx -y @blockrun/mcp@latest --profile media
|
|
110
|
+
# or a trading-only install
|
|
111
|
+
claude mcp add blockrun-trading -s user -- npx -y @blockrun/mcp@latest --profile trading
|
|
112
|
+
```
|
|
113
|
+
Equivalent via env: `BLOCKRUN_MCP_PROFILE=trading`. An unknown profile name falls back to `full`. `modal` and `phone` are available in the `full` profile only.
|
|
114
|
+
|
|
87
115
|
**Claude Desktop** — add to `claude_desktop_config.json`:
|
|
88
116
|
```json
|
|
89
117
|
{
|
|
@@ -117,7 +145,7 @@ ensures `-y` is passed to `npx`, not parsed by `claude mcp add`.
|
|
|
117
145
|
|
|
118
146
|
## Fund your wallet
|
|
119
147
|
|
|
120
|
-
Run `blockrun_wallet` to see your address. Send USDC on Base
|
|
148
|
+
Run `blockrun_wallet` to see your address. The server pays on **Base** by default. Send USDC on Base:
|
|
121
149
|
|
|
122
150
|
| Method | Steps |
|
|
123
151
|
|--------|-------|
|
|
@@ -126,6 +154,24 @@ Run `blockrun_wallet` to see your address. Send USDC on Base.
|
|
|
126
154
|
|
|
127
155
|
$5 covers ~5,000 market queries, ~500 Exa searches, ~250 image generations, or ~10 Seedance 1.5-pro clips (5s @ 720p+audio, ~$0.46 each).
|
|
128
156
|
|
|
157
|
+
### Pay on Solana
|
|
158
|
+
|
|
159
|
+
Prefer to pay in USDC on Solana? It's two tool calls — no env vars, no file editing, no restart:
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
blockrun_wallet action:"chain" chain:"solana" # provisions + activates the Solana wallet
|
|
163
|
+
blockrun_wallet action:"setup" # shows the Solana address + funding QR
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Then send USDC (SPL) on the **Solana** network — from Coinbase (pick "Solana"), Phantom, Solflare, or Backpack. Switch back anytime with `blockrun_wallet action:"chain" chain:"base"`. The server keeps both wallets; switching just changes which one pays.
|
|
167
|
+
|
|
168
|
+
**Base-only — these fall back to Base regardless of active chain:**
|
|
169
|
+
|
|
170
|
+
- Tools: `blockrun_image`, `blockrun_music`, `blockrun_speech`, `blockrun_video`, paid stock `blockrun_price`. In Solana mode they return a "switch to Base" message instead of charging.
|
|
171
|
+
- `blockrun_chat routing:"smart"` (ClawRouter) and native Anthropic (`claude-*`) passthrough — on Solana, pass `model:` or `mode:` explicitly.
|
|
172
|
+
|
|
173
|
+
> Advanced: chain selection can also be forced before startup via files/env (`~/.blockrun/.chain`, `SOLANA_WALLET_KEY`) — see [Environment Variables](#environment-variables). The `action:"chain"` command above is the recommended path.
|
|
174
|
+
|
|
129
175
|
---
|
|
130
176
|
|
|
131
177
|
## Tools
|
|
@@ -261,10 +307,16 @@ Chain selection priority (see `src/utils/wallet.ts`):
|
|
|
261
307
|
|
|
262
308
|
**Switching chains:**
|
|
263
309
|
|
|
264
|
-
|
|
265
|
-
|
|
310
|
+
The recommended way is the tool itself — it provisions both wallets, applies instantly (no restart), and shows the funding QR:
|
|
311
|
+
|
|
312
|
+
```
|
|
313
|
+
blockrun_wallet action:"chain" chain:"solana" # or chain:"base"
|
|
314
|
+
blockrun_wallet action:"setup" # funding instructions for the active chain
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
*Advanced (force a chain before startup, e.g. in CI):* `echo solana > ~/.blockrun/.chain` then set `SOLANA_WALLET_KEY` or create `~/.blockrun/.solana-session`; `echo base > ~/.blockrun/.chain` reuses the existing `.session` (same Base wallet). These edit the same preference file that `action:"chain"` writes — prefer the tool unless you need pre-startup control.
|
|
266
318
|
|
|
267
|
-
Some media and paid market-data tools still settle on Base only: `blockrun_image`, `blockrun_music`, `blockrun_speech`, `blockrun_video`, and paid stock `blockrun_price` calls. In Solana mode
|
|
319
|
+
Some media and paid market-data tools still settle on Base only: `blockrun_image`, `blockrun_music`, `blockrun_speech`, `blockrun_video`, and paid stock `blockrun_price` calls — plus `blockrun_chat routing:"smart"` and native Anthropic (`claude-*`) passthrough. In Solana mode these return a "switch to Base" message instead of charging.
|
|
268
320
|
|
|
269
321
|
The server also runs a non-blocking npm registry check at startup and prints an `Update available` notice to stderr when a newer `@blockrun/mcp` version exists. Upgrade by re-running the install command — no manual `npm update` needed.
|
|
270
322
|
|
package/dist/index.js
CHANGED
|
@@ -388,6 +388,14 @@ Call this to set spending limits before spawning child agents.
|
|
|
388
388
|
|
|
389
389
|
The server holds TWO wallets \u2014 one on Base, one on Solana \u2014 but pays on ONE
|
|
390
390
|
active chain at a time. status shows both addresses/balances and which is active.
|
|
391
|
+
Default chain is Base.
|
|
392
|
+
|
|
393
|
+
To pay on Solana (no env vars, no file editing, no restart):
|
|
394
|
+
1. action:"chain" chain:"solana" \u2192 provisions + activates the Solana wallet
|
|
395
|
+
2. action:"setup" \u2192 Solana address + funding QR (send USDC SPL on Solana)
|
|
396
|
+
Switch back with action:"chain" chain:"base". Base-only \u2014 these ignore Solana and
|
|
397
|
+
need Base: blockrun_image, blockrun_music, blockrun_speech, blockrun_video, paid
|
|
398
|
+
blockrun_price, blockrun_chat routing:"smart", and native Anthropic (claude-*).
|
|
391
399
|
|
|
392
400
|
Actions:
|
|
393
401
|
- status (default): Both wallet addresses + USDC balances, active chain, session spending
|
|
@@ -3022,58 +3030,127 @@ Use blockrun_price (free) for plain spot quotes, blockrun_dex (free) for DEX pai
|
|
|
3022
3030
|
);
|
|
3023
3031
|
}
|
|
3024
3032
|
|
|
3033
|
+
// src/profiles.ts
|
|
3034
|
+
var ALL_TOOLS = [
|
|
3035
|
+
"wallet",
|
|
3036
|
+
"chat",
|
|
3037
|
+
"models",
|
|
3038
|
+
"image",
|
|
3039
|
+
"music",
|
|
3040
|
+
"speech",
|
|
3041
|
+
"video",
|
|
3042
|
+
"realface",
|
|
3043
|
+
"search",
|
|
3044
|
+
"exa",
|
|
3045
|
+
"markets",
|
|
3046
|
+
"price",
|
|
3047
|
+
"dex",
|
|
3048
|
+
"modal",
|
|
3049
|
+
"phone",
|
|
3050
|
+
"surf",
|
|
3051
|
+
"rpc",
|
|
3052
|
+
"defi"
|
|
3053
|
+
];
|
|
3054
|
+
var PROFILES = {
|
|
3055
|
+
full: "all",
|
|
3056
|
+
// Generative media: image/video/realface plus the other media-generation
|
|
3057
|
+
// tools (music, speech), with wallet (funding/balance — media calls cost
|
|
3058
|
+
// USDC) and models (discover what's available).
|
|
3059
|
+
media: ["wallet", "models", "image", "video", "realface", "music", "speech"],
|
|
3060
|
+
// Markets & on-chain data: prediction markets, realtime prices, DEX/CEX
|
|
3061
|
+
// data, DeFi metrics, and raw RPC, plus the wallet for balance/funding.
|
|
3062
|
+
trading: ["wallet", "price", "dex", "markets", "surf", "defi", "rpc"],
|
|
3063
|
+
// Web research & analysis: live search, neural search, Surf's news/SQL,
|
|
3064
|
+
// and chat for synthesis, plus wallet and the model catalogue.
|
|
3065
|
+
research: ["wallet", "models", "chat", "search", "exa", "surf"],
|
|
3066
|
+
// Minimal LLM gateway: just chat + model discovery + wallet.
|
|
3067
|
+
chat: ["wallet", "models", "chat"]
|
|
3068
|
+
};
|
|
3069
|
+
var DEFAULT_PROFILE = "full";
|
|
3070
|
+
function resolveProfileName(argv = process.argv.slice(2), env = process.env) {
|
|
3071
|
+
for (let i = 0; i < argv.length; i++) {
|
|
3072
|
+
const arg = argv[i];
|
|
3073
|
+
if (arg === "--profile") return (argv[i + 1] ?? DEFAULT_PROFILE).toLowerCase();
|
|
3074
|
+
if (arg.startsWith("--profile=")) return arg.slice("--profile=".length).toLowerCase();
|
|
3075
|
+
}
|
|
3076
|
+
if (env.BLOCKRUN_MCP_PROFILE) return env.BLOCKRUN_MCP_PROFILE.toLowerCase();
|
|
3077
|
+
return DEFAULT_PROFILE;
|
|
3078
|
+
}
|
|
3079
|
+
function resolveTools(argv, env) {
|
|
3080
|
+
const requested = resolveProfileName(argv, env);
|
|
3081
|
+
const spec = PROFILES[requested];
|
|
3082
|
+
if (!spec) {
|
|
3083
|
+
return { profile: DEFAULT_PROFILE, tools: new Set(ALL_TOOLS) };
|
|
3084
|
+
}
|
|
3085
|
+
return {
|
|
3086
|
+
profile: requested,
|
|
3087
|
+
tools: new Set(spec === "all" ? ALL_TOOLS : spec)
|
|
3088
|
+
};
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3025
3091
|
// src/mcp-handler.ts
|
|
3026
|
-
function initializeMcpServer(server) {
|
|
3092
|
+
function initializeMcpServer(server, profileArgs) {
|
|
3027
3093
|
const budget = { limit: null, spent: 0, calls: 0, agents: /* @__PURE__ */ new Map() };
|
|
3028
3094
|
const modelCache = { models: null };
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
}
|
|
3075
|
-
|
|
3076
|
-
|
|
3095
|
+
const { profile, tools } = resolveTools(profileArgs?.argv, profileArgs?.env);
|
|
3096
|
+
const registrars = {
|
|
3097
|
+
wallet: () => registerWalletTool(server, budget),
|
|
3098
|
+
chat: () => registerChatTool(server, budget),
|
|
3099
|
+
models: () => registerModelsTool(server, modelCache),
|
|
3100
|
+
image: () => registerImageTool(server, budget),
|
|
3101
|
+
music: () => registerMusicTool(server, budget),
|
|
3102
|
+
speech: () => registerSpeechTool(server, budget),
|
|
3103
|
+
video: () => registerVideoTool(server, budget),
|
|
3104
|
+
realface: () => registerRealfaceTool(server, budget),
|
|
3105
|
+
search: () => registerSearchTool(server, budget),
|
|
3106
|
+
exa: () => registerExaTool(server, budget),
|
|
3107
|
+
markets: () => registerMarketsTool(server, budget),
|
|
3108
|
+
price: () => registerPriceTool(server, budget),
|
|
3109
|
+
dex: () => registerDexTool(server),
|
|
3110
|
+
modal: () => registerModalTool(server, budget),
|
|
3111
|
+
phone: () => registerPhoneTool(server, budget),
|
|
3112
|
+
surf: () => registerSurfTool(server, budget),
|
|
3113
|
+
rpc: () => registerRpcTool(server, budget),
|
|
3114
|
+
defi: () => registerDefiTool(server, budget)
|
|
3115
|
+
};
|
|
3116
|
+
for (const [name, register] of Object.entries(registrars)) {
|
|
3117
|
+
if (tools.has(name)) register();
|
|
3118
|
+
}
|
|
3119
|
+
if (tools.has("wallet")) {
|
|
3120
|
+
server.registerResource(
|
|
3121
|
+
"wallet",
|
|
3122
|
+
"blockrun://wallet",
|
|
3123
|
+
{ description: "Wallet address and status", mimeType: "application/json" },
|
|
3124
|
+
async () => {
|
|
3125
|
+
const info = await getWalletInfo();
|
|
3126
|
+
return {
|
|
3127
|
+
contents: [{
|
|
3128
|
+
uri: "blockrun://wallet",
|
|
3129
|
+
mimeType: "application/json",
|
|
3130
|
+
text: JSON.stringify(info, null, 2)
|
|
3131
|
+
}]
|
|
3132
|
+
};
|
|
3133
|
+
}
|
|
3134
|
+
);
|
|
3135
|
+
}
|
|
3136
|
+
if (tools.has("models")) {
|
|
3137
|
+
server.registerResource(
|
|
3138
|
+
"models",
|
|
3139
|
+
"blockrun://models",
|
|
3140
|
+
{ description: "Available AI models with pricing", mimeType: "application/json" },
|
|
3141
|
+
async () => {
|
|
3142
|
+
const models = await loadModels(getClient(), modelCache);
|
|
3143
|
+
return {
|
|
3144
|
+
contents: [{
|
|
3145
|
+
uri: "blockrun://models",
|
|
3146
|
+
mimeType: "application/json",
|
|
3147
|
+
text: JSON.stringify(models, null, 2)
|
|
3148
|
+
}]
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
);
|
|
3152
|
+
}
|
|
3153
|
+
return { profile, tools: [...tools] };
|
|
3077
3154
|
}
|
|
3078
3155
|
|
|
3079
3156
|
// src/utils/key-leak-scanner.ts
|
|
@@ -3173,6 +3250,7 @@ function printHelp() {
|
|
|
3173
3250
|
"Options:",
|
|
3174
3251
|
" -h, --help Show this help message",
|
|
3175
3252
|
" -v, --version Print the package version",
|
|
3253
|
+
` --profile <name> Tool profile to expose: ${Object.keys(PROFILES).join(" | ")} (default: full)`,
|
|
3176
3254
|
"",
|
|
3177
3255
|
"When no metadata flag is provided, the server starts on stdio for MCP clients.",
|
|
3178
3256
|
""
|
|
@@ -3211,10 +3289,11 @@ async function main() {
|
|
|
3211
3289
|
name: "blockrun-mcp",
|
|
3212
3290
|
version: VERSION
|
|
3213
3291
|
});
|
|
3214
|
-
initializeMcpServer(server);
|
|
3292
|
+
const { profile, tools } = initializeMcpServer(server);
|
|
3215
3293
|
const transport = new StdioServerTransport();
|
|
3216
3294
|
await server.connect(transport);
|
|
3217
|
-
|
|
3295
|
+
const profileNote = profile === "full" ? `${tools.length} tools` : `profile "${profile}" \u2014 ${tools.length} tools: ${tools.join(", ")}`;
|
|
3296
|
+
console.error(`BlockRun MCP Server started (v${VERSION}) \u2014 stdio transport \u2014 ${profileNote}`);
|
|
3218
3297
|
checkForUpdate();
|
|
3219
3298
|
}
|
|
3220
3299
|
main().catch((error) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blockrun/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"mcpName": "io.github.BlockRunAI/blockrun-mcp",
|
|
5
5
|
"description": "BlockRun MCP Server - Give your AI agent web search, deep research, prediction markets, crypto data, X/Twitter intelligence. Paid via x402 micropayments.",
|
|
6
6
|
"type": "module",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"dev": "tsx watch src/index.ts",
|
|
19
19
|
"start": "node dist/index.js",
|
|
20
20
|
"typecheck": "tsc --noEmit",
|
|
21
|
+
"test": "tsx --test test/*.test.ts",
|
|
21
22
|
"prepublishOnly": "npm run build"
|
|
22
23
|
},
|
|
23
24
|
"keywords": [
|