@blockrun/mcp 0.9.1 → 0.13.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 +32 -7
  2. package/dist/index.js +145 -55
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -45,6 +45,27 @@ After BlockRun, it can. Each query costs fractions of a cent, billed from a loca
45
45
 
46
46
  ---
47
47
 
48
+ ## Showcase
49
+
50
+ Posters generated through `blockrun_image` with `openai/gpt-image-2`. Each is a single API call routed through BlockRun, paid in USDC on Base.
51
+
52
+ ### Latest — GPT-5.5 now live on BlockRun
53
+
54
+ <p align="center">
55
+ <img src="assets/posters/gpt-5-5-launch.png" width="640" alt="gpt-5.5 — now live on BlockRun. Pay per call. No subscription. No keys.">
56
+ </p>
57
+
58
+ ### Gallery
59
+
60
+ | | | |
61
+ |:---:|:---:|:---:|
62
+ | <img src="assets/posters/cornell-2026-popular-booth.png" width="280" alt="Thank you, Cornell — BlockRun at the Cornell Blockchain Conference 2026, packed booth"> | <img src="assets/posters/cornell-2026.png" width="280" alt="Thank you, Cornell — BlockRun at the Cornell Blockchain Conference 2026"> | <img src="skills/image-prompting/example-100t-poster.jpg" width="280" alt="100 Trillion Tokens served — synthwave milestone poster"> |
63
+ | **Cornell Blockchain Conference 2026** — packed booth recap | **Cornell Blockchain Conference 2026** — quiet variant | **100 Trillion Tokens** — milestone synthwave poster |
64
+
65
+ Prompts and a worked example for these are in [`skills/image-prompting/SKILL.md`](skills/image-prompting/SKILL.md).
66
+
67
+ ---
68
+
48
69
  ## Install
49
70
 
50
71
  **Claude Code (recommended)**
@@ -83,7 +104,7 @@ Run `blockrun_wallet` to see your address. Send USDC on Base.
83
104
  | Coinbase | Send → USDC → Base network → paste address |
