Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,50 @@
# Changelog

## 0.53.0

### Added — Seedance reference media, 2.5 first/last frame, output controls

`blockrun_video` gains the Seedance capabilities the gateway already serves.
Full matrix, per rail and per model, in
[docs/seedance-capabilities.md](docs/seedance-capabilities.md).

- **Reference media — account rail only (`BLOCKRUN_API_KEY`).**
`reference_image_urls` (up to 9 on seedance-2.0 / 2.0-fast / 2.0-mini, up
to 30 on 2.5), `reference_videos` and `reference_audios` (1-3 each, 2.0
family only; audio needs an image or video beside it). The Base and Solana
gateways refuse reference media with a 400 before quoting, so the tool
refuses it on those rails first, naming the rail that serves it. No
payment is taken. References and frame seeds (`image_url`,
`last_frame_url`, `real_face_asset_id`) are mutually exclusive.
- **Reference clips are expensive, and the reserve says so.** The gateway
bills per reference second, and the caller sends a URL, never a duration,
so every clip is reserved at the model's 15.2s ceiling. One clip makes a 5s
720p render cost about 4x (seedance-2.0-mini ~$0.40 to ~$1.61). A 4K job
on seedance-2.0 with three videos and three audios reserves ~$130.88. The
spend confirmation now lists the reference clips, so the price makes sense.
Reference images carry no surcharge.
- **First-and-last-frame on seedance-2.5** (`last_frame_url` with
`image_url`), joining 1.5-pro and the 2.0 family.
- **Output controls:** `bitrate_mode` (2.x), `output_format` mp4/mov (2.5),
`return_last_frame`, `watermark` and `safety_identifier` (Seedance), and
`seed` / `camera_fixed` (1.5-pro). A control declared for the wrong model is
refused by name before payment.
- Every in-memory guard now runs before the SSRF DNS resolution, so a
request the tool will refuse anyway costs no lookups.

### Fixed

- **Guard order.** With references present, the conflict with frame seeds is
answered before the `last_frame_url` / RealFace guards. Before, a reference
request carrying `last_frame_url` was told to add `image_url`, and only on
the resubmit that seeds and references never mix.
- **A Solana image give-up named the wrong place to check.** Since 0.52.2 the
Solana image path can end in a settled-at-submit give-up, and the message
was written for the account rail: "the account is charged", "check
user.blockrun.ai/dashboard/activity". That dashboard has no record of an
on-chain transfer. The message now names the Solana wallet and
`blockrun_wallet action:"report"`.

## 0.52.3

### Fixed — 0.52.2's Solana image fix cut the paid submit off at 30s
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ claude mcp add blockrun -s user -- npx -y @blockrun/mcp@latest
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/context-cost-dark.svg">
<img src="assets/context-cost.svg" width="620" alt="Context cost: 13.0K tokens, 7% of a 200K context window, charged every turn whether or not you call a tool. 5.4K with --profile trading, 59% less.">
<img src="assets/context-cost.svg" width="620" alt="Context cost: 14.0K tokens, 7% of a 200K context window, charged every turn whether or not you call a tool. 5.4K with --profile trading, 61% less.">
</picture>
</div>

Expand Down Expand Up @@ -252,13 +252,13 @@ Package managers have shown install size for decades. Almost no MCP server shows

| Profile | Tools | Context |
|---------|-------|---------|
| `full` *(default)* | 19 | 13,044 |
| `full` *(default)* | 19 | 14,000 |
| `trading` | 8 | 5,411 |
| `media` | 7 | 5,828 |
| `media` | 7 | 6,784 |
| `research` | 5 | 2,752 |
| `chat` | 3 | 2,079 |

Running `--profile trading` instead of the default costs **59% less context** for the same trading
Running `--profile trading` instead of the default costs **61% less context** for the same trading
workflow. If you only ever ask about markets, that is the single cheapest change you can make.

