@starreel/mcp 0.1.125 → 0.1.129
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.
- package/SKILL.md +2 -1
- package/dist/tools/produce.js +25 -0
- package/openapi.json +211 -2
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -91,7 +91,7 @@ announces a condensed version as MCP `instructions` at connect time.
|
|
|
91
91
|
| **No sample** — just an idea of the voice (a narrator, a character that deserves its own voice) | `design_voice` (one-sentence description, free) → `get_voice_design` until `done` (candidates arrive as local wav files — let the customer listen) → `save_designed_voice` (pick one; billed like a clone) → `set_character_voice` | generating every line straight from the description — each generation is a different person; naming a real person to imitate their voice |
|
|
92
92
|
| A song + lyrics | `create_drama` (`project_type: "mv"`) → `set_mv_lyrics` → `generate_mv_story` → `generate_mv_script` | `rewrite_script` (blocked for MV) |
|
|
93
93
|
| A product / brand | `create_drama` (`project_type: "ad"` or `"brand_film"`) → `add_product` → `generate_product_sheet` | writing brand copy as dialogue (it gets spoken) |
|
|
94
|
-
| Generated shots / a cut that needs changes | `scan_dialogue_coverage` / `scan_intra_shot_cuts` first, then `get_shot_prompts` · `update_shot` · `replace_shot_dialogue` · `repair_episode_dialogue` · `split_shot` · `trim_shot` · `regenerate_shot_video` · `edit_video_shot` → `rerender_episode`. To put **specific shots on a different video engine** in a whole-episode run, pass `shot_engines` (`{storyboard_id: engine}`) to `quote_videos` (a scene group that contains a picked shot is **split into per-shot generation** — listed in `shot_engines_ungrouped`; its other shots stay on the drama engine but lose the group's one-take continuity, so don't break a good group for one shot; a shot that already has a video is not re-run by the episode run, so picking an engine for it is rejected). Re-quoting after a partial run prices only the shots that will actually be dispatched (`shots_total`; already-finished ones are counted in `shots_already_done`, except that a scene group with any unfinished shot is re-run whole). To retry **one shot on a different video engine**, pass `model` to `quote_regenerate_shot_video` (that shot, that regeneration only — the drama's `video_engine` is untouched; the quote pins the engine, so changing it means re-quoting) | re-composing to fix what a clip *says*; switching the whole drama's `video_engine` just to fix one shot |
|
|
94
|
+
| Generated shots / a cut that needs changes | `scan_dialogue_coverage` / `scan_intra_shot_cuts` first, then `get_shot_prompts` · `update_shot` · `replace_shot_dialogue` · `repair_episode_dialogue` · `split_shot` · `trim_shot` · `regenerate_shot_video` · `edit_video_shot` → `rerender_episode`. To put **specific shots on a different video engine** in a whole-episode run, pass `shot_engines` (`{storyboard_id: engine}`) to `quote_videos` (a scene group that contains a picked shot is **split into per-shot generation** — listed in `shot_engines_ungrouped`; its other shots stay on the drama engine but lose the group's one-take continuity, so don't break a good group for one shot; a shot that already has a video is not re-run by the episode run, so picking an engine for it is rejected). Re-quoting after a partial run prices only the shots that will actually be dispatched (`shots_total`; already-finished ones are counted in `shots_already_done`, except that a scene group with any unfinished shot is re-run whole). To make a shot **always** use a different engine (single, batch and regen alike), set `video_engine` with `update_shot` (stored on the shot, shown in the web workbench; such a shot is never put in a scene group; explicit per-call parameters still win). To re-run **one scene group** (one request, keeps in-group continuity) — optionally on a different engine for that run — use `quote_regenerate_scene_group` (`shot_numbers` = exactly one group from `get_scene_group_plan`, optional `video_engine`; the whole group must fit that engine's single-clip limit) → `regenerate_scene_group`. To retry **one shot on a different video engine**, pass `model` to `quote_regenerate_shot_video` (that shot, that regeneration only — the drama's `video_engine` is untouched; the quote pins the engine, so changing it means re-quoting) | re-composing to fix what a clip *says*; switching the whole drama's `video_engine` just to fix one shot |
|
|
95
95
|
| Wants old portraits / sheets / a shot's old tail frame "deleted" | `set_character_portrait` (old assets listed in `old_assets`) · `clear_shot_frame` (old tail frame) → `regenerate_shot_video`; `list_unlinked_assets` lists the drama's unlinked old assets (a history list, not proof of ownership). Both only **unlink** — files are not deleted (`physically_deleted` is always empty; `in_history: false` means the platform kept no record, so save that URL if it matters). Tell the customer exactly that | telling the customer the old image was deleted; writing `last_frame_image: null` through the internal API |
|
|
96
96
|
| Wants an old image **permanently** deleted from storage (not just unlinked) | `preview_delete_asset` → show the customer exactly what it says (blocking references, history that will break, copies) → only after an explicit "confirm delete" → `delete_asset` with the `confirm_token`. Irreversible; only the drama owner; only files with trusted provenance (generated for this drama, or uploaded through the platform with a grant record) | deleting without showing the preview; retrying automatically; treating `list_unlinked_assets` as proof the file is unused |
|
|
97
97
|
| Cross-era drama (scenes in different periods) — checking props fit their period | `get_props` → read each prop's `era_audit` (`form_consistent`, `conflicting_scopes`, `violations`); `audit_prop_era` to re-check after a new sheet. On a conflict: `update_prop` with a precise `era_lock` (dynasty + physical form) → `generate_prop_sheet`, or bind a different prop to those shots. `run_precheck` also lists shots whose bound prop conflicts (`prop-era-conflict`) | trusting the prop's name or description alone; regenerating shot frames before the prop sheet is fixed |
|
|
@@ -1214,6 +1214,7 @@ Full reference: https://api.shortreelai.com/docs/mcp
|
|
|
1214
1214
|
- `ready` 和生成数量只表示产物存在;当前有效数量使用 `get_pipeline_status.asset_versions_summary.*.current_effective`。出图、出视频两步的 `status=done` 同样只表示已生成,旁边的 `validity` 拆出当前有效、生成后输入已变(`changed_by` 给出是哪类依赖变了)、无法判断、未审核、审核未过;`validity.note` 非空时先告知客户,再决定重出哪些镜,不要因输入变更就整集重出。换帧后旧视频仍可查看,但失效版本不能混入当前有效汇总。
|
|
1215
1215
|
- `get_asset_versions(storyboard_id)` 查看历史版本链接、依赖 ID/版本哈希及各自状态。历史没有快照时不从当前绑定伪造依赖。
|
|
1216
1216
|
- `get_image_dispatch(image_id)` 查一张镜头帧的派发台账:每张参考图的用途、所属角色、是否送达模型,派发前被剔的图在哪一步因什么被剔(如时代预检点名的冲突物件),以及最终发给模型的提示词。画面「不像某角色/少了某道具」时先查它,确认是参考没送到还是模型没画对,再决定改什么;`ledger` 不是 `full` 时缺失项为 `null`,不能当作已送达。
|
|
1217
|
+
- `get_frame_candidates(storyboard_id)` 一镜首帧/尾帧的全部候选(含被拒的原图):`adopted` 标出当前在用那张;`reject.class` 区分要改内容(`needs_content_fix`)、内容问题但可重掷(`content_retryable`)、审核没审成或偶发(`transient`,不是画面不合格);`audit.warnings` / `expected` / `derived_shot_type` / `boxes` 是审计证据(老候选为 `null`,不代表审过)。镜头反复被拒或客户问「被拒的长什么样」时先逐张看它,再决定改分镜、改参考还是重掷。
|
|
1217
1218
|
- `get_stale_portrait_frames(episode_id)` 换定妆图后查影响范围:列出在用帧仍基于角色旧资产的镜头,每条附证据(`ledger-old-asset` / `references-previous-asset` / `portrait-born-after-frame`)。`unknown` 是证据不足,不是已过期,不要据此批量重出。先把 `stale` 清单和 `has_video` 告诉客户,由客户决定重出哪些镜——重出帧和视频都要付费。
|
|
1218
1219
|
- `get_asset_binding_repair_plan(episode_id)` 只返回缺失场景绑定的候选和依据,`applied=false`。必须逐项审核,不按名字自动回填,也不自动重新生成客户已完成的片子。
|
|
1219
1220
|
|
package/dist/tools/produce.js
CHANGED
|
@@ -530,6 +530,11 @@ export function registerProduceTools(server, client) {
|
|
|
530
530
|
})));
|
|
531
531
|
server.tool('get_frame_retry_diagnosis', '免费只读查询图片任务的连败诊断、证据任务 ID 和下一步动作。diagnosis_required 时先调用本工具:审计故障重审已有候选,未知原因先复核;不得原样重抽或擅自改剧本。', { image_id: z.number().int().positive() }, async ({ image_id }) => jsonResult(await client.produceGet(`/images/${image_id}/diagnosis`)));
|
|
532
532
|
server.tool('get_image_dispatch', '免费只读查询一张镜头帧的派发台账:实际用了哪几张参考图、每张的用途与所属角色、是否送达模型、没送达或派发前被剔除的是哪一步因什么被剔(如时代预检点名的冲突物件),以及真正发给图片模型的最终提示词。用于回答「到底用了哪张图、为什么画面不像」;先查清再决定是否重出,别靠猜反复付费重抽。ledger=partial/none 表示该图生成于台账上线前,缺失字段如实为 null。', { image_id: z.number().int().positive() }, async ({ image_id }) => jsonResult(await client.produceGet(`/images/${image_id}/dispatch`)));
|
|
533
|
+
server.tool('get_frame_candidates', '免费只读:一个镜头首帧/尾帧的**全部候选**(出图验收工作台同一份数据)。每张候选给原图地址(被拒的也在,可直接打开看原尺寸)、状态、是否为当前在用(adopted)、' +
|
|
534
|
+
'拒因 reject(main 主码 / code 具体病因 / details 明细 / class 分流:needs_content_fix=要改内容、content_retryable=内容问题但重掷约 1/3 能成、transient=审核没审成或偶发——不是画面不合格)、' +
|
|
535
|
+
'审计证据 audit(warnings 中文结论、expected 设计要求、derived_shot_type 画面推出的景别及依据、boxes 主体与身体部位在画面里的位置框;2026-10-07 前的候选无存档为 null,不代表审过)、' +
|
|
536
|
+
'以及这张图实际用了哪些参考图(references:用途/所属角色/是否送达)。storyboard.tail_endstate 是「尾帧≈首帧」检查结论(current=false 表示结论对应的不是现在这两张图)。' +
|
|
537
|
+
'★镜头反复被拒、或客户问「被拒的那几张到底什么样 / 为什么不采用」时先调它:逐张看原图和证据,再决定改分镜、改参考还是重掷——别盲目付费重抽。要看某张的最终提示词用 get_image_dispatch(generation_id)。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/frame-workbench`)));
|
|
533
538
|
server.tool('get_stale_portrait_frames', '免费只读查询一集里哪些镜头的在用首帧/尾帧,是拿角色已被换掉的旧资产(旧定妆图、旧设定图、旧身体/发型图)画的。换定妆图后用它确认影响范围,再由客户决定重出哪些镜(重出要付费,本工具不改任何数据)。verdict=stale 必附证据:ledger-old-asset(派发台账直接记录用了旧图)/ references-previous-asset(参考图里有该角色以前的旧资产)/ portrait-born-after-frame(当前定妆图晚于该帧诞生);证不了的标 unknown 并给原因,不当作已过期。has_video=true 表示该镜视频也基于旧帧,重出帧后视频需重生。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/stale-portrait-frames`)));
|
|
534
539
|
server.tool('get_asset_versions', '只读查询一个镜头的全部图片/视频版本、历史查看链接、依赖 ID 与版本哈希,以及已生成→与当前输入一致→审核有效→已采用四项独立事实。历史缺少依赖记录时显示未知,不补造快照。免费。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/asset-versions`)));
|
|
535
540
|
server.tool('get_asset_binding_repair_plan', '只读生成一集历史缺失场景绑定的可审核修复提案。返回原始地点/时段、候选 ID、匹配依据、歧义和 proposed_scene_id;applied=false,绝不按名字自动回填。逐项核对后才由客户决定是否改绑。免费。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/asset-binding-repair-plan`)));
|
|
@@ -1380,6 +1385,10 @@ export function registerProduceTools(server, client) {
|
|
|
1380
1385
|
shot_intent: z.string().optional().describe('这镜为什么存在(叙事意图)'),
|
|
1381
1386
|
duration: z.number().positive().optional().describe('本镜时长(秒,可带小数如 2.5)。上限=本剧视频引擎的单镜上限,超出直接拒并告知上限(更长内容用 split_shot 拆镜)。有台词时平台按语速律只抬不降,抬了会在回执 speech_duration_note 里说。★改时长不会自动重出视频:已有视频仍是旧长度,要厂商按新时长出就 regenerate_shot_video(报价按新时长算)。★别拿加长治「动作太慢」——同样的动作摊到更长时间里只会更慢,见 qa_tools「动作太慢」'),
|
|
1382
1387
|
speed_factor: z.number().positive().nullable().optional().describe('成片变速:<1 慢镜、>1 快放、null 清除(0.5–2.0,越界被钳到范围内)。只在终拼/剪映导出时变速播放(画面 setpts + 声音 atempo,音高不变),**不重出视频、不扣费**,但会改变本镜在成片里占的时长。适合做慢镜/升格氛围;治不了「动作没演出来」——那是视频内容本身,要改 video_prompt 重出;也治不了一镜塞太多动作(action_overload)——那要拆镜重出。有台词的镜慎用(人声也跟着变快变慢)'),
|
|
1388
|
+
video_engine: z.enum(VIDEO_ENGINES).nullable().optional().describe('本镜视频引擎(**存为镜头设置**,之后这一镜的单镜出视频 / 整集批量 / 重生都按它;null 清除=跟随剧 video_engine)。' +
|
|
1389
|
+
'与整剧的区别:只改这一镜。设了引擎的镜**不进场景组**(组的规划按剧引擎做),会单独出,失去与相邻镜一次成片的连贯性——别为个别镜随手设。' +
|
|
1390
|
+
'须支持本剧分辨率(seedance-2.5 只有 480p/720p;hailuo-3 只有 720p/1080p)且容得下本镜时长(seedance-2.5/wan3.0 30s,hailuo-3 15s),否则 400。' +
|
|
1391
|
+
'只想这一次换引擎、不留设置:用 quote_regenerate_shot_video 的 model 或 quote_videos 的 shot_engines(显式参数优先于镜头设置)。get_storyboards 回读 video_engine。'),
|
|
1383
1392
|
image_prompt: z.string().optional().describe('首帧画面提示词**正文**(全量覆盖本镜现值)。★先 get_shot_prompts 读现值再改;★原样保留其中的 @char:N / @scene:M 补充参考标记(注入谁由 character_ids / scene_id 决定,删标记不会让已绑定的人消失)。出图时平台会在正文之上再拼身份锚与一致性约束,不必你写。★写法坑:别写「no X / without X / 不要 X / 没有 X」这类否定式约束——图像模型把名词当正向线索,反而把 X 画出来;要正向写出那块画面该有什么(材质/形状/颜色/远近)。保存响应带 image_prompt_negation_advisory 即命中,按其 note 改写'),
|
|
1384
1393
|
video_prompt: z.string().optional().describe('视频(动态/运镜/表演)提示词**正文**(全量覆盖本镜现值)。★同 image_prompt:先读现值、保留 @char/@scene 标记'),
|
|
1385
1394
|
first_frame_prompt: z.string().optional().describe('本镜**开始时**画面是什么样(首帧目标状态正文,全量覆盖现值)。送达提示词里作为 [START FRAME] 段排在最前,优先级高于 image_prompt——所以 image_prompt 改了不生效时,往往是这条在压着它。★同 image_prompt:先 get_shot_prompts 读现值、原样保留 @char/@scene 标记'),
|
|
@@ -1788,6 +1797,22 @@ export function registerProduceTools(server, client) {
|
|
|
1788
1797
|
quote_id: z.string().describe('来自 quote_align_prev_shot'),
|
|
1789
1798
|
}, async ({ storyboard_id, quote_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/align-prev`, { quote_id })));
|
|
1790
1799
|
server.tool('get_scene_group_plan', '查某一集的场景组规划(镜头如何归组做连续长镜)。免费。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/scene-group-plan`)));
|
|
1800
|
+
server.tool('quote_regenerate_scene_group', '报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点。返回 quote_id。零扣费。' +
|
|
1801
|
+
'shot_numbers 必须正好等于 get_scene_group_plan 里某一组的镜号。' +
|
|
1802
|
+
'\n★可选 video_engine:只为这一次整组重出换引擎(不改剧级 video_engine);报价按它计、quote_id 钉死,regenerate_scene_group 派发的就是它。' +
|
|
1803
|
+
'整组仍一次成片,所以整组总时长必须在该引擎单段上限内(hailuo-3 15s;seedance-2.5/wan3.0 30s)且支持本剧分辨率,否则 400——' +
|
|
1804
|
+
'那种情况改用 update_shot 给个别镜设 video_engine(设了的镜会单独出)。' +
|
|
1805
|
+
'报价按逐镜计(整组失败会逐镜兜底,逐镜是上界),正常路径实扣通常更低。', {
|
|
1806
|
+
episode_id: z.number().int().positive(),
|
|
1807
|
+
shot_numbers: z.array(z.number().int().positive()).min(1).describe('这一组的镜号(storyboard_number,见 get_scene_group_plan)'),
|
|
1808
|
+
video_engine: z.enum(VIDEO_ENGINES).optional().describe('本次整组重出的引擎(缺省=跟随剧 video_engine)'),
|
|
1809
|
+
}, async ({ episode_id, shot_numbers, video_engine }) => jsonResult(await client.producePost(`/episodes/${episode_id}/scene-groups/regenerate/quote`, { shot_numbers, ...(video_engine ? { video_engine } : {}) })));
|
|
1810
|
+
server.tool('regenerate_scene_group', '确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)。' +
|
|
1811
|
+
'分组、引擎都由 quote_id 钉死,这里不能改;报价后组内任一镜被改、或分组变了,quote 作废(409),重新报价即可(免费)。' +
|
|
1812
|
+
CONFIRM_HINT, {
|
|
1813
|
+
episode_id: z.number().int().positive(),
|
|
1814
|
+
quote_id: z.string().describe('来自 quote_regenerate_scene_group'),
|
|
1815
|
+
}, async ({ episode_id, quote_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/scene-groups/regenerate`, { quote_id })));
|
|
1791
1816
|
server.tool('generate_scene_groups', '生成场景组(把连续镜头归组,连续长镜/批量出图的地基)。后台异步。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/scene-groups`)));
|
|
1792
1817
|
server.tool('render_multi_aspect', '把成片按多个画幅(竖/横/方)重渲一版,便于多平台分发。免费(纯 ffmpeg),后台异步。', {
|
|
1793
1818
|
episode_id: z.number().int().positive(),
|
package/openapi.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "StarReel Production API",
|
|
5
|
-
"version": "0.1.
|
|
6
|
-
"description": "Turn a script into a finished, downloadable short-drama episode over REST.\n\nPipeline: script → AI rewrite → cast/scenes/props extraction → storyboards → portraits & sheets + scene plates → keyframes → video shots → TTS → final cut (.mp4).\n\n**Billing is prepaid and agent-safe**: big-ticket stages are quote-then-generate (`quote_*` returns a `quote_id`). For video, quote == actual charge. For images the quote is a *range* — models billed per reference image are priced before those are assembled, so `estimated_points` is the upper bound (size the balance by it and a run never dies half-way) and `typical_points` is the usual cost; fixed-price models return the two equal. Insufficient balance returns 402 — nothing half-runs and the account never goes negative.\n\nAuth: exchange your API key at `POST /v1/agent/token` for a 15-minute bearer token.\n\nGenerated from the @starreel/mcp v0.1.
|
|
5
|
+
"version": "0.1.129",
|
|
6
|
+
"description": "Turn a script into a finished, downloadable short-drama episode over REST.\n\nPipeline: script → AI rewrite → cast/scenes/props extraction → storyboards → portraits & sheets + scene plates → keyframes → video shots → TTS → final cut (.mp4).\n\n**Billing is prepaid and agent-safe**: big-ticket stages are quote-then-generate (`quote_*` returns a `quote_id`). For video, quote == actual charge. For images the quote is a *range* — models billed per reference image are priced before those are assembled, so `estimated_points` is the upper bound (size the balance by it and a run never dies half-way) and `typical_points` is the usual cost; fixed-price models return the two equal. Insufficient balance returns 402 — nothing half-runs and the account never goes negative.\n\nAuth: exchange your API key at `POST /v1/agent/token` for a 15-minute bearer token.\n\nGenerated from the @starreel/mcp v0.1.129 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -6785,6 +6785,152 @@
|
|
|
6785
6785
|
}
|
|
6786
6786
|
}
|
|
6787
6787
|
},
|
|
6788
|
+
"/episodes/{episode_id}/scene-groups/regenerate": {
|
|
6789
|
+
"post": {
|
|
6790
|
+
"operationId": "regenerate_scene_group",
|
|
6791
|
+
"summary": "确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)",
|
|
6792
|
+
"description": "确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)。分组、引擎都由 quote_id 钉死,这里不能改;报价后组内任一镜被改、或分组变了,quote 作废(409),重新报价即可(免费)。⚠️ 批量报价确认流程:先调对应的 quote_* 工具,把返回的 estimated_points 原样告诉用户,用户明确同意后,才用返回的 quote_id 调本工具。不要擅自确认。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
6793
|
+
"tags": [
|
|
6794
|
+
"episodes"
|
|
6795
|
+
],
|
|
6796
|
+
"parameters": [
|
|
6797
|
+
{
|
|
6798
|
+
"name": "episode_id",
|
|
6799
|
+
"in": "path",
|
|
6800
|
+
"required": true,
|
|
6801
|
+
"schema": {
|
|
6802
|
+
"type": "integer",
|
|
6803
|
+
"exclusiveMinimum": 0
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6806
|
+
],
|
|
6807
|
+
"requestBody": {
|
|
6808
|
+
"required": true,
|
|
6809
|
+
"content": {
|
|
6810
|
+
"application/json": {
|
|
6811
|
+
"schema": {
|
|
6812
|
+
"type": "object",
|
|
6813
|
+
"properties": {
|
|
6814
|
+
"quote_id": {
|
|
6815
|
+
"type": "string",
|
|
6816
|
+
"description": "来自 quote_regenerate_scene_group"
|
|
6817
|
+
}
|
|
6818
|
+
},
|
|
6819
|
+
"required": [
|
|
6820
|
+
"quote_id"
|
|
6821
|
+
]
|
|
6822
|
+
}
|
|
6823
|
+
}
|
|
6824
|
+
}
|
|
6825
|
+
},
|
|
6826
|
+
"responses": {
|
|
6827
|
+
"200": {
|
|
6828
|
+
"description": "StarReel envelope",
|
|
6829
|
+
"content": {
|
|
6830
|
+
"application/json": {
|
|
6831
|
+
"schema": {
|
|
6832
|
+
"type": "object",
|
|
6833
|
+
"properties": {
|
|
6834
|
+
"code": {
|
|
6835
|
+
"type": "integer"
|
|
6836
|
+
},
|
|
6837
|
+
"message": {
|
|
6838
|
+
"type": "string"
|
|
6839
|
+
},
|
|
6840
|
+
"data": {
|
|
6841
|
+
"description": "Operation result payload"
|
|
6842
|
+
}
|
|
6843
|
+
}
|
|
6844
|
+
}
|
|
6845
|
+
}
|
|
6846
|
+
}
|
|
6847
|
+
},
|
|
6848
|
+
"402": {
|
|
6849
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
6850
|
+
}
|
|
6851
|
+
}
|
|
6852
|
+
}
|
|
6853
|
+
},
|
|
6854
|
+
"/episodes/{episode_id}/scene-groups/regenerate/quote": {
|
|
6855
|
+
"post": {
|
|
6856
|
+
"operationId": "quote_regenerate_scene_group",
|
|
6857
|
+
"summary": "报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点",
|
|
6858
|
+
"description": "报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点。返回 quote_id。零扣费。shot_numbers 必须正好等于 get_scene_group_plan 里某一组的镜号。\n★可选 video_engine:只为这一次整组重出换引擎(不改剧级 video_engine);报价按它计、quote_id 钉死,regenerate_scene_group 派发的就是它。整组仍一次成片,所以整组总时长必须在该引擎单段上限内(hailuo-3 15s;seedance-2.5/wan3.0 30s)且支持本剧分辨率,否则 400——那种情况改用 update_shot 给个别镜设 video_engine(设了的镜会单独出)。报价按逐镜计(整组失败会逐镜兜底,逐镜是上界),正常路径实扣通常更低。",
|
|
6859
|
+
"tags": [
|
|
6860
|
+
"episodes"
|
|
6861
|
+
],
|
|
6862
|
+
"parameters": [
|
|
6863
|
+
{
|
|
6864
|
+
"name": "episode_id",
|
|
6865
|
+
"in": "path",
|
|
6866
|
+
"required": true,
|
|
6867
|
+
"schema": {
|
|
6868
|
+
"type": "integer",
|
|
6869
|
+
"exclusiveMinimum": 0
|
|
6870
|
+
}
|
|
6871
|
+
}
|
|
6872
|
+
],
|
|
6873
|
+
"requestBody": {
|
|
6874
|
+
"required": true,
|
|
6875
|
+
"content": {
|
|
6876
|
+
"application/json": {
|
|
6877
|
+
"schema": {
|
|
6878
|
+
"type": "object",
|
|
6879
|
+
"properties": {
|
|
6880
|
+
"shot_numbers": {
|
|
6881
|
+
"type": "array",
|
|
6882
|
+
"items": {
|
|
6883
|
+
"type": "integer",
|
|
6884
|
+
"exclusiveMinimum": 0
|
|
6885
|
+
},
|
|
6886
|
+
"minItems": 1,
|
|
6887
|
+
"description": "这一组的镜号(storyboard_number,见 get_scene_group_plan)"
|
|
6888
|
+
},
|
|
6889
|
+
"video_engine": {
|
|
6890
|
+
"type": "string",
|
|
6891
|
+
"enum": [
|
|
6892
|
+
"seedance-2.5",
|
|
6893
|
+
"hailuo-3",
|
|
6894
|
+
"wan3.0",
|
|
6895
|
+
"wan3.0-prime"
|
|
6896
|
+
]
|
|
6897
|
+
}
|
|
6898
|
+
},
|
|
6899
|
+
"required": [
|
|
6900
|
+
"shot_numbers"
|
|
6901
|
+
]
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
},
|
|
6906
|
+
"responses": {
|
|
6907
|
+
"200": {
|
|
6908
|
+
"description": "StarReel envelope",
|
|
6909
|
+
"content": {
|
|
6910
|
+
"application/json": {
|
|
6911
|
+
"schema": {
|
|
6912
|
+
"type": "object",
|
|
6913
|
+
"properties": {
|
|
6914
|
+
"code": {
|
|
6915
|
+
"type": "integer"
|
|
6916
|
+
},
|
|
6917
|
+
"message": {
|
|
6918
|
+
"type": "string"
|
|
6919
|
+
},
|
|
6920
|
+
"data": {
|
|
6921
|
+
"description": "Operation result payload"
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
},
|
|
6928
|
+
"402": {
|
|
6929
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
}
|
|
6933
|
+
},
|
|
6788
6934
|
"/episodes/{episode_id}/scenes": {
|
|
6789
6935
|
"get": {
|
|
6790
6936
|
"operationId": "get_scenes",
|
|
@@ -10005,6 +10151,22 @@
|
|
|
10005
10151
|
}
|
|
10006
10152
|
]
|
|
10007
10153
|
},
|
|
10154
|
+
"video_engine": {
|
|
10155
|
+
"anyOf": [
|
|
10156
|
+
{
|
|
10157
|
+
"type": "string",
|
|
10158
|
+
"enum": [
|
|
10159
|
+
"seedance-2.5",
|
|
10160
|
+
"hailuo-3",
|
|
10161
|
+
"wan3.0",
|
|
10162
|
+
"wan3.0-prime"
|
|
10163
|
+
]
|
|
10164
|
+
},
|
|
10165
|
+
{
|
|
10166
|
+
"type": "null"
|
|
10167
|
+
}
|
|
10168
|
+
]
|
|
10169
|
+
},
|
|
10008
10170
|
"image_prompt": {
|
|
10009
10171
|
"type": "string"
|
|
10010
10172
|
},
|
|
@@ -10692,6 +10854,53 @@
|
|
|
10692
10854
|
}
|
|
10693
10855
|
}
|
|
10694
10856
|
},
|
|
10857
|
+
"/storyboards/{storyboard_id}/frame-workbench": {
|
|
10858
|
+
"get": {
|
|
10859
|
+
"operationId": "get_frame_candidates",
|
|
10860
|
+
"summary": "免费只读:一个镜头首帧/尾帧的**全部候选**(出图验收工作台同一份数据)",
|
|
10861
|
+
"description": "免费只读:一个镜头首帧/尾帧的**全部候选**(出图验收工作台同一份数据)。每张候选给原图地址(被拒的也在,可直接打开看原尺寸)、状态、是否为当前在用(adopted)、拒因 reject(main 主码 / code 具体病因 / details 明细 / class 分流:needs_content_fix=要改内容、content_retryable=内容问题但重掷约 1/3 能成、transient=审核没审成或偶发——不是画面不合格)、审计证据 audit(warnings 中文结论、expected 设计要求、derived_shot_type 画面推出的景别及依据、boxes 主体与身体部位在画面里的位置框;2026-10-07 前的候选无存档为 null,不代表审过)、以及这张图实际用了哪些参考图(references:用途/所属角色/是否送达)。storyboard.tail_endstate 是「尾帧≈首帧」检查结论(current=false 表示结论对应的不是现在这两张图)。★镜头反复被拒、或客户问「被拒的那几张到底什么样 / 为什么不采用」时先调它:逐张看原图和证据,再决定改分镜、改参考还是重掷——别盲目付费重抽。要看某张的最终提示词用 get_image_dispatch(generation_id)。",
|
|
10862
|
+
"tags": [
|
|
10863
|
+
"storyboards"
|
|
10864
|
+
],
|
|
10865
|
+
"parameters": [
|
|
10866
|
+
{
|
|
10867
|
+
"name": "storyboard_id",
|
|
10868
|
+
"in": "path",
|
|
10869
|
+
"required": true,
|
|
10870
|
+
"schema": {
|
|
10871
|
+
"type": "integer",
|
|
10872
|
+
"exclusiveMinimum": 0
|
|
10873
|
+
}
|
|
10874
|
+
}
|
|
10875
|
+
],
|
|
10876
|
+
"responses": {
|
|
10877
|
+
"200": {
|
|
10878
|
+
"description": "StarReel envelope",
|
|
10879
|
+
"content": {
|
|
10880
|
+
"application/json": {
|
|
10881
|
+
"schema": {
|
|
10882
|
+
"type": "object",
|
|
10883
|
+
"properties": {
|
|
10884
|
+
"code": {
|
|
10885
|
+
"type": "integer"
|
|
10886
|
+
},
|
|
10887
|
+
"message": {
|
|
10888
|
+
"type": "string"
|
|
10889
|
+
},
|
|
10890
|
+
"data": {
|
|
10891
|
+
"description": "Operation result payload"
|
|
10892
|
+
}
|
|
10893
|
+
}
|
|
10894
|
+
}
|
|
10895
|
+
}
|
|
10896
|
+
}
|
|
10897
|
+
},
|
|
10898
|
+
"402": {
|
|
10899
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
10900
|
+
}
|
|
10901
|
+
}
|
|
10902
|
+
}
|
|
10903
|
+
},
|
|
10695
10904
|
"/storyboards/{storyboard_id}/frame/clear": {
|
|
10696
10905
|
"post": {
|
|
10697
10906
|
"operationId": "clear_shot_frame",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.129",
|
|
4
4
|
"mcpName": "ai.starreel/starreel",
|
|
5
5
|
"description": "StarReel MCP server — drive the AI short-drama production pipeline (script → storyboards → frames → video → final cut) from Claude, Cursor, or any MCP client",
|
|
6
6
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
|
|
3
3
|
"name": "ai.starreel/starreel",
|
|
4
4
|
"description": "Turn a script into a finished, downloadable short-drama episode — via MCP or REST.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.129",
|
|
6
6
|
"websiteUrl": "https://starreel.ai",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "@starreel/mcp",
|
|
11
|
-
"version": "0.1.
|
|
11
|
+
"version": "0.1.129",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|