84
105
  | Bridge from Ethereum | [bridge.base.org](https://bridge.base.org) |
85
106
 
86
- $5 covers ~5,000 market queries, ~500 Exa searches, or ~250 image generations.
107
+ $5 covers ~5,000 market queries, ~500 Exa searches, ~250 image generations, or ~30 Seedance 1.5-pro clips (5s).
87
108
 
88
109
  ---
89
110
 
@@ -91,14 +112,18 @@ $5 covers ~5,000 market queries, ~500 Exa searches, or ~250 image generations.
91
112
 
92
113
  | Tool | Data source | Cost |
93
114
  |------|-------------|------|
94
- | `blockrun_markets` | Polymarket, Kalshi, dFlow, Binance Futures | $0.001/query |
115
+ | `blockrun_chat` | 55+ LLMs (GPT, Claude, Gemini, DeepSeek, Kimi K2.6, GLM, NVIDIA free tier, ...) with `mode` tier routing | per token |
116
+ | `blockrun_image` | DALL-E 3, GPT Image 1/2, Grok Imagine, Flux, CogView-4, Nano Banana — generation + editing | $0.015–0.12 |
117
+ | `blockrun_video` | xAI Grok Imagine Video + ByteDance Seedance 1.5/2.0/2.0-fast | $0.03–0.30/sec |
118
+ | `blockrun_music` | MiniMax music generation | per track |
119
+ | `blockrun_price` | Pyth-backed realtime + OHLC — crypto / FX / commodity (free), 12 stock markets (paid) | free or $0.001/call |
120
+ | `blockrun_markets` | Polymarket (markets, candles, trades, orderbooks, leaderboards, smart-wallet PnL/clusters, UMA oracle), Kalshi, Limitless, Opinion, Predict.Fun, dFlow, Binance Futures, cross-platform match + search | $0.001–0.005/query |
121
+ | `blockrun_x` | X/Twitter — profiles, tweets, followers, mentions, search (AttentionVC) | per call |
95
122
  | `blockrun_exa` | Neural web search (Exa) — research, competitors, papers, URL content | $0.01/query |
96
- | `blockrun_search` | Web + news with citations | ~$0.01 |
97
- | `blockrun_twitter` | X/Twitter — profiles, tweets, trends, Grok sentiment | per token |
123
+ | `blockrun_search` | Grok Live Search — web + news with citations | ~$0.025 per source |
98
124
  | `blockrun_dex` | Live DEX prices via DexScreener | free |
99
- | `blockrun_image` | DALL-E 3, Flux image generation + editing | $0.02–0.08 |
100
- | `blockrun_chat` | GPT-4o, Gemini, DeepSeek, 30+ models | per token |
101
- | `blockrun_wallet` | Balance, spending, agent budgets | free |
125
+ | `blockrun_models` | Live catalogue of every LLM/image/video/music model + pricing | free |
126
+ | `blockrun_wallet` | Balance, spending, agent budgets, setup QR | free |
102
127
 
103
128
  ---
104
129
 
package/dist/index.js CHANGED
@@ -117,8 +117,8 @@ var MODEL_TIERS = {
117
117
  powerful: ["openai/gpt-5.4-pro", "anthropic/claude-opus-4.7", "anthropic/claude-opus-4.6", "openai/o3", "openai/gpt-5.4"],
118
118
  cheap: ["zai/glm-5", "zai/glm-5-turbo", "nvidia/gpt-oss-120b", "nvidia/deepseek-v3.2", "google/gemini-2.5-flash", "deepseek/deepseek-chat", "openai/gpt-5.4-nano"],
119
119
  reasoning: ["openai/o3", "openai/o1", "openai/o3-mini", "deepseek/deepseek-reasoner", "moonshot/kimi-k2.6", "openai/gpt-5.3-codex"],
120
- free: ["nvidia/gpt-oss-120b", "nvidia/deepseek-v3.2", "nvidia/nemotron-ultra-253b", "nvidia/nemotron-super-49b", "nvidia/qwen3-coder-480b", "nvidia/llama-4-maverick", "nvidia/gpt-oss-20b", "nvidia/glm-4.7"],
121
- coding: ["zai/glm-5", "openai/gpt-5.3-codex", "moonshot/kimi-k2.6", "nvidia/qwen3-coder-480b", "nvidia/devstral-2-123b", "anthropic/claude-sonnet-4.6", "openai/gpt-5.4"],
120
+ free: ["nvidia/qwen3-next-80b-a3b-thinking", "nvidia/mistral-small-4-119b", "nvidia/gpt-oss-120b", "nvidia/deepseek-v3.2", "nvidia/qwen3-coder-480b", "nvidia/llama-4-maverick", "nvidia/gpt-oss-20b", "nvidia/glm-4.7"],
121
+ coding: ["zai/glm-5", "openai/gpt-5.3-codex", "moonshot/kimi-k2.6", "nvidia/qwen3-coder-480b", "anthropic/claude-sonnet-4.6", "openai/gpt-5.4"],
122
122
  glm: ["zai/glm-5", "zai/glm-5-turbo", "nvidia/glm-4.7"]
123
123
  };
124
124
 
@@ -596,6 +596,7 @@ ${lines.join("\n")}` }],
596
596
 
597
597
  // src/tools/image.ts
598
598
  import { z as z4 } from "zod";
599
+ import { PaymentError } from "@blockrun/llm";
599
600
  function registerImageTool(server) {
600
601
  server.registerTool(
601
602
  "blockrun_image",
@@ -611,13 +612,14 @@ Generation models:
611
612
  - xai/grok-imagine-image ($0.02) \u2014 xAI Grok Imagine, stylized, fast
612
613
  - xai/grok-imagine-image-pro ($0.07) \u2014 xAI Grok Imagine Pro, higher quality
613
614
  - openai/gpt-image-1 ($0.02-0.04) \u2014 GPT native image generation
615
+ - openai/gpt-image-2 ($0.06-0.12) \u2014 ChatGPT Images 2.0, reasoning-driven, multilingual text rendering + character consistency
614
616
  - openai/dall-e-3 ($0.04-0.08) \u2014 High quality, prompt adherence
615
617
  - google/nano-banana ($0.05) \u2014 Google image model
616
- Edit models: openai/gpt-image-1 (default for edits)`,
618
+ Edit models: openai/gpt-image-1, openai/gpt-image-2 (default for edits)`,
617
619
  inputSchema: {
618
620
  prompt: z4.string().describe("Image description or edit instructions"),
619
621
  action: z4.enum(["generate", "edit"]).optional().default("generate").describe("generate: create from text; edit: transform existing image"),
620
- model: z4.enum(["zai/cogview-4", "openai/dall-e-3", "together/flux-schnell", "google/nano-banana", "openai/gpt-image-1", "xai/grok-imagine-image", "xai/grok-imagine-image-pro"]).optional().describe("Model to use (default: dall-e-3 for generate, gpt-image-1 for edit). xai/grok-imagine-image is stylized and fast; xai/grok-imagine-image-pro is higher quality."),
622
+ 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."),
621
623
  image: z4.string().optional().describe("Source image for edit action: base64-encoded image or URL"),
622
624
  size: z4.enum(["1024x1024", "1792x1024", "1024x1792"]).optional().default("1024x1024"),
623
625
  quality: z4.enum(["standard", "hd"]).optional().default("standard")
@@ -635,7 +637,7 @@ Edit models: openai/gpt-image-1 (default for edits)`,
635
637
  };
