Releases: BlockRunAI/blockrun-mcp
Release list
v0.32.0 — Kimi K3 and the current high-end lineup
Adds Kimi K3 and the models the gateway serves that we didn't, and rebuilds MODEL_TIERS against the live catalogue.
A retired model ID does not fail
That's why the tiers had rotted invisibly. The gateway silently aliases a dead ID onto something else:
nvidia/llama-4-maverick→200 OK, body says"model": "nvidia/gpt-oss-120b"moonshot/kimi-k2.6→ still returns a402price quote- only a wholly unknown ID
400s
So "the tier works" was never evidence the tier was correct. 8 dead IDs had accumulated across 6 tiers, quietly routing to models nobody chose.
What's new
- Kimi K3 —
$3/$15, 1M ctx, vision + reasoning + coding →balanced,reasoning,coding. Supersedes the retired k2.x line. - The current high end —
gpt-5.6-sol/terra,claude-sonnet-5,claude-fable-5,grok-4.5/4.3/build-0.1,qwen3.7-max,deepseek-v4-pro(frontier-class reasoning at$0.435/$0.87),minimax-m3,glm-5.2/5.1. - Default model is now
gpt-5.6-terra— newer line, 1M context, and half the price of the outgoinggpt-5.5default.
What was broken
- The
freetier was 4/5 retired. Free calls were being served by models nobody picked. Rebuilt from the$0models actually listed. - Listed ≠ alive.
nvidia/mistral-large-3-675bis in the catalogue at$0and hangs — no response, no error, >90s, reproduced twice. It had landed atfree[0]on the first pass, where it would stall everymode:"free"call before the loop could fall through. Excluded. - The tool description advertised tiers that no longer existed — it told the model
codingmeant "GLM-5 first" whencoding[0]had beenclaude-opus-4.8for several releases.
Budget gate — verified, not assumed
The new $180/M and $168/M models raise whether the $20/M frontier reserve still covers the worst case. It does; the gateway quotes sublinearly — gpt-5.4-pro at 128k max_tokens quotes $2.42 against a $2.56 reserve. Headroom is only ~5%, so the constant was left alone rather than guessed at.
Verification
169/169 tests · typecheck · build · verify:prices 20/20 exact · stdio smoke test 19 tools · all 49 tier IDs validated against live GET /v1/models.
0.31.6 — a dead skill, a phantom endpoint, and a live price gate
Two of these were live the whole time and invisible to every prior audit round: a skill that never loaded and an endpoint that never existed. Both were found by asking the gateway instead of re-reading our own files.
prediction-markets has never once loaded
Its description read ...you CANNOT get from a public API: historical price.... A plain YAML scalar may not contain ": ", so the frontmatter failed to parse, the loader got no name, and the skill was never registered. It built, it published, the prose read perfectly — the only symptom was that Claude never used a capability we shipped.
blockrun_surf advertised an endpoint that does not exist
chat/completions ("Surf-1.5 chat with citations", $0.02 flat) returns 404 Unknown Surf endpoint — the gateway replies with its own catalog of 83. That phantom was the off-by-one: surf.ts claimed 84 where the skill and the gateway both say 83.
Correctness
withTxFeerounded where the gateway ceils.usdToMicroUsdcis an unconditionalMath.ceil; rounding goes one micro short wherever the ×1.05 margin drifts in float. modal's CPU hour charges 102001 micro, not 102000 —.toFixed(4)had been hiding it.- A prototype key killed every budget cap. modal's GPU tables were object literals, so
TABLE["toString"]returned a function, reaching the gate as NaN —cost > 0is false (call allowed) andspent += NaNsticks for the life of the process. A $1-capped agent was cleared for a $500 call. NowMaps, andbudget.tsfails closed on any non-finite estimate.
Prices — all understating, all corrected against live quotes
| claimed | charged | |
|---|---|---|
| image-prompting nano-banana | ~$0.01 | $0.0545 (5.45×) |
| image-prompting gpt-image-2 poster | ~$0.04 | $0.128 (3.2×) |
| surf worked example | $0.001 | $0.0095 (9.5×) |
| modal A100 example | no price, "auto-evicts when idle" | $1.3413, upfront, never refunded |
| rpc | $0.002 | $0.0040 |
| exa | $0.01 | $0.0120 |
search max_results:20 |
$0.50 | $0.527 |
Plus crypto-data, which documented blockrun_rpc({ chain: ... }) when the param is network — the call as written could not have run.
New: npm run verify:prices
Probes all 20 paid routes and compares each live 402 quote to what the estimator reserves. Under-reserving exits non-zero; over-reserving warns. Free to run (no payment attached). This drift is invisible to CI by construction — the gateway reprices without an MCP release — and had already shipped three times.
0 under-reserving, 0 over-reserving, 0 unreachable, 20 exact
169 tests, typecheck, build green.
v0.30.5 — redeem actually pays out (pUSD collateral adapters)
Fixes a real-money bug: action:"redeem" returned success + a tx hash while redeeming 0 shares (Polymarket data-api: REDEEM size=0).
Root cause (verified on-chain): V2-era CLOB token_ids are still keyed to USDC.e (standard) / the legacy NegRiskAdapter's wrapped collateral (neg-risk) — not pUSD. Redeeming via CTF.redeemPositions with pUSD collateral computes a positionId nobody holds, and the CTF does not revert on zero balance — it burns nothing, pays nothing, and the tx succeeds.
Fix: redeem now routes through Polymarket's canonical pUSD collateral adapters (contracts; Sourcify exact_match; identity constants verified on-chain): CtfCollateralAdapter 0xAdA100Db00Ca00073811820692005400218FcE1f (standard) and NegRiskCtfCollateralAdapter 0xadA2005600Dec949baf300f4C6120000bDB6eAab (neg-risk). They pull your outcome tokens, redeem through the right path, and pay the winnings back as pUSD.
action:"setup" confirm:true once before your next redeem — it grants the two new adapter approvals (setup reads approvals on-chain every run and signs what's missing).
Hardening from the adversarial audit of the fix: success message reports the actual payout delta (a $0 payout with winning tokens held returns a loud receipt.status; relayer failure text now triggers the missing-approval hint. 153 tests green.
v0.30.4 — Polymarket doc & runtime-text accuracy audit
A two-round multi-agent audit of the polymarket-trading skill against the implementation (69 claims verified, every finding adversarially re-checked) surfaced 24 stale or contradictory statements left behind by the 0.30.0 builder-key-bootstrap and 0.30.3 Finland-egress transitions. All fixed:
- Tool description no longer demands
POLYMARKET_RELAYER_API_KEY/_SECRET/_PASSPHRASE(creds are auto-bootstrapped from the wallet key since 0.30.0) and states the Finland-egress geoblock default. - Dead manual-creds code deleted (-77 lines):
relayerCredsMissing(), the unreachable "get relayer creds" setup branch,deriveDepositWalletNoCreds(), unusedRelayerCredsenv config. - Proxy ≠ egress, consistently: every surface (403 error, setup region line, skill, README, setup guide) now leads with the
POLYMARKET_CLOB_HOSTrepoint and states that a proxy alone doesn't change the Polymarket-facing egress. - EOA mode (
POLYMARKET_SIG_TYPE=0) honestly framed as a diagnostic fallback — the CLOB may reject plain-EOA makers (removes the contradictory "read-only for orders" claim). - Signer-key custody claims qualified:
~/.blockrun/.sessionis the default;BLOCKRUN_WALLET_KEYor an agentwallet.jsontakes precedence — backup notes now point at the key behind the signer addresssetupprints. README env table gains the missingBLOCKRUN_WALLET_KEYrow.
150 tests, typecheck, build, stdio smoke (19 tools) green. No behavior change to trading paths.
v0.30.2 — neg-risk trading fix (pUSD→NegRisk Adapter approval)
Fixes real-money trading on neg-risk (multi-outcome "winner") markets.
fix(polymarket)— grant the missing pUSD → NegRisk Adapter approval.setupapproved pUSD spend for only the two exchanges while giving the adapter a CTF operator approval but not the pUSD one — so a funded, exchange-approved vault had its neg-risk orders accepted by the CLOB then reverted in settlement. The pUSD spender set now matches Polymarket's canonicalapproveTokensForTrading(both exchanges + NegRisk Adapter + Conditional Tokens). Existing deposit wallets self-correct: re-runaction:"setup" confirm:trueonce to sign the new approval.fix(polymarket)— buy/sell now self-heal a stale CLOB balance cache: on anot enough balance/allowancerejection, refreshupdateBalanceAllowanceand retry the submit once;setupno longer silently swallows a failed cache warm-up.docs— document the full canonical approval set + neg-risk troubleshooting (README, setup guide, skill).
152 tests, typecheck, build, and stdio MCP smoke (19 tools) green.
v0.26.0 — media tools report USDC cost
blockrun_image, blockrun_video, and blockrun_music now surface the USDC cost in their result: a Cost: $X.XXXX line in the text output and a cost_usd field in structuredContent, matching blockrun_speech / blockrun_realface. Video and music report the real 402-settled amount (token-priced upstream, so 1080p/4K clips and long tracks can exceed the per-unit estimate); image uses the catalog estimate on Base and the 402 amount on Solana, each falling back to the estimate only if the quote doesn't parse. No new spend path and no change to what is charged — the figure shown is the same amount already booked to the budget ledger. Adds handler-level tests (HTTP + x402 mocked, no network/no spend). Typecheck clean, 109 tests pass, build + 18-tool stdio smoke green.
v0.25.3 — audit pass: budget-gate + pricing hardening, SSRF FQDN fix
A multi-agent audit pass (finder fan-out across the payment path + freshly-merged Solana image code, each finding adversarially verified) surfaced six real issues — all fixed. Two are budget-gate bypasses on the most-used tools; one is an SSRF deny-list gap.
- fix(chat) — reserve the frontier worst-case for
balanced/coding/default modes (the default chat path was reserving 6–20× too little, defeating the cap under concurrency). - security(ssrf) — strip trailing dots so an FQDN (
metadata.google.internal.,localhost.) can't bypass theblockrun_imagefetch deny-list. - fix(phone,surf) — price on a normalized path so a query string / trailing slash can't downgrade an expensive route (e.g. the $5
phone/numbers/buy) to the $0.001 default while the gateway charges full. - fix(image) — re-reserve the Solana quote against the budget before signing, so a marked-up settlement can't blow the cap (mirrors
blockrun_video). - fix(music) — keep the EIP-3009 authorization valid through the whole submit+poll window (was expiring at 300s, failing settlement for slow tracks).
- fix(speech,music) — book settled spend before parsing the response body, so a truncated body can't un-record a real on-chain charge.
103 tests (13 new) + typecheck + build + 18-tool stdio smoke green. No breaking changes.
v0.25.2 — patch the ws DoS dependency chain
Dependency security: a pinned viem transitive ws@8.20.1 (below the ≥8.21.0 patch) was flagging the whole ws → viem → @x402/evm → @blockrun/clawrouter → @blockrun/llm chain (5 high). An overrides entry forces viem's ws to 8.21.0 — clearing all of them (npm audit 15 → 11). The override ships in package.json, so every npx install gets the patched ws.
Remaining advisories are out of this repo's control: the Solana web3.js-v1 tree (no upstream fix for bigint-buffer; npm's only "fix" is a breaking downgrade), the intentional rpc-websockets@9.3.0 pin (bumping re-introduces the Node <20.19 ESM break), and a dev-only esbuild.
Also fixed at the source in @blockrun/llm@3.5.1 (pnpm overrides for ws+form-data, dev-tool bump — 0 critical, runtime highs cleared). No source changes; 84 tests + build + live wallet smoke green.
v0.25.1 — validate 0.25.0 env knobs
Hardening for the v0.25.0 opt-in image features (delta-audited, adversarially verified). Both findings low/quality, same root cause: bare Number(env || default) doesn't catch a malformed value.
fix(image)— a typo'd numeric env becameNaNand silently changed behavior:BLOCKRUN_CONFIRM_THRESHOLD="$0.05"flipped the confirm gate to ask-on-every-call, and (fail-open) a malformedBLOCKRUN_INLINE_MAX_BYTESremoved the inline base64 context cap (data.length > NaNis always false).confirm-spendnow reuses the validatedparseBudgetLimitEnv;inline-imageuses a validatingenvInt(falls back on non-finite/non-positive, clamps quality 1–100). No change for valid configs.
84 unit tests. Full details in CHANGELOG.md.
v0.25.0 — image inline preview + opt-in spend confirmation
Lands #21 (thanks @KillerQueen-Z!) — re-integrated on top of the 0.24.x charge path. Two opt-in blockrun_image UX layers, both default to prior behavior:
- Inline preview —
inlineparam (orBLOCKRUN_INLINE_IMAGES=1) returns a downscaled JPEG thumbnail as atype:"image"block alongside the full-res URL, so rich clients render it in-conversation. Best-effort with source download/decode caps; tunable viaBLOCKRUN_INLINE_MAX_DIM/_QUALITY/_MAX_BYTES. - Spend confirmation — MCP elicitation before charging, with an "approve all this session" checkbox. Off by default (
BLOCKRUN_CONFIRM_SPEND=on); fails open (only an explicit decline aborts, releasing the reservation and charging nothing; auto-approve latches only on an explicit accept).
Re-integrated so the 0.24.x SSRF guard, Content-Length cap, and concurrency-safe reserveBudget reservation all stay intact — the confirmation runs once inside the reserve→record→release flow. 84 unit tests. Full details in CHANGELOG.md.