Measure it yourself — against us, or against any other stdio MCP server:
Expand Down Expand Up @@ -371,7 +371,7 @@ npx -y @blockrun/mcp@latest skills install --to ~/.codex/skills
|------|-------------|------|
| `blockrun_chat` | <!-- br:models.chatVisible -->82<!-- /br:models.chatVisible --> LLMs (GPT, Claude, Gemini, DeepSeek, Kimi K3, GLM, NVIDIA free tier, …) with `mode` tier routing | per token |
| `blockrun_image` | Generate: openai/gpt-image-2, gpt-image-1, google/nano-banana(-2/-pro), xai/grok-imagine-image(-pro), zai/cogview-4, bytedance/seedream-5-pro. Edit: img2img, inpaint, fusion. | $0.015–0.15 |
| `blockrun_video` | Sora 2 + xAI Grok Imagine Video + ByteDance Seedance 1.5/2.0-mini/2.0-fast/2.0/2.5 (720p + audio; 4K on 2.0, up to 30s on 2.5); RealFace asset → real-person video | $0.053–0.32/sec charged |
| `blockrun_video` | Sora 2 + xAI Grok Imagine Video + ByteDance Seedance 1.5/2.0-mini/2.0-fast/2.0/2.5 (720p + audio; 4K on 2.0, up to 30s on 2.5); RealFace asset → real-person video; [reference images, video and audio](docs/seedance-capabilities.md) on the account rail | $0.053–0.32/sec charged; reference clips billed at a 15.2s ceiling |
| `blockrun_realface` | Enroll a real person (phone liveness) or AI character (Virtual Portrait) as a `ta_xxxx` asset for Seedance 2.0 / 2.0-fast / 2.0-mini video (not 2.5) | free; $0.01 to enroll |
| `blockrun_music` | MiniMax music generation | per track |
| `blockrun_speech` | ElevenLabs TTS (Flash/Turbo/Multilingual/v3, 8 voices) + ByteDance Seed Audio (prompt-directed) + cinematic sound effects; free voice listing | $0.05–0.10/1k chars |
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.52.3
0.53.0
6 changes: 3 additions & 3 deletions assets/context-cost-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions assets/context-cost.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 4 additions & 4 deletions docs/mcp-schema-overhead.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ Harness: [`scripts/measure-tool-schema.mjs`](../scripts/measure-tool-schema.mjs)
which fails the build when the README card disagrees with a live measurement.

Written 2026-09-01, verified against `@modelcontextprotocol/sdk` 1.29.0. Numbers re-measured
2026-09-09 at 0.49.0.
2026-09-26 for the Seedance video parameter expansion and its review pass.

## Our number

| Profile | Tools | Context |
|---------|-------|---------|
| `full` *(default)* | 19 | 13,044 |
| `full` *(default)* | 19 | 14,000 |
| `trading` | 8 | 5,411 |
| `media` | 7 | 5,828 |
| `media` | 7 | 6,784 |
| `research` | 5 | 2,752 |
| `chat` | 3 | 2,079 |

Descriptions are ~55% of it, input schemas ~40%. `--profile trading` costs 59% less than the
Descriptions are ~54% of it, input schemas ~42%. `--profile trading` costs 61% less than the
default for the same workflow.

These figures move with every description edit, so they are not the source of truth — the README
Expand Down
139 changes: 139 additions & 0 deletions docs/seedance-capabilities.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Seedance input and output capabilities

What `blockrun_video` accepts, which models take it, which RAIL serves it, and
what it costs. Written for this MCP server; the gateway's own request shapes,
the SDK field names and the deployment switches live in their own repos.

## Reference media is account-rail only

Reference inputs (`reference_image_urls`, `reference_videos`,
`reference_audios`) are served **only** by `api.blockrun.ai` — the account rail,
reached by setting `BLOCKRUN_API_KEY`.

Both wallet gateways refuse them with a `400` **before** issuing a quote
(blockrun#728, blockrun-sol#374; live-probed on `blockrun.ai` and
`sol.blockrun.ai` on 2026-09-26):

```
{"error":"reference media is not available on this gateway",
"message":"Seedance reference media (reference_image_urls) is served only by
api.blockrun.ai. ..."}
```

`blockrun_video` refuses them client-side on the wallet rails rather than
forwarding a request that cannot succeed, so no payment is taken and no DNS
lookup is spent on the reference URLs. Frame seeding (`image_url`,
`last_frame_url`) is unaffected and works on every rail.

## Supported combinations

| Model | First + last frame | Reference images | Reference video/audio |
| --- | --- | --- | --- |
| Seedance 1.5-pro | Yes | No | No |
| Seedance 2.0 / 2.0-fast / 2.0-mini | Yes | 1–9 | Image + video, image + audio, video + audio, or all three; 1–3 clips of each type |
| Seedance 2.5 | Yes | 1–30 | No |

Seedance 2.5 takes reference **images** but no reference clips — the gateway
registry carries `supportsReferenceImages: true` with
`supportsReferenceMedia: false` for it, and the tool's guard matches.

`image_url` means a first-frame seed. For a character or style image alongside
a reference video, use `reference_image_urls`, not `image_url`. Frame seeding
and reference mode are mutually exclusive. Reference audio on the 2.0 family
requires at least one reference image or video. Upstream duration, size and
content constraints still apply; accepting a URL does not verify the remote
file.

```json
{
"model": "bytedance/seedance-2.0-mini",
"prompt": "Use image 1 for the character and video 1 for the motion",
"duration_seconds": 5,
"reference_image_urls": ["https://example.com/character.png"],
"reference_videos": [{"url": "https://example.com/motion.mp4"}],
"return_last_frame": true
}
```

`input_type` is not a parameter of this tool. The gateway infers it from the
fields above, so there is nothing to declare; a clip `role` is likewise omitted,
since `"reference"` is the only value upstream honours.

## What reference media costs