636
638
  }
637
639
  response = await imgClient.edit(prompt, image, {
638
- model: model || "openai/gpt-image-1",
640
+ model: model || "openai/gpt-image-2",
639
641
  size
640
642
  });
641
643
  } else {
@@ -660,7 +662,7 @@ Model: ${model}` }],
660
662
  };
661
663
  } catch (err) {
662
664
  const errMsg = err instanceof Error ? err.message : String(err);
663
- if (errMsg.includes("balance") || errMsg.includes("payment") || errMsg.includes("402")) {
665
+ if (err instanceof PaymentError) {
664
666
  return {
665
667
  content: [{ type: "text", text: `Image generation requires payment. Run blockrun_wallet with action: "setup" for funding instructions.
666
668
  Error: ${errMsg}` }],
@@ -825,41 +827,46 @@ import {
825
827
  extractPaymentDetails as extractPaymentDetails2
826
828
  } from "@blockrun/llm";
827
829
  var BLOCKRUN_API2 = "https://blockrun.ai/api";
828
- var VIDEO_TIMEOUT = 3e5;
830
+ var TOTAL_BUDGET_MS = 3e5;
831
+ var POLL_INTERVAL_MS = 5e3;
829
832
  function registerVideoTool(server) {
830
833
  server.registerTool(
831
834
  "blockrun_video",
832
835
  {
833
- description: `Generate short AI videos via BlockRun x402.
836
+ description: `Generate short AI videos via BlockRun x402 (async, client-polled).
834
837
 
835
- Uses xAI's Grok Imagine Video to turn a text prompt (and optional seed image) into an 8-second MP4 clip. The call blocks until the video is ready (30-120s typical).
838
+ Turns a text prompt (and optional seed image) into a short MP4 clip. The tool submits the job, then polls until the video is ready (typical total wall-time 60-180s; 5 min hard cap). Payment is settled only when upstream returns a finished video \u2014 if the job fails or we give up, you are not charged.
836
839
 
837
- Model: xai/grok-imagine-video ($0.05/sec, 8s default -> $0.42/clip)
840
+ Models:
841
+ - xai/grok-imagine-video ($0.05/sec, 8s default -> $0.42/clip) \u2014 stylized, fast
842
+ - bytedance/seedance-1.5-pro ($0.03/sec, 720p, 5s default up to 10s) \u2014 cheapest
843
+ - bytedance/seedance-2.0-fast ($0.15/sec, ~60-80s gen) \u2014 sweet-spot price/quality
844
+ - bytedance/seedance-2.0 ($0.30/sec, 720p Pro) \u2014 highest quality
838
845
 
839
846
  Returns a permanent blockrun-hosted MP4 URL (the gateway mirrors the asset to GCS so URLs don't expire).`,
840
847
  inputSchema: {
841
848
  prompt: z6.string().describe("Text description of the video to generate. E.g. 'a red apple slowly spinning on a wooden table', 'a hummingbird hovering near a red flower, ultra slow motion'"),
842
849
  image_url: z6.string().url().optional().describe("Optional seed image URL for image-to-video generation"),
843
- duration_seconds: z6.number().int().min(1).max(60).optional().describe("Duration to bill for (defaults to the model's 8s default). Must not exceed max_duration_seconds."),
844
- model: z6.enum(["xai/grok-imagine-video"]).optional().default("xai/grok-imagine-video").describe("Video model to use")
850
+ duration_seconds: z6.number().int().min(1).max(60).optional().describe("Duration to bill for (defaults to the model's default \u2014 8s for xAI, 5s for Seedance; Seedance supports up to 10s)."),
851
+ model: z6.enum(["xai/grok-imagine-video", "bytedance/seedance-1.5-pro", "bytedance/seedance-2.0-fast", "bytedance/seedance-2.0"]).optional().default("xai/grok-imagine-video").describe("Video model to use")
845
852
  }
846
853
  },
