Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Smoke-test the built server via the MCP stdio handshake:
(printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}\n{"jsonrpc":"2.0","method":"notifications/initialized"}\n{"jsonrpc":"2.0","id":2,"method":"tools/list"}\n'; sleep 2) | node dist/index.js 2>/dev/null
```

Should return <!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools including `blockrun_surf` and any new one you add.
Should return <!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools including `blockrun_surf` and any new one you add.

To test locally with Claude Code, point it at your dev build:

Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

<p>Agents can't sign up for accounts. Agents can't enter credit cards.<br>
Agents can only sign transactions.<br><br>
<strong>BlockRun MCP gives your agent <!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools — markets, research, web search, images, video, on-chain data, and live Polymarket trading — paid per call in USDC. No accounts. No API keys. No dashboards.</strong><br><br>
<strong>BlockRun MCP gives your agent <!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools — markets, research, web search, images, video, on-chain data, and live Polymarket trading — paid per call in USDC. No accounts. No API keys. No dashboards.</strong><br><br>
<em>Read the odds <strong>and</strong> place the bet, from one self-custody wallet.</em></p>

<br>

<img src="https://img.shields.io/badge/🧰_20_Tools-success?style=for-the-badge" alt="20 tools">&nbsp;
<img src="https://img.shields.io/badge/🧰_21_Tools-success?style=for-the-badge" alt="21 tools">&nbsp;
<img src="https://img.shields.io/badge/🤖_Agent--Native-black?style=for-the-badge" alt="Agent native">&nbsp;
<img src="https://img.shields.io/badge/🔑_Zero_API_Keys-blue?style=for-the-badge" alt="No API keys">&nbsp;
<img src="https://img.shields.io/badge/📈_Read_+_Trade_Polymarket-e11d48?style=for-the-badge" alt="Read and trade Polymarket">&nbsp;
Expand Down Expand Up @@ -42,7 +42,7 @@ claude mcp add blockrun -s user -- npx -y @blockrun/mcp@latest

---

> **BlockRun MCP** is an open-source [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude — and any MCP-compatible agent — <!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools for real-time data and real actions: <!-- br:models.chatVisible -->70<!-- /br:models.chatVisible --> LLMs, image & video generation, prediction-market data, live web/X search, on-chain queries across <!-- br:chains.rpc -->40<!-- /br:chains.rpc --> chains, and **the ability to place real, USDC-settled bets on Polymarket**. Authentication is a wallet signature (no API keys); you pay per call in USDC via the [x402](https://x402.org) protocol (no credit cards, no subscriptions). One self-custody wallet on Base or Solana. MIT licensed.
> **BlockRun MCP** is an open-source [Model Context Protocol](https://modelcontextprotocol.io) server that gives Claude — and any MCP-compatible agent — <!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools for real-time data and real actions: <!-- br:models.chatVisible -->70<!-- /br:models.chatVisible --> LLMs, image & video generation, prediction-market data, live web/X search, on-chain queries across <!-- br:chains.rpc -->40<!-- /br:chains.rpc --> chains, and **the ability to place real, USDC-settled bets on Polymarket**. Authentication is a wallet signature (no API keys); you pay per call in USDC via the [x402](https://x402.org) protocol (no credit cards, no subscriptions). One self-custody wallet on Base or Solana. MIT licensed.

## 🏆 First of its kind — the signal → trade loop in Claude Code

Expand All @@ -56,7 +56,7 @@ Every other data integration was built for **human developers** — create an ac

**Agents can't do any of that.** BlockRun MCP is built for the agent-first world:

- **One wallet, every source** — <!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools behind a single self-custody wallet. No per-vendor signups.
- **One wallet, every source** — <!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools behind a single self-custody wallet. No per-vendor signups.
- **No API keys** — your wallet signature *is* authentication.
- **No credit cards** — pay per request in USDC via [x402](https://x402.org), fractions of a cent each.
- **Starts free** — the free tier (`blockrun_chat mode:"free"`, `blockrun_dex`, crypto `blockrun_price`, `blockrun_models`) costs $0.
Expand All @@ -71,7 +71,7 @@ Every other data integration was built for **human developers** — create an ac
| ------------------- | -------------------------------- | ------------------------- | ----------------------------------------- |
| **Setup** | Account + API key *per vendor* | Account/key for 1 vendor | **Wallet auto-created, no signup** |
| **Payment** | Credit card, monthly minimums | Credit card / vendor plan | **USDC per-call via x402** |
| **Data sources** | One per integration | One vendor | **<!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools — LLMs, media, markets, chain**|
| **Data sources** | One per integration | One vendor | **<!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools — LLMs, media, markets, chain**|
| **Place real bets** | Build it yourself | Rare | **Yes — Polymarket CLOB, confirm-gated** |
| **Pay-chain** | — | — | **Base + Solana** |
| **Agent budgets** | Manual | — | **Built-in per-agent delegation** |
Expand Down Expand Up @@ -147,7 +147,7 @@ Expose a trimmed tool set so the client loads fewer schemas into context. Pass `