Reference **clips** are billed **per reference second**, not per clip — measured
against token360 on 2026-09-23 (blockrun#730): a reference second costs what an
output second costs (~21,600 tokens against 21,780), with no per-clip
component. Audio counts at 0.3x video.

The caller sends a URL and never declares the clip's length, so the gateway
quotes **every clip at the model's 15.2s ceiling** and this tool reserves the
same. Consequences worth knowing before you call:

| Request | Reserved |
| --- | --- |
| seedance-2.0-mini, 5s output, no references | ~$0.40 |
| seedance-2.0-mini, 5s output, 1 reference video | ~$1.61 |
| seedance-2.0-mini, 4s output, 3 videos + 3 audios | ~$5.03 |
| seedance-2.0, 5s output, 3 videos + 3 audios | ~$14.54 |
| seedance-2.0, 5s output at **4K**, 3 videos + 3 audios | ~$130.88 |
| seedance-2.0-mini, 5s output at **480p**, 3 videos + 3 audios | ~$4.91 |

A single reference clip therefore costs more than the render it conditions —
roughly 4x a plain 5s 720p render, and about 24x for three videos plus three
audios at 480p, because the resolution discount reaches the render but not the
clip. The 4K row is not a typo: the clip term scales with output resolution
exactly as the gateway's does, so a 4K reference job genuinely reserves and
bills over a hundred dollars.
`bytedance/seedance-2.0-mini` takes the same reference inputs as
`bytedance/seedance-2.0` at roughly a third of the rate — prefer it unless you
need 4K.

Reference **images** carry no surcharge: the gateway's price formula takes
reference video and audio seconds only, and on Seedance the image-to-video and
text-to-video per-second rates are equal.

The account rail bills when the gateway **accepts** the job, and issues no 402,
so the reserve above is the only pre-payment control. Check
`blockrun_wallet action:"report"` before a large reference job.

## Additional output controls

| Field | Models | Values |
| --- | --- | --- |
| `bitrate_mode` | Seedance 2.x | `standard`, `high` |
| `output_format` | Seedance 2.5 | `mp4`, `mov` |
| `camera_fixed` | Seedance 1.5-pro | Boolean |
| `seed` | Seedance 1.5-pro | 0 – 2147483647 |
| `safety_identifier` | Seedance | Opaque end-user id, ≤128 chars — not a content filter, and not a place for personal data |
| `watermark` | Seedance | Boolean, default off |
| `return_last_frame` | Seedance | Boolean |

With `return_last_frame`, a completed response carries `last_frame_url` in both
the text output and `structuredContent`, plus `last_frame_backed_up` when the
gateway reports it. The frame uses the same storage backup semantics as the
video. An upstream that omits the frame produces no invented URL.

## Not in scope

Automatic duration (`-1`), 2.5 editing/extension task modes, 2.5 1080p,
draft/flex service tiers, callbacks, and task-list/cancel APIs are not exposed.
The first group needs verified cost/output bounds; the lifecycle features need
a separate ownership and settlement design.

A control this tool DOES declare but the chosen model does not support is
rejected before payment, naming the model and the field. A field the tool does
not declare at all — `callback_url`, `draft`, `service_tier` and the rest — is
stripped by schema validation before the handler sees it, so the job proceeds
without it rather than failing. Do not rely on one of those reaching the
gateway.

Reference-video/audio jobs are additionally subject to the gateway's own
`R2V_ENABLED` operational switch, which answers `503` when off. That is
deployment state this repo neither reads nor changes. Image-only references are
not subject to it.

New behaviour is covered by `test/video-reference-media.test.ts` (rail
availability, per-guard refusals, reserve arithmetic, SSRF across the arrays).
No paid upstream renders were performed; run a small paid smoke test before
relying on a new combination in production.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@blockrun/mcp",
"version": "0.52.3",
"version": "0.53.0",
"mcpName": "io.github.BlockRunAI/blockrun-mcp",
"description": "BlockRun MCP Server - Give your AI agent web search, deep research, prediction markets, and crypto data. Pay per call from a USDC wallet (Solana or Base) or a BlockRun API key.",
"type": "module",
Expand Down
9 changes: 9 additions & 0 deletions scripts/verify-prices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,15 @@ const PROBES: Probe[] = [
["bytedance/seedance-2.0-fast", undefined, "480p"],
["bytedance/seedance-2.5", undefined, "480p"],
["bytedance/seedance-2.0", undefined, "480p"],
// NOT probed here, and not probeable here: the reference-media surcharge.
// Both wallet gateways refuse reference_image_urls / reference_videos /
// reference_audios with a 400 before quoting (blockrun#728, sol#374), so
// this script — which only speaks to blockrun.ai and sol.blockrun.ai — can
// never see a 402 that carries it. The reference term in estimateVideoCost
// is pinned instead against the gateway's own arithmetic in
// test/video-reference-media.test.ts, whose constants come from the
// token360 measurement in blockrun#730. A green run here does NOT mean the
// surcharge was verified.
] as Array<[string, number | undefined, string | undefined, boolean?]>).map(([model, seconds, resolution, expectRefused]) => ({
label: `video ${model.split("/")[1]}${seconds ? ` ${seconds}s` : ""}${resolution ? ` ${resolution}` : ""}`,
path: "videos/generations",
Expand Down
Loading
Loading