@blockrun/mcp 0.19.1 → 0.20.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.
Files changed (3) hide show
  1. package/README.md +6 -8
  2. package/dist/index.js +117 -22
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -96,11 +96,6 @@ ensures `-y` is passed to `npx`, not parsed by `claude mcp add`.
96
96
  }
97
97
  ```
98
98
 
99
- **Hosted (no install, always latest)**
100
- ```bash
101
- claude mcp add blockrun -s user --transport http https://mcp.blockrun.ai/mcp
102
- ```
103
-
104
99
  **Cursor** — add to `~/.cursor/mcp.json` (macOS / Linux) or `%APPDATA%\Cursor\mcp.json` (Windows):
105
100
  ```json
106
101
  {
@@ -137,9 +132,9 @@ $5 covers ~5,000 market queries, ~500 Exa searches, ~250 image generations, or ~
137
132
 
138
133
  | Tool | Data source | Cost |
139
134
  |------|-------------|------|
140
- | `blockrun_chat` | 55+ LLMs (GPT, Claude, Gemini, DeepSeek, Kimi K2.6, GLM, NVIDIA free tier, ...) with `mode` tier routing | per token |
141
- | `blockrun_image` | DALL-E 3, GPT Image 1/2, Grok Imagine, Flux, CogView-4, Nano Banana — generation + editing | $0.015–0.12 |
142
- | `blockrun_video` | xAI Grok Imagine Video + ByteDance Seedance 1.5/2.0/2.0-fast (720p + audio defaults); RealFace asset → real-person video | $0.05–0.298/sec |
135
+ | `blockrun_chat` | 66+ LLMs (GPT, Claude, Gemini, DeepSeek, Kimi K2.6, GLM, NVIDIA free tier, ...) with `mode` tier routing | per token |
136
+ | `blockrun_image` | GPT Image 1/2, Nano Banana / Pro (up to 4K), Grok Imagine, CogView-4 — generation + img2img editing | $0.015–0.15 |
137
+ | `blockrun_video` | Sora 2 + xAI Grok Imagine Video + ByteDance Seedance 1.5/2.0/2.0-fast (720p + audio defaults); RealFace asset → real-person video | $0.05–0.30/sec |
143
138
  | `blockrun_realface` | Enroll a real person (phone liveness → `ta_xxxx` asset) for Seedance 2.0 real-person video | free; $0.01 to enroll |
144
139
  | `blockrun_music` | MiniMax music generation | per track |
145
140
  | `blockrun_speech` | ElevenLabs text-to-speech (Flash/Turbo/Multilingual/v3, 8 voice aliases) + cinematic sound effects; free voice listing | $0.05–0.10/1k chars; $0.0525/effect |
@@ -149,6 +144,9 @@ $5 covers ~5,000 market queries, ~500 Exa searches, ~250 image generations, or ~
149
144
  | `blockrun_exa` | Neural web search (Exa) — research, competitors, papers, URL content | $0.01/query |
150
145
  | `blockrun_search` | Grok Live Search — web + news with citations | $0.025 × max_results (default 10) |
151
146
  | `blockrun_dex` | Live DEX prices via DexScreener | free |
147
+ | `blockrun_rpc` | Raw JSON-RPC on 40+ chains (Ethereum, Base, Solana, Bitcoin, Sui, NEAR, ...) via Tatum gateway — eth_call, balances, blocks, logs | $0.002/call |
148
+ | `blockrun_modal` | Isolated code execution in a BlockRun-hosted Modal sandbox — disposable container, optional GPU (T4 → H100) | $0.01 create; $0.001/op |
149
+ | `blockrun_phone` | Outbound AI voice calls (Bland) + wallet-owned US/CA numbers (Twilio), carrier + fraud lookups | $0.54/call; $5/number |
152
150
  | `blockrun_models` | Live catalogue of every LLM/image/video/music model + pricing | free |
153
151
  | `blockrun_wallet` | Balance, spending, agent budgets, setup QR | free |
154
152
 
package/dist/index.js CHANGED
@@ -1092,13 +1092,39 @@ var GENERATE_MODEL_COST = {
1092
1092
  "zai/cogview-4": 0.015,
1093
1093
  "xai/grok-imagine-image": 0.02,
1094
1094
  "xai/grok-imagine-image-pro": 0.07,
1095
+ "openai/gpt-image-1": 0.02,
1096
+ "openai/gpt-image-2": 0.06,
1097
+ "google/nano-banana": 0.05,
1098
+ "google/nano-banana-pro": 0.1
1099
+ };
1100
+ var LARGE_SIZE_COST = {
1095
1101
  "openai/gpt-image-1": 0.04,
1096
1102
  "openai/gpt-image-2": 0.12,
1097
- "openai/dall-e-3": 0.08,
1098
- "google/nano-banana": 0.05,
1099
- "together/flux-schnell": 3e-3
1103
+ "google/nano-banana-pro": 0.15
1104
+ // 4096x4096 tier
1100
1105
  };
1101
- var EDIT_MODELS = /* @__PURE__ */ new Set(["openai/gpt-image-1", "openai/gpt-image-2"]);
1106
+ var EDIT_MODELS = /* @__PURE__ */ new Set([
1107
+ "openai/gpt-image-1",
1108
+ "openai/gpt-image-2",
1109
+ "google/nano-banana",
1110
+ "google/nano-banana-pro"
1111
+ ]);
1112
+ var IMAGE_MODELS = [
1113
+ "zai/cogview-4",
1114
+ "google/nano-banana",
1115
+ "google/nano-banana-pro",
1116
+ "openai/gpt-image-1",
1117
+ "openai/gpt-image-2",
1118
+ "xai/grok-imagine-image",
1119
+ "xai/grok-imagine-image-pro"
1120
+ ];
1121
+ function estimateCost(model, size) {
1122
+ const base = GENERATE_MODEL_COST[model] ?? 0.06;
1123
+ if (size !== "1024x1024" && LARGE_SIZE_COST[model]) {
1124
+ return LARGE_SIZE_COST[model];
1125
+ }
1126
+ return base;
1127
+ }
1102
1128
  function registerImageTool(server, budget) {
1103
1129
  server.registerTool(
1104
1130
  "blockrun_image",
@@ -1109,21 +1135,22 @@ Actions:
1109
1135
  - generate (default): Create image from text prompt
1110
1136
  - edit: Transform an existing image using img2img
1111
1137
 
1112
- Generation models:
1113
- - zai/cogview-4 ($0.015) \u2014 Zhipu CogView-4, photorealistic, great for detailed scenes
1114
- - xai/grok-imagine-image ($0.02) \u2014 xAI Grok Imagine, stylized, fast
1115
- - xai/grok-imagine-image-pro ($0.07) \u2014 xAI Grok Imagine Pro, higher quality
1116
- - openai/gpt-image-1 ($0.02-0.04) \u2014 GPT native image generation
1117
- - openai/gpt-image-2 ($0.06-0.12) \u2014 ChatGPT Images 2.0, reasoning-driven, multilingual text rendering + character consistency
1118
- - openai/dall-e-3 ($0.04-0.08) \u2014 High quality, prompt adherence
1119
- - google/nano-banana ($0.05) \u2014 Google image model
1120
- Edit models: openai/gpt-image-1, openai/gpt-image-2 (default for edits)`,
1138
+ Generation models (1024x1024 base price; larger sizes cost more on gpt-image-*):
1139
+ - openai/gpt-image-2 ($0.06\u20130.12) \u2014 flagship, reasoning-driven, multilingual on-image text + character consistency (default)
1140
+ - openai/gpt-image-1 ($0.02\u20130.04) \u2014 GPT native image generation
1141
+ - google/nano-banana ($0.05) \u2014 Gemini-family image model
1142
+ - google/nano-banana-pro ($0.10; $0.15 at 4096px) \u2014 up to 4K, strongest photorealism
1143
+ - xai/grok-imagine-image ($0.02) \u2014 stylized, fast
1144
+ - xai/grok-imagine-image-pro ($0.07) \u2014 higher quality Grok Imagine
1145
+ - zai/cogview-4 ($0.015) \u2014 cheapest, photorealistic detailed scenes
1146
+
1147
+ Edit (img2img) models: openai/gpt-image-2 (default), openai/gpt-image-1, google/nano-banana, google/nano-banana-pro`,
1121
1148
  inputSchema: {
1122
1149
  prompt: z4.string().describe("Image description or edit instructions"),
1123
1150
  action: z4.enum(["generate", "edit"]).optional().default("generate").describe("generate: create from text; edit: transform existing image"),
1124
- model: z4.enum(["zai/cogview-4", "openai/dall-e-3", "together/flux-schnell", "google/nano-banana", "openai/gpt-image-1", "openai/gpt-image-2", "xai/grok-imagine-image", "xai/grok-imagine-image-pro"]).optional().describe("Model to use (default: dall-e-3 for generate, gpt-image-2 for edit). xai/grok-imagine-image is stylized and fast; xai/grok-imagine-image-pro is higher quality; gpt-image-2 is the newest edit-capable model with stronger instruction following."),
1151
+ model: z4.enum(IMAGE_MODELS).optional().describe("Model to use (default: openai/gpt-image-2 for both generate and edit). gpt-image-2 renders on-image text best; nano-banana-pro for 4K photorealism; cogview-4 / grok-imagine-image for cheap drafts."),
1125
1152
  image: z4.string().optional().describe("Source image for edit action: base64-encoded image or URL"),
1126
- size: z4.enum(["1024x1024", "1792x1024", "1024x1792"]).optional().default("1024x1024"),
1153
+ size: z4.string().optional().default("1024x1024").describe("Image size. Common values: 1024x1024 (all models), 1536x1024 / 1024x1536 (gpt-image-*), 2048x2048 / 4096x4096 (nano-banana-pro)"),
1127
1154
  quality: z4.enum(["standard", "hd"]).optional().default("standard"),
1128
1155
  agent_id: z4.string().optional().describe("Agent identifier for budget tracking and enforcement.")
1129
1156
  }
@@ -1136,6 +1163,7 @@ Edit models: openai/gpt-image-1, openai/gpt-image-2 (default for edits)`,
1136
1163
  isError: true
1137
1164
  };
1138
1165
  }
1166
+ const selectedModel = model || "openai/gpt-image-2";
1139
1167
  let response;
1140
1168
  if (action === "edit") {
1141
1169
  if (!image) {
@@ -1144,14 +1172,13 @@ Edit models: openai/gpt-image-1, openai/gpt-image-2 (default for edits)`,
1144
1172
  isError: true
1145
1173
  };
1146
1174
  }
1147
- const selectedModel = model || "openai/gpt-image-2";
1148
1175
  if (!EDIT_MODELS.has(selectedModel)) {
1149
1176
  return {
1150
- content: [{ type: "text", text: formatError("Image edits support only openai/gpt-image-1 or openai/gpt-image-2") }],
1177
+ content: [{ type: "text", text: formatError("Image edits support openai/gpt-image-1, openai/gpt-image-2, google/nano-banana, or google/nano-banana-pro") }],
1151
1178
  isError: true
1152
1179
  };
1153
1180
  }
1154
- const estimatedCost = selectedModel === "openai/gpt-image-2" ? 0.12 : 0.04;
1181
+ const estimatedCost = estimateCost(selectedModel, size);
1155
1182
  const budgetCheck = checkBudget(budget, agent_id, estimatedCost);
1156
1183
  if (!budgetCheck.allowed) {
1157
1184
  return {
@@ -1165,8 +1192,7 @@ Edit models: openai/gpt-image-1, openai/gpt-image-2 (default for edits)`,
1165
1192
  });
1166
1193
  recordSpending(budget, estimatedCost, agent_id);
1167
1194
  } else {
1168
- const selectedModel = model || "openai/dall-e-3";
1169
- const estimatedCost = GENERATE_MODEL_COST[selectedModel] ?? 0.05;
1195
+ const estimatedCost = estimateCost(selectedModel, size);
1170
1196
  const budgetCheck = checkBudget(budget, agent_id, estimatedCost);
1171
1197
  if (!budgetCheck.allowed) {
1172
1198
  return {
@@ -1191,8 +1217,8 @@ Edit models: openai/gpt-image-1, openai/gpt-image-2 (default for edits)`,
1191
1217
  return {
1192
1218
  content: [{ type: "text", text: `Image: ${imageUrl}
1193
1219
  Prompt: ${prompt}
1194
- Model: ${action === "edit" ? model || "openai/gpt-image-2" : model || "openai/dall-e-3"}` }],
1195
- structuredContent: { url: imageUrl, prompt, model: action === "edit" ? model || "openai/gpt-image-2" : model || "openai/dall-e-3" }
1220
+ Model: ${selectedModel}` }],
1221
+ structuredContent: { url: imageUrl, prompt, model: selectedModel }
1196
1222
  };
1197
1223
  } catch (err) {
1198
1224
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -2780,6 +2806,74 @@ Each Surf endpoint pre-validates required params before settling \u2014 you get
2780
2806
  );
2781
2807
  }
2782
2808
 
2809
+ // src/tools/rpc.ts
2810
+ import { z as z17 } from "zod";
2811
+ var RPC_PRICE_USD = 2e-3;
2812
+ function registerRpcTool(server, budget) {
2813
+ server.registerTool(
2814
+ "blockrun_rpc",
2815
+ {
2816
+ description: `Raw JSON-RPC against 40+ blockchains \u2014 one endpoint, no node, no API key. $0.002 per call (batch charges per element).
2817
+
2818
+ Use when you need data the higher-level tools don't cover: contract reads (eth_call), balances, blocks, txs, logs, gas, or any chain-native RPC method.
2819
+
2820
+ Networks (full catalog in the rpc skill): ethereum, base, arbitrum, optimism, polygon, bsc, avalanche, solana, bitcoin, sui, near, ripple, polkadot, dogecoin, litecoin, monad, berachain, unichain, hyperevm, sonic, and 20+ more.
2821
+
2822
+ Examples:
2823
+ blockrun_rpc({ network: "ethereum", method: "eth_blockNumber" })
2824
+ blockrun_rpc({ network: "base", method: "eth_getBalance", params: ["0xabc...", "latest"] })
2825
+ blockrun_rpc({ network: "solana", method: "getSlot" })
2826
+ blockrun_rpc({ network: "bitcoin", method: "getblockchaininfo" })
2827
+ blockrun_rpc({ network: "ethereum", body: [{jsonrpc:"2.0",id:1,method:"eth_blockNumber"},{...}] }) // batch
2828
+
2829
+ Prefer blockrun_price (free quotes), blockrun_dex (free DEX data), or blockrun_surf (labeled/aggregated data) when they cover the question \u2014 this tool is for raw chain access.`,
2830
+ inputSchema: {
2831
+ network: z17.string().describe("Chain key, e.g. 'ethereum', 'base', 'solana', 'bitcoin', 'arbitrum', 'polygon'. Unknown slugs pass through to the Tatum gateway."),
2832
+ method: z17.string().optional().describe("JSON-RPC method, e.g. 'eth_blockNumber', 'eth_call', 'getSlot' (Solana), 'getblockchaininfo' (Bitcoin). Required unless 'body' is set."),
2833
+ params: z17.any().optional().describe("JSON-RPC params array for the method, e.g. ['0xabc...', 'latest']."),
2834
+ body: z17.any().optional().describe("Full JSON-RPC 2.0 body or an array of them (batch). Overrides method/params when set."),
2835
+ agent_id: z17.string().optional().describe("Agent identifier for budget tracking and enforcement.")
2836
+ }
2837
+ },
2838
+ async ({ network, method, params, body, agent_id }) => {
2839
+ try {
2840
+ body = coerceBody(body);
2841
+ if (body === void 0) {
2842
+ if (!method) {
2843
+ return {
2844
+ content: [{ type: "text", text: formatError("Provide either 'method' (with optional 'params') or a full JSON-RPC 'body'.") }],
2845
+ isError: true
2846
+ };
2847
+ }
2848
+ body = { jsonrpc: "2.0", id: 1, method, params: params ?? [] };
2849
+ }
2850
+ const batchCount = Array.isArray(body) ? Math.max(body.length, 1) : 1;
2851
+ const estimatedCost = RPC_PRICE_USD * batchCount;
2852
+ const budgetCheck = checkBudget(budget, agent_id, estimatedCost);
2853
+ if (!budgetCheck.allowed) {
2854
+ return {
2855
+ content: [{ type: "text", text: `${budgetCheck.reason}. Use blockrun_wallet action:"report" to see usage or action:"delegate" to increase agent budget.` }],
2856
+ isError: true
2857
+ };
2858
+ }
2859
+ const cleanNetwork = network.trim().toLowerCase().replace(/^\/+|\/+$/g, "");
2860
+ const client = getClient();
2861
+ const result = await client.requestWithPaymentRaw(`/v1/rpc/${cleanNetwork}`, body);
2862
+ recordSpending(budget, estimatedCost, agent_id);
2863
+ return {
2864
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
2865
+ structuredContent: typeof result === "object" && result !== null && !Array.isArray(result) ? result : { result }
2866
+ };
2867
+ } catch (err) {
2868
+ return {
2869
+ content: [{ type: "text", text: formatError(extractErrorMessage(err)) }],
2870
+ isError: true
2871
+ };
2872
+ }
2873
+ }
2874
+ );
2875
+ }
2876
+
2783
2877
  // src/mcp-handler.ts
2784
2878
  function initializeMcpServer(server) {
2785
2879
  const budget = { limit: null, spent: 0, calls: 0, agents: /* @__PURE__ */ new Map() };
@@ -2800,6 +2894,7 @@ function initializeMcpServer(server) {
2800
2894
  registerModalTool(server, budget);
2801
2895
  registerPhoneTool(server, budget);
2802
2896
  registerSurfTool(server, budget);
2897
+ registerRpcTool(server, budget);
2803
2898
  server.registerResource(
2804
2899
  "wallet",
2805
2900
  "blockrun://wallet",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/mcp",
3
- "version": "0.19.1",
3
+ "version": "0.20.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",