847
854
  async ({ prompt, image_url, duration_seconds, model }) => {
848
855
  try {
849
856
  const privateKey = getOrCreateWalletKey();
850
857
  const account = privateKeyToAccount2(privateKey);
851
- const url = `${BLOCKRUN_API2}/v1/videos/generations`;
858
+ const submitUrl = `${BLOCKRUN_API2}/v1/videos/generations`;
852
859
  const body = { model, prompt };
853
860
  if (image_url) body.image_url = image_url;
854
861
  if (duration_seconds !== void 0) body.duration_seconds = duration_seconds;
855
- const resp402 = await fetchWithTimeout2(url, {
862
+ const resp402 = await fetchWithTimeout2(submitUrl, {
856
863
  method: "POST",
857
864
  headers: { "Content-Type": "application/json" },
858
865
  body: JSON.stringify(body)
859
866
  }, 15e3);
860
867
  if (resp402.status !== 402) {
861
- const data2 = await resp402.json();
862
- throw new Error(`Expected 402, got ${resp402.status}: ${JSON.stringify(data2)}`);
868
+ const data = await resp402.json();
869
+ throw new Error(`Expected 402, got ${resp402.status}: ${JSON.stringify(data)}`);
863
870
  }
864
871
  const prHeader = resp402.headers.get("payment-required") || resp402.headers.get("PAYMENT-REQUIRED");
865
872
  if (!prHeader) throw new Error("No PAYMENT-REQUIRED header in 402 response");
@@ -872,50 +879,91 @@ Returns a permanent blockrun-hosted MP4 URL (the gateway mirrors the asset to GC
872
879
  details.amount,
873
880
  details.network || "eip155:8453",
874
881
  {
875
- resourceUrl: details.resource?.url || url,
882
+ resourceUrl: details.resource?.url || submitUrl,
876
883
  resourceDescription: details.resource?.description || "BlockRun Video Generation",
877
- maxTimeoutSeconds: details.maxTimeoutSeconds || 300,
884
+ // Bump to 10 min so the signed authorization stays valid through the
885
+ // async polling window. Default (~5 min) is tight when upstream is slow.
886
+ maxTimeoutSeconds: Math.max(details.maxTimeoutSeconds || 0, 600),
878
887
  extra: details.extra
879
888
  }
880
889
  );
881
- const resp = await fetchWithTimeout2(url, {
890
+ const submitResp = await fetchWithTimeout2(submitUrl, {
882
891
  method: "POST",
883
892
  headers: {
884
893
  "Content-Type": "application/json",
885
894
  "PAYMENT-SIGNATURE": paymentPayload
886
895
  },
887
896
  body: JSON.stringify(body)
888
- }, VIDEO_TIMEOUT);
889
- if (resp.status === 402) {
897
+ }, 3e4);
898
+ if (submitResp.status === 402) {
890
899
  throw new Error("Payment rejected. Check your wallet balance.");
891
900
  }
892
- if (!resp.ok) {
893
- const errBody = await resp.json().catch(() => ({ error: "Request failed" }));
894
- throw new Error(`API error ${resp.status}: ${JSON.stringify(errBody)}`);
901
+ if (!submitResp.ok && submitResp.status !== 202) {
902
+ const errBody = await submitResp.json().catch(() => ({ error: "Submit failed" }));
903
+ throw new Error(`API error ${submitResp.status}: ${JSON.stringify(errBody)}`);
904
+ }
905
+ const submitData = await submitResp.json();
906
+ if (!submitData.id || !submitData.poll_url) {
907
+ throw new Error(`Submit response missing id/poll_url: ${JSON.stringify(submitData)}`);
908
+ }
909
+ const pollAbsoluteUrl = submitData.poll_url.startsWith("http") ? submitData.poll_url : `${BLOCKRUN_API2.replace(/\/api$/, "")}${submitData.poll_url}`;
910
+ const startedAt = Date.now();
911
+ let lastStatus = submitData.status || "queued";
912
+ let completed = null;
913
+ while (Date.now() - startedAt < TOTAL_BUDGET_MS) {
914
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
915
+ const pollResp = await fetchWithTimeout2(pollAbsoluteUrl, {
916
+ method: "GET",
917
+ headers: { "PAYMENT-SIGNATURE": paymentPayload }
918
+ }, 9e4);
919
+ const pollData = await pollResp.json().catch(() => ({}));
920
+ lastStatus = pollData.status || lastStatus;
921
+ if (pollResp.status === 202 && (lastStatus === "queued" || lastStatus === "in_progress")) {
922
+ continue;
923
+ }
924
+ if (lastStatus === "failed") {
925
+ throw new Error(`Upstream generation failed: ${pollData.error || "unknown"}. No payment taken.`);
926
+ }
927
+ if (pollResp.ok && lastStatus === "completed") {
928
+ const clip = pollData.data?.[0];
929
+ if (!clip?.url) throw new Error("Completed poll missing video URL");
930
+ completed = {
931
+ url: clip.url,
932
+ source_url: clip.source_url,
933
+ duration_seconds: clip.duration_seconds,
934
+ request_id: clip.request_id,
935
+ backed_up: clip.backed_up,
936
+ modelReturned: pollData.model,
937
+ txHash: pollResp.headers.get("X-Payment-Receipt") || pollResp.headers.get("x-payment-receipt") || void 0
938
+ };
939
+ break;
940
+ }
941
+ if (!pollResp.ok && pollResp.status !== 202 && pollResp.status !== 504) {
942
+ throw new Error(`Poll error ${pollResp.status}: ${JSON.stringify(pollData)}`);
943
+ }
944
+ }
945
+ if (!completed) {
946
+ throw new Error(`Video generation did not complete within ${Math.round(TOTAL_BUDGET_MS / 1e3)}s (last status: ${lastStatus}). No payment was taken.`);
895
947
  }
896
- const data = await resp.json();
897
- const clip = data.data?.[0];
898
- if (!clip?.url) throw new Error("No video URL in response");
899
- const txHash = resp.headers.get("X-Payment-Receipt") || resp.headers.get("x-payment-receipt");
900
948
  const lines = [
901
949
  `\u{1F3AC} Video ready!`,
902
- `URL: ${clip.url}`,
903
- `Duration: ${clip.duration_seconds ? `${clip.duration_seconds}s` : "8s"}`,
904
- `Model: ${data.model || model}`,
905
- ...clip.backed_up ? [`Backed up to BlockRun storage (URL is permanent)`] : clip.source_url ? [`Source URL: ${clip.source_url}`] : [],
906
- ...clip.request_id ? [`Request ID: ${clip.request_id}`] : [],
907
- ...txHash ? [`Tx: ${txHash}`] : []
950
+ `URL: ${completed.url}`,
951
+ `Duration: ${completed.duration_seconds ? `${completed.duration_seconds}s` : "8s"}`,
952
+ `Model: ${completed.modelReturned || model}`,
953
+ ...completed.backed_up ? [`Backed up to BlockRun storage (URL is permanent)`] : completed.source_url ? [`Source URL: ${completed.source_url}`] : [],
954
+ ...completed.request_id ? [`Request ID: ${completed.request_id}`] : [],
955
+ ...completed.txHash ? [`Tx: ${completed.txHash}`] : []
908
956
  ];
909
957
  return {
910
958
  content: [{ type: "text", text: lines.join("\n") }],
911
959
  structuredContent: {
912
- url: clip.url,
913
- ...clip.source_url ? { source_url: clip.source_url } : {},
914
- duration_seconds: clip.duration_seconds,
915
- model: data.model || model,
916
- ...clip.request_id ? { request_id: clip.request_id } : {},
917
- ...clip.backed_up !== void 0 ? { backed_up: clip.backed_up } : {},
918
- ...txHash ? { txHash } : {}
960
+ url: completed.url,
961
+ ...completed.source_url ? { source_url: completed.source_url } : {},
962
+ duration_seconds: completed.duration_seconds,
963
+ model: completed.modelReturned || model,
964
+ ...completed.request_id ? { request_id: completed.request_id } : {},
965
+ ...completed.backed_up !== void 0 ? { backed_up: completed.backed_up } : {},
966
+ ...completed.txHash ? { txHash: completed.txHash } : {}
919
967
  }
920
968
  };
921
969
  } catch (err) {
@@ -927,9 +975,9 @@ Error: ${errMsg}` }],
927
975
  isError: true
928
976
  };
929
977
  }
930
- if (errMsg.includes("abort") || errMsg.includes("timeout") || errMsg.includes("Timeout") || errMsg.includes("timed out")) {
978
+ if (errMsg.includes("abort") || errMsg.includes("timeout") || errMsg.includes("Timeout") || errMsg.includes("timed out") || errMsg.includes("did not complete within")) {
931
979
  return {
932
- content: [{ type: "text", text: `Video generation timed out. xAI's async job didn't complete in time \u2014 please try again.
980
+ content: [{ type: "text", text: `Video generation timed out. The upstream async job didn't complete in time \u2014 please try again.
933
981
  Error: ${errMsg}` }],
934
982
  isError: true
935
983
  };
@@ -1075,19 +1123,61 @@ function registerMarketsTool(server) {
1075
1123
  server.registerTool(
1076
1124
  "blockrun_markets",
1077
1125
  {
1078
- description: `Prediction market data. Real-time from Polymarket, Kalshi.
1079
-
1080
- Example paths:
1081
- - "polymarket/events" \u2014 list active events
1082
- - "polymarket/markets" \u2014 list markets
1083
- - "kalshi/markets" \u2014 Kalshi markets
1084
- - "kalshi/markets/KXBTC-25MAR14" \u2014 specific market
1085
-
1086
- $0.001/call.`,
1126
+ description: `Prediction market + derivatives data via Predexon aggregator. Tier 1 = $0.001/call, Tier 2 = $0.005/call.
1127
+
1128
+ CANONICAL CROSS-VENUE (Tier 1) \u2014 Predexon v2 unified data layer:
1129
+ - markets \u2014 list canonical market/question containers with cross-venue Predexon IDs
1130
+ - markets/listings \u2014 venue-native executable listings flattened across canonical markets
1131
+ - outcomes/:predexon_id \u2014 resolve a canonical outcome ID to its market context + venue listings
1132
+ Filter with ?venue=polymarket|kalshi|limitless|opinion|predictfun, ?status=, ?category=, ?league=, ?event_id=, ?pagination_key=
1133
+
1134
+ POLYMARKET (Tier 1):
1135
+ - polymarket/events, polymarket/markets \u2014 list events/markets (filter, sort, paginate)
1136
+ - polymarket/markets/keyset, polymarket/events/keyset \u2014 same data, cursor-based keyset pagination (use ?pagination_key=)
1137
+ - polymarket/crypto-updown \u2014 crypto up/down markets
1138
+ - polymarket/market-price/:token_id \u2014 current/historical price
1139
+ - polymarket/candlesticks/:condition_id \u2014 OHLCV by market
1140
+ - polymarket/candlesticks/token/:token_id \u2014 OHLCV by single outcome token
1141
+ - polymarket/volume-chart/:condition_id \u2014 volume w/ YES/NO split
1142
+ - polymarket/orderbooks, polymarket/trades, polymarket/activity
1143
+ - polymarket/markets/:token_id/volume, polymarket/markets/:condition_id/open_interest
1144
+ - polymarket/positions \u2014 user positions
1145
+ - polymarket/leaderboard, polymarket/leaderboard/market/:condition_id
1146
+ - polymarket/cohorts/stats, polymarket/market/:condition_id/top-holders
1147
+ - polymarket/uma/markets, polymarket/uma/market/:condition_id \u2014 UMA oracle questions/timeline
1148
+
1149
+ POLYMARKET (Tier 2 \u2014 wallet/smart-money analytics):
1150
+ - polymarket/wallet/:wallet \u2014 full smart-wallet profile
1151
+ - polymarket/wallet/:wallet/markets, .../similar
1152
+ - polymarket/wallet/pnl/:wallet, .../positions/:wallet, .../volume-chart/:wallet
1153
+ - polymarket/wallets/profiles, polymarket/wallets/filter \u2014 batch + AND/OR filter
1154
+ - polymarket/market/:condition_id/smart-money, polymarket/markets/smart-activity
1155
+
1156
+ WALLET IDENTITY & CLUSTERING (Tier 2) \u2014 cross-context labels + on-chain relationship graph:
1157
+ - polymarket/wallet/identity/:wallet \u2014 fetch identity + profile metadata for one wallet
1158
+ - polymarket/wallet/identities \u2014 POST { addresses: [...] } for bulk lookup (up to 200 wallets)
1159
+ - polymarket/wallet/:address/cluster \u2014 discover wallets connected via on-chain transfers + identity proofs
1160
+
1161
+ SPORTS (Tier 1):
1162
+ - sports/categories \u2014 list available sports categories
1163
+ - sports/markets \u2014 list sports markets grouped by game (filter ?league=, ?sport_type=, ?status=, ?venue=)
1164
+ - sports/markets/:game_id \u2014 single sports game with all venue outcomes
1165
+ - sports/outcomes/:predexon_id \u2014 equivalent sports outcomes across venues for a Predexon ID
1166
+
1167
+ KALSHI (Tier 1): kalshi/markets, kalshi/trades, kalshi/orderbooks
1168
+ LIMITLESS / OPINION / PREDICT.FUN (Tier 1): {platform}/markets, {platform}/orderbooks
1169
+ DFLOW: dflow/trades (T1), dflow/wallet/positions/:wallet (T2), dflow/wallet/pnl/:wallet (T2)
1170
+ BINANCE FUTURES (Tier 2): binance/candles/:symbol, binance/ticks/:symbol
1171
+
1172
+ CROSS-PLATFORM:
1173
+ - matching-markets, matching-markets/pairs \u2014 equivalent markets across Polymarket+Kalshi (T2)
1174
+ - markets/search \u2014 search across all platforms in one call (T2)
1175
+
1176
+ Pass query params via 'params' (GET). Use 'body' only for POST endpoints (e.g. polymarket/wallet/identities).`,
1087
1177
  inputSchema: {
1088
- path: z9.string().describe("Endpoint path, e.g. 'polymarket/events', 'kalshi/markets/KXBTC-25MAR14'"),
1089
- params: z9.record(z9.string(), z9.string()).optional().describe("Query parameters for GET requests"),
1090
- body: z9.any().optional().describe("JSON body for POST queries (triggers pmQuery)")
1178
+ path: z9.string().describe("Endpoint path, e.g. 'polymarket/events', 'kalshi/markets/KXBTC-25MAR14', 'polymarket/wallet/0xabc...', 'markets/search'"),
1179
+ params: z9.record(z9.string(), z9.string()).optional().describe("Query parameters for GET requests (e.g. { limit: '20', active: 'true' })"),
1180
+ body: z9.any().optional().describe("JSON body for POST queries (triggers pmQuery \u2014 most endpoints are GET)")
1091
1181
  }
1092
1182
  },
1093
1183
  async ({ path: path3, params, body }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blockrun/mcp",
3
- "version": "0.9.1",
3
+ "version": "0.13.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",
@@ -44,7 +44,7 @@
44
44
  "url": "https://github.com/blockrunai/blockrun-mcp/issues"
45
45
  },
46
46
  "dependencies": {
47
- "@blockrun/llm": "^1.8.0",
47
+ "@blockrun/llm": "^1.12.0",
48
48
  "@modelcontextprotocol/sdk": "^1.0.0",
49
49
  "open": "^11.0.0",
50
50
  "qrcode": "^1.5.4",