| Profile | Tools |
|---------|-------|
| `full` *(default)* | everything (<!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools) |
| `full` *(default)* | everything (<!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools) |
| `media` | `wallet` `models` `image` `video` `realface` `music` `speech` |
| `trading` | `wallet` `price` `dex` `markets` `surf` `defi` `rpc` `polymarket_read` `polymarket` |
| `research` | `wallet` `models` `chat` `search` `exa` `surf` |
Expand Down Expand Up @@ -215,6 +215,7 @@ Claude reads the odds with `blockrun_markets` and — with your confirmation —
| `blockrun_polymarket` | **Trade on Polymarket** (CLOB V2): place/cancel real bets, positions, redeem winnings — signed locally, settled in pUSD from a gasless deposit wallet. Confirm-gated, $25/order default cap. [Details ↓](#-polymarket-trading) | free tool; bets are your funds |
| `blockrun_surf` | Surf (asksurf.ai) — 83 endpoints: CEX data, on-chain SQL (13 chains, 80+ tables), 100M+ labeled wallets, Polymarket + Kalshi, social mindshare, news, Surf-1.5 chat with citations | $0.0095/call |
| `blockrun_exa` | Neural web search (Exa) — research, competitors, papers, URL content | $0.01/query |
| `blockrun_scrapecheck` | ScrapeCheck — verify a held web value (price, title, availability) against its live source page; pass/fail/unverifiable verdict carrying an ed25519 signature you can check against ScrapeCheck's published key | $0.012 full / $0.0040 presence |
| `blockrun_search` | Grok Live Search — web + X/Twitter + news with citations | $0.025 × max_results |
| `blockrun_dex` | Live DEX prices via DexScreener | free |
| `blockrun_rpc` | Raw JSON-RPC on <!-- br:chains.rpc -->40<!-- /br:chains.rpc --> chains (Ethereum, Base, Solana, Bitcoin, Sui, NEAR, …) via Tatum | $0.002/call |
Expand Down Expand Up @@ -295,7 +296,7 @@ blockrun_wallet action:"setup" # shows the Solana address + fun

Then send USDC (SPL) on the **Solana** network — from Coinbase (pick "Solana"), Phantom, Solflare, or Backpack. Switch back with `blockrun_wallet action:"chain" chain:"base"`. The server keeps both wallets; switching just changes which one pays.

**Base-only** — these fall back to Base regardless of active chain: `blockrun_music`, `blockrun_speech`, `blockrun_video`, paid `blockrun_realface`, paid stock `blockrun_price`, and native Anthropic (`claude-*`) passthrough. In Solana mode they return a "switch to Base" message instead of charging. `blockrun_image` pays on either chain.
**Base-only** — these fall back to Base regardless of active chain: `blockrun_music`, `blockrun_speech`, `blockrun_video`, `blockrun_scrapecheck`, paid `blockrun_realface`, paid stock `blockrun_price`, and native Anthropic (`claude-*`) passthrough. In Solana mode they return a "switch to Base" message instead of charging. `blockrun_image` pays on either chain.

---

Expand Down Expand Up @@ -391,7 +392,7 @@ The server runs a non-blocking npm registry check at startup and prints an `Upda
## FAQ

**What is BlockRun MCP?**
An open-source MCP server that gives Claude and other agents <!-- br:mcp.tools -->20<!-- /br:mcp.tools --> tools for real-time data and real actions (trading, media, on-chain), paid per call in USDC. No accounts, no API keys.
An open-source MCP server that gives Claude and other agents <!-- br:mcp.tools -->21<!-- /br:mcp.tools --> tools for real-time data and real actions (trading, media, on-chain), paid per call in USDC. No accounts, no API keys.

**Do I need API keys or accounts?**
No. A wallet is auto-created locally on first run; you fund it with USDC. No signups, no dashboards, no key rotation.
Expand Down
2 changes: 1 addition & 1 deletion brand-numbers.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"aliases": 229
},
"mcp": {
"tools": 20
"tools": 21
},
"chains": {
"rpc": 40
Expand Down
7 changes: 7 additions & 0 deletions scripts/verify-prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { estimateSurfCost, SURF_PRICE_USD } from "../src/tools/surf.js";
import { estimateSearchCost } from "../src/tools/search.js";
import { estimateCost as estimateImageCost } from "../src/tools/image.js";
import { estimateExaCost } from "../src/tools/exa.js";
import { estimateScrapecheckCost } from "../src/tools/scrapecheck.js";
import { estimateChatCost, promptCharSize } from "../src/tools/chat.js";
import { estimateVideoCost } from "../src/tools/video.js";
import { MARKETS_PRICE_USD } from "../src/tools/markets.js";
Expand Down Expand Up @@ -111,6 +112,12 @@ const PROBES: Probe[] = [
// Routes with no exported estimator: pin the documented figure instead, so a
// gateway reprice still trips this gate rather than only the skill docs.
{ label: "exa/search", path: "exa/search?query=t", expected: withTxFee(0.01) },
// ScrapeCheck is a pass-through partner: the BASE price is set by ScrapeCheck,
// not by our own catalogue, so it can move without a BlockRun deploy — the
// exact drift this sweep exists to catch. Base only (settles to ScrapeCheck's
// Base treasury), so `[sol: not served]` on these two rows is correct, not a gap.
{ label: "scrapecheck/verify", path: "scrapecheck/verify", body: { url: "https://example.com", claim: { price: "$1" }, asked: "what is the price?" }, expected: estimateScrapecheckCost("verify") },
{ label: "scrapecheck/presence", path: "scrapecheck/verify-presence", body: { url: "https://example.com", claim: { price: "$1" }, asked: "what is the price?" }, expected: estimateScrapecheckCost("presence") },
{ label: "defillama/protocols", path: "defillama/protocols", expected: withTxFee(0.005) },
{ label: "rpc/ethereum (single)", path: "rpc/ethereum", body: { jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] }, expected: withTxFee(0.002) },

Expand Down
2 changes: 2 additions & 0 deletions src/mcp-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { registerSurfTool } from "./tools/surf.js";
import { registerRpcTool } from "./tools/rpc.js";
import { registerDefiTool } from "./tools/defi.js";
import { registerPolymarketReadTool, registerPolymarketTool } from "./tools/polymarket.js";
import { registerScrapecheckTool } from "./tools/scrapecheck.js";
import { resolveTools, type ToolName } from "./profiles.js";

/**
Expand Down Expand Up @@ -75,6 +76,7 @@ export function initializeMcpServer(
defi: () => registerDefiTool(server, budget),
polymarket_read: () => registerPolymarketReadTool(server),
polymarket: () => registerPolymarketTool(server),
scrapecheck: () => registerScrapecheckTool(server, budget),
};

for (const [name, register] of Object.entries(registrars) as [ToolName, () => void][]) {
Expand Down
7 changes: 4 additions & 3 deletions src/profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ export type ToolName =
| "rpc"
| "defi"
| "polymarket_read"
| "polymarket";
| "polymarket"
| "scrapecheck";

// `as const satisfies` keeps the literal tuple type (so the exhaustiveness
// guard below can see the actual entries) AND rejects any entry that isn't a
// real ToolName (catches typos).
export const ALL_TOOLS = [
"wallet", "chat", "models", "image", "music", "speech", "video", "realface",
"search", "exa", "markets", "price", "dex", "modal", "phone", "surf", "rpc", "defi",
"polymarket_read", "polymarket",
"polymarket_read", "polymarket", "scrapecheck",
] as const satisfies readonly ToolName[];

// Compile-time guard: if a new ToolName is added to the union but not to
Expand All @@ -60,7 +61,7 @@ export const PROFILES: Record<string, ToolName[] | "all"> = {
trading: ["wallet", "price", "dex", "markets", "surf", "defi", "rpc", "polymarket_read", "polymarket"],
// Web research & analysis: live search, neural search, Surf's news/SQL,
// and chat for synthesis, plus wallet and the model catalogue.
research: ["wallet", "models", "chat", "search", "exa", "surf"],
research: ["wallet", "models", "chat", "search", "exa", "surf", "scrapecheck"],
// Minimal LLM gateway: just chat + model discovery + wallet.
chat: ["wallet", "models", "chat"],
};
Expand Down
Loading
Loading