@starreel/mcp 0.1.104 → 0.1.106

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 CHANGED
@@ -121,6 +121,17 @@ Don't ask the user at every step. Sort work into three tiers:
121
121
  `video_style_prompt`) are all free and the foundation that steers every later
122
122
  generation. Set them up front via `create_drama` / `update_project_settings`
123
123
  — don't build an empty shell, or all downstream generation drifts.
124
+ **Honor explicit creative requirements.** `creative_contract` on
125
+ `create_drama` / `update_project_settings` accepts `version: 1`, optional
126
+ `speech` (`unspecified` / `forbidden` / `required`), `music`
127
+ (`unspecified` / `forbidden`), and `pacing` (`unspecified` / `quiet`).
128
+ Set these only from the customer's explicit choice, never infer them from
129
+ genre. Omission preserves settings; `null` clears; an object replaces the
130
+ whole contract. Forbidden speech covers dialogue, narration and singing;
131
+ environmental/action sounds remain allowed. Forbidden music applies to
132
+ video output and final composition; customers may still generate, save and
133
+ select music assets. Music already mixed into native clip audio needs
134
+ separate handling. Quiet pacing suppresses generic climax/valley advice.
124
135
  **Set the structured era contract for anything non-contemporary.**
125
136
  `setting_brief` is free text: it supplies background but cannot hold the
126
137
  frame. The one mechanism that outranks the visual lock is the structured
@@ -477,7 +488,14 @@ content that will be rejected.
477
488
  storyboards; `get_characters` after portraits to confirm every on-screen
478
489
  character has an image and a sheet; `get_storyboards` after frames and after
479
490
  videos to read `frame_status` / `video_status` / `fail_reason` / `fail_hint`
480
- and fix failed shots before moving on; `get_pipeline_status` before the
491
+ and fix failed shots before moving on. `video_status=ready` means generation
492
+ finished, not visual acceptance. Read `video_quality_issues`: `terminal_cut`
493
+ with `suspected` blocks automatic tail promotion and chaining for that result;
494
+ `unavailable` means the check failed, not that a defect was confirmed. A missing
495
+ issue does not prove a scan happened. `scan_intra_shot_cuts` also reports
496
+ `shots_with_terminal_cuts` and `detail.terminal_cut`, including individual
497
+ clips split from a group. Review the footage before any paid regeneration.
498
+ Use `get_pipeline_status` before the
481
499
  final cut to confirm no shot is missing. `review_all` gives a whole-episode
482
500
  checkup at any time (it issues no token — the gates want a review of the
483
501
  *current* artifact).
@@ -1112,3 +1130,10 @@ to close") tells the vendor to fit that entire sequence into each 3-second shot.
1112
1130
  outside the kept window)
1113
1131
 
1114
1132
  Full reference: https://api.shortreelai.com/docs/mcp
1133
+
1134
+ ### 资产引用与版本有效性
1135
+
1136
+ - `get_storyboards.asset_versions` 对首帧、尾帧和视频分别返回四项事实:`generated`(已生成)、`input_consistent`(与当前输入一致)、`review_valid`(审核有效)、`adopted`(已采用)。`null` 表示证据不足,不能当作 true。
1137
+ - `ready` 和生成数量只表示产物存在;当前有效数量使用 `get_pipeline_status.asset_versions_summary.*.current_effective`。换帧后旧视频仍可查看,但失效版本不能混入当前有效汇总。
1138
+ - `get_asset_versions(storyboard_id)` 查看历史版本链接、依赖 ID/版本哈希及各自状态。历史没有快照时不从当前绑定伪造依赖。
1139
+ - `get_asset_binding_repair_plan(episode_id)` 只返回缺失场景绑定的候选和依据,`applied=false`。必须逐项审核,不按名字自动回填,也不自动重新生成客户已完成的片子。
@@ -221,6 +221,12 @@ const VIDEO_ENGINES = ['seedance-2.5', 'hailuo-3', 'wan3.0', 'wan3.0-prime'];
221
221
  // 后端内部 PUT /dramas 已接受写库,facade 白名单 Wave3 已放行(produce-create-fields.ts)。
222
222
  // 不含内部产线/成本开关(strict_mode/best_of_n/shoppable/budget_points 等,需产品决策)。
223
223
  const PROJECT_SETTINGS_FIELDS = {
224
+ creative_contract: z.object({
225
+ version: z.literal(1),
226
+ speech: z.enum(['unspecified', 'forbidden', 'required']).optional(),
227
+ music: z.enum(['unspecified', 'forbidden']).optional(),
228
+ pacing: z.enum(['unspecified', 'quiet']).optional(),
229
+ }).strict().nullable().optional().describe('客户明确创作约束:speech=forbidden 禁止对白/旁白/演唱,music=forbidden 仅禁止本片输出混入配乐(允许生成/保存/选择音乐素材),pacing=quiet 保持平静节奏。不推断;整对象替换,null 清除,省略保持。环境声/音效不受禁止人声影响。'),
224
230
  // drama 级图片模型(整剧统一画风):默认 ChatGPT Image 2.5 Flare(v0.9.1558)
225
231
  image_model: z.string().optional().describe('图片模型(★drama级·整剧统一画风·默认 ChatGPT Image 2.5 Flare)。可选:' +
226
232
  'gpt-image-2.5-flare(默认·基础11点+每张参考图18点)/gpt-image-2.5-sunburst(同价·中文字形与细节更准·慢约5秒)/' +
@@ -479,6 +485,7 @@ export function registerProduceTools(server, client) {
479
485
  // ---------- 完整工作流进度 ----------
480
486
  server.tool('get_pipeline_status', '查某一集完整工作流的进度(script_rewrite/提取/分镜/语音/出图/出视频/合成/配乐/终拼…各步 ' +
481
487
  'done/partial/pending/not_required)。照它按序推进、不跳步。免费。' +
488
+ 'asset_versions_summary 将 generated、input_consistent、review_valid、adopted 和 current_effective 分开计数;不能把 generate_videos.completed 当当前有效数量。' +
482
489
  '★not_required=当前模式不需要该步(如原声剧的 TTS 三步、关配乐的 generate_bgm),不是没做完,别去补做。' +
483
490
  '图片/视频分母已剔除卡镜(shots_not_applicable);merge_episode.bgm_stale=true 表示配乐晚于成片,重新 compose_episode 即可。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/pipeline-status`)));
484
491
  // ---------- 角色定妆图(一致性锚) ----------
@@ -518,13 +525,19 @@ export function registerProduceTools(server, client) {
518
525
  }, async ({ episode_id, quote_id, confirm_replace, review_token, acknowledge_review }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/generate`, {
519
526
  quote_id, review_token, acknowledge_review, ...(confirm_replace ? { confirm_replace } : {}),
520
527
  })));
528
+ server.tool('get_asset_versions', '只读查询一个镜头的全部图片/视频版本、历史查看链接、依赖 ID 与版本哈希,以及已生成→与当前输入一致→审核有效→已采用四项独立事实。历史缺少依赖记录时显示未知,不补造快照。免费。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/asset-versions`)));
529
+ 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`)));
521
530
  server.tool('get_storyboards', '读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。' +
531
+ 'asset_versions 按首帧/尾帧/视频分别给出 generated(已生成)、input_consistent(与当前输入一致)、review_valid(审核有效)、adopted(已采用)、current_effective(当前有效)。null=缺少证据;ready 只表示存在产物,不代表当前有效。旧素材仍可查看。' +
522
532
  '★每镜带**台词与说话人**:dialogue(原文,无台词为 null)、dialogue_lines([{speaker,text}] 逐行,' +
523
533
  '与字幕/配音同一个解析器拆的——这里的 speaker 就是成片里被配音的那个;舞台提示已剥),' +
524
534
  '以及 is_key_moment(1=关键镜,走高端图模)与 emotion_intensity(1-10)。' +
525
535
  '核对「台词有没有丢/谁说的/关键镜是哪几镜/情绪曲线」用这一次调用即可,不用逐镜拉;update_shot 改完台词也在这里核对。' +
526
536
  '画面/视频/首尾帧提示词仍只在 get_shot_prompts 逐镜读。' +
527
537
  '★每镜还带**结构化状态**:frame_status/video_status(ready/pending/authorizing/rejected/failed/none/not_required)、' +
538
+ '★video_status=ready 只表示视频已生成,不等于画面验收通过。video_quality_issues 若含 terminal_cut:' +
539
+ 'status=suspected 表示片尾疑似短促切镜,cut_at_s/tail_duration_s 给出位置;status=unavailable 表示探测未完成,不能当检测通过。' +
540
+ '两者均暂停本次自动尾帧回写与续接,先复核视频;字段缺席不代表做过检测,也不要直接重试收费生成。' +
528
541
  '★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。' +
529
542
  'fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/' +
530
543
  'insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。' +
@@ -1195,12 +1208,12 @@ export function registerProduceTools(server, client) {
1195
1208
  server.tool('scan_intra_shot_cuts', '★客户报「镜头切太快 / 一个镜头里画面跳来跳去」时先跑这个。免费零扣费。'
1196
1209
  + '一个分镜本应是**一个连续镜头**,但厂商可能在片内自行换机位硬切(望远镜特写→高空全景→人物中景),'
1197
1210
  + '这类切点在分镜表和 timeline 里都看不到——只能扫画面。'
1198
- + '返回 shots_with_cuts(有镜内跳切的镜号)/total_cuts/engine_suspect/message。'
1211
+ + '返回 shots_with_cuts(有镜内跳切的镜号)/total_cuts/engine_suspect/message;shots_with_terminal_cuts 单列疑似短促片尾切镜,detail.terminal_cut 给出位置和状态。'
1199
1212
  + '★判读:成片观感切点 = 镜与镜的接缝 + 这里报的镜内跳切;若本项占了大头,那不是剪辑节奏问题,'
1200
1213
  + '重新拆镜或改转场都没用。engine_suspect=true 表示本剧引擎是已知高发源(WAN),'
1201
1214
  + '实测 WAN 11/12 镜有镜内跳切、Seedance 1/6、H3 0/5,且提示词层拦不住(负向约束已在其中)——'
1202
- + '要根治只能 regenerate_shot_video 这些镜并换 seedance-2.5 或 hailuo-3。'
1203
- + '组模式镜与显式快剪蒙太奇镜天然多机位,已自动排除(detail 里标 skipped)。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/intra-shot-cuts`)));
1215
+ + '先复核实际切点与叙事意图,再决定调整切分还是重新生成;不要因扫描告警直接重试收费生成。'
1216
+ + '普通镜内多切统计仍排除组模式与显式蒙太奇;但组切分后的单段不能豁免片尾检查,需另看 shots_with_terminal_cuts/detail.terminal_cut。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/intra-shot-cuts`)));
1204
1217
  server.tool('scan_burned_subtitles', '★原声剧(视频自带人声)终拼前建议跑一次;客户报「成片里有两层字幕 / 画面里多出一行字」时先跑这个。'
1205
1218
  + '视频厂商有时会无视「不要字幕」的约束,把台词烧进画面——字小、通常只在说出那句台词的一两秒内出现,'
1206
1219
  + '而平台成片还会再叠一层字幕,于是变成双字幕。重新拼接去不掉它,只能 regenerate_shot_video 重出该镜。'
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.104",
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.104 tool surface (operationIds match MCP tool names 1:1)."
5
+ "version": "0.1.106",
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.106 tool surface (operationIds match MCP tool names 1:1)."
7
7
  },
8
8
  "servers": [
9
9
  {
@@ -722,6 +722,41 @@
722
722
  "director_style": {
723
723
  "type": "string"
724
724
  },
725
+ "creative_contract": {
726
+ "type": "object",
727
+ "properties": {
728
+ "version": {
729
+ "type": "number",
730
+ "const": 1
731
+ },
732
+ "speech": {
733
+ "type": "string",
734
+ "enum": [
735
+ "unspecified",
736
+ "forbidden",
737
+ "required"
738
+ ]
739
+ },
740
+ "music": {
741
+ "type": "string",
742
+ "enum": [
743
+ "unspecified",
744
+ "forbidden"
745
+ ]
746
+ },
747
+ "pacing": {
748
+ "type": "string",
749
+ "enum": [
750
+ "unspecified",
751
+ "quiet"
752
+ ]
753
+ }
754
+ },
755
+ "required": [
756
+ "version"
757
+ ],
758
+ "additionalProperties": false
759
+ },
725
760
  "image_model": {
726
761
  "type": "string"
727
762
  },
@@ -1022,6 +1057,41 @@
1022
1057
  "mv_audio_url": {
1023
1058
  "type": "string"
1024
1059
  },
1060
+ "creative_contract": {
1061
+ "type": "object",
1062
+ "properties": {
1063
+ "version": {
1064
+ "type": "number",
1065
+ "const": 1
1066
+ },
1067
+ "speech": {
1068
+ "type": "string",
1069
+ "enum": [
1070
+ "unspecified",
1071
+ "forbidden",
1072
+ "required"
1073
+ ]
1074
+ },
1075
+ "music": {
1076
+ "type": "string",
1077
+ "enum": [
1078
+ "unspecified",
1079
+ "forbidden"
1080
+ ]
1081
+ },
1082
+ "pacing": {
1083
+ "type": "string",
1084
+ "enum": [
1085
+ "unspecified",
1086
+ "quiet"
1087
+ ]
1088
+ }
1089
+ },
1090
+ "required": [
1091
+ "version"
1092
+ ],
1093
+ "additionalProperties": false
1094
+ },
1025
1095
  "image_model": {
1026
1096
  "type": "string"
1027
1097
  },
@@ -2697,6 +2767,53 @@
2697
2767
  }
2698
2768
  }
2699
2769
  },
2770
+ "/episodes/{episode_id}/asset-binding-repair-plan": {
2771
+ "get": {
2772
+ "operationId": "get_asset_binding_repair_plan",
2773
+ "summary": "只读生成一集历史缺失场景绑定的可审核修复提案",
2774
+ "description": "只读生成一集历史缺失场景绑定的可审核修复提案。返回原始地点/时段、候选 ID、匹配依据、歧义和 proposed_scene_id;applied=false,绝不按名字自动回填。逐项核对后才由客户决定是否改绑。免费。",
2775
+ "tags": [
2776
+ "episodes"
2777
+ ],
2778
+ "parameters": [
2779
+ {
2780
+ "name": "episode_id",
2781
+ "in": "path",
2782
+ "required": true,
2783
+ "schema": {
2784
+ "type": "integer",
2785
+ "exclusiveMinimum": 0
2786
+ }
2787
+ }
2788
+ ],
2789
+ "responses": {
2790
+ "200": {
2791
+ "description": "StarReel envelope",
2792
+ "content": {
2793
+ "application/json": {
2794
+ "schema": {
2795
+ "type": "object",
2796
+ "properties": {
2797
+ "code": {
2798
+ "type": "integer"
2799
+ },
2800
+ "message": {
2801
+ "type": "string"
2802
+ },
2803
+ "data": {
2804
+ "description": "Operation result payload"
2805
+ }
2806
+ }
2807
+ }
2808
+ }
2809
+ }
2810
+ },
2811
+ "402": {
2812
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
2813
+ }
2814
+ }
2815
+ }
2816
+ },
2700
2817
  "/episodes/{episode_id}/asset-recovery": {
2701
2818
  "get": {
2702
2819
  "operationId": "get_asset_recovery",
@@ -4719,7 +4836,7 @@
4719
4836
  "get": {
4720
4837
  "operationId": "scan_intra_shot_cuts",
4721
4838
  "summary": "★客户报「镜头切太快 / 一个镜头里画面跳来跳去」时先跑这个",
4722
- "description": "★客户报「镜头切太快 / 一个镜头里画面跳来跳去」时先跑这个。免费零扣费。一个分镜本应是**一个连续镜头**,但厂商可能在片内自行换机位硬切(望远镜特写→高空全景→人物中景),这类切点在分镜表和 timeline 里都看不到——只能扫画面。返回 shots_with_cuts(有镜内跳切的镜号)/total_cuts/engine_suspect/message。★判读:成片观感切点 = 镜与镜的接缝 + 这里报的镜内跳切;若本项占了大头,那不是剪辑节奏问题,重新拆镜或改转场都没用。engine_suspect=true 表示本剧引擎是已知高发源(WAN),实测 WAN 11/12 镜有镜内跳切、Seedance 1/6、H3 0/5,且提示词层拦不住(负向约束已在其中)——要根治只能 regenerate_shot_video 这些镜并换 seedance-2.5 或 hailuo-3。组模式镜与显式快剪蒙太奇镜天然多机位,已自动排除(detail 里标 skipped)。",
4839
+ "description": "★客户报「镜头切太快 / 一个镜头里画面跳来跳去」时先跑这个。免费零扣费。一个分镜本应是**一个连续镜头**,但厂商可能在片内自行换机位硬切(望远镜特写→高空全景→人物中景),这类切点在分镜表和 timeline 里都看不到——只能扫画面。返回 shots_with_cuts(有镜内跳切的镜号)/total_cuts/engine_suspect/message;shots_with_terminal_cuts 单列疑似短促片尾切镜,detail.terminal_cut 给出位置和状态。★判读:成片观感切点 = 镜与镜的接缝 + 这里报的镜内跳切;若本项占了大头,那不是剪辑节奏问题,重新拆镜或改转场都没用。engine_suspect=true 表示本剧引擎是已知高发源(WAN),实测 WAN 11/12 镜有镜内跳切、Seedance 1/6、H3 0/5,且提示词层拦不住(负向约束已在其中)——先复核实际切点与叙事意图,再决定调整切分还是重新生成;不要因扫描告警直接重试收费生成。普通镜内多切统计仍排除组模式与显式蒙太奇;但组切分后的单段不能豁免片尾检查,需另看 shots_with_terminal_cuts/detail.terminal_cut。",
4723
4840
  "tags": [
4724
4841
  "episodes"
4725
4842
  ],
@@ -4860,7 +4977,7 @@
4860
4977
  "get": {
4861
4978
  "operationId": "get_pipeline_status",
4862
4979
  "summary": "查某一集完整工作流的进度(script_rewrite/提取/分镜/语音/出图/出视频/合成/配乐/终拼…各步 done/partial/pending/not_required)",
4863
- "description": "查某一集完整工作流的进度(script_rewrite/提取/分镜/语音/出图/出视频/合成/配乐/终拼…各步 done/partial/pending/not_required)。照它按序推进、不跳步。免费。★not_required=当前模式不需要该步(如原声剧的 TTS 三步、关配乐的 generate_bgm),不是没做完,别去补做。图片/视频分母已剔除卡镜(shots_not_applicable);merge_episode.bgm_stale=true 表示配乐晚于成片,重新 compose_episode 即可。",
4980
+ "description": "查某一集完整工作流的进度(script_rewrite/提取/分镜/语音/出图/出视频/合成/配乐/终拼…各步 done/partial/pending/not_required)。照它按序推进、不跳步。免费。asset_versions_summary 将 generated、input_consistent、review_valid、adopted 和 current_effective 分开计数;不能把 generate_videos.completed 当当前有效数量。★not_required=当前模式不需要该步(如原声剧的 TTS 三步、关配乐的 generate_bgm),不是没做完,别去补做。图片/视频分母已剔除卡镜(shots_not_applicable);merge_episode.bgm_stale=true 表示配乐晚于成片,重新 compose_episode 即可。",
4864
4981
  "tags": [
4865
4982
  "episodes"
4866
4983
  ],
@@ -6263,7 +6380,7 @@
6263
6380
  "get": {
6264
6381
  "operationId": "get_storyboards",
6265
6382
  "summary": "读某一集的分镜列表(供审阅/查进度)",
6266
- "description": "读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。★每镜带**台词与说话人**:dialogue(原文,无台词为 null)、dialogue_lines([{speaker,text}] 逐行,与字幕/配音同一个解析器拆的——这里的 speaker 就是成片里被配音的那个;舞台提示已剥),以及 is_key_moment(1=关键镜,走高端图模)与 emotion_intensity(1-10)。核对「台词有没有丢/谁说的/关键镜是哪几镜/情绪曲线」用这一次调用即可,不用逐镜拉;update_shot 改完台词也在这里核对。画面/视频/首尾帧提示词仍只在 get_shot_prompts 逐镜读。★每镜还带**结构化状态**:frame_status/video_status(ready/pending/authorizing/rejected/failed/none/not_required)、★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。照 retryable 判该重试还是该改内容,别解析中文。★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。★若某镜带 degraded_frames:[{frame_type,reason,reason_label,since,hint}],表示该帧是系统在同因连拒熔断后**放行**的(判据照记未拒),URL 上与干净帧无区别但需人工复核;不满意按 hint 修正输入后 generate_shot_frame 重生该帧。★terminal_desc_missing=true:该镜标为「状态改变」却三处都没说结束时什么样——**出尾帧前**就能看出来,现在整集一次拿到(此前只有 get_shot_prompts 能逐镜问,一集几十次没人会去问)。先 update_shot 把结束状态写进 last_frame_prompt 再出尾帧:照现状硬出的历史成功率 9.4%,写了终态的 40.2%,而每次被拒都照常扣费。确实该「几乎不变」的镜才用 generate_shot_frame 的 allow_missing_terminal 放行。★first_frame_source/last_frame_source='upload' 表示该帧是**外部上传图**(绕开了身份锚/画风锚/best-of-N/帧审计整条质量链路)——人物·服装·画风漂移排查先看这些镜;外部图导致的漂移不是平台生成质量问题,修复正路是删掉外部图改走 generate_shot_frame 平台重生。★若某镜带 reopen_pair_id:该镜首尾帧同时生成时只有一侧真的有问题、另一侧是无辜陪拒,原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。★每镜还带**绑定**(只有 ID):character_ids(本镜绑定的角色)、character_bindings[{character_id,presence}](presence=on_screen 在画面 / voice_only 只有声音、不进画面)、scene_id、prop_ids、active_wardrobe_id。出图注入谁的定妆图/哪张场景图/哪些道具图由这几项决定;角色名对照 get_characters、道具名对照 get_props。改绑用 update_shot 的 character_ids(★全量覆盖,先从这里读现值再改,漏传即解绑)与 character_presence;改完再读一次本工具核对。character_bindings 缺席 = 这次没读到(不是没绑),空数组才是没绑。★每镜带 **seam_state**(本镜与上一镜的镜间接缝,与官网帧时间线同一判据):ok=已续接(首帧就是上镜尾帧,或平台做过首尾帧衔接、已落地且之后两侧都没再重生) / unchained=该连续却没接上(标了连续从没接过,或平台发起的衔接重生没落地:被拒/失败/还在生成——本镜 frame_status 会是 failed/processing;或衔接审过之后本镜首帧又被重生过) / broken=接过但没接上(seam_failed_dims 给出哪几维不连续:characters/wardrobe/props/lighting/scene;seam_audit_status=stale 且没有维度 = 上一镜尾帧在衔接之后又重生过,本镜首帧接的还是旧尾帧) / intended=有意切换(硬切/换场/时间跳跃/景别大跳/插入镜/外部上传帧),不用管 / missing=两侧帧没齐 / unknown=没标意图也没接过(系统没判,不是有问题) / na=首镜或旁白卡。seam_audit_status=pending 表示衔接已落地、平台的衔接审计还没出结论。出视频前只需处理 unchained 与 broken:整集用 chain_frames(先 dry_run),单道用 chain_shot_from_prev / chain_shot_from。",
6383
+ "description": "读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。asset_versions 按首帧/尾帧/视频分别给出 generated(已生成)、input_consistent(与当前输入一致)、review_valid(审核有效)、adopted(已采用)、current_effective(当前有效)。null=缺少证据;ready 只表示存在产物,不代表当前有效。旧素材仍可查看。★每镜带**台词与说话人**:dialogue(原文,无台词为 null)、dialogue_lines([{speaker,text}] 逐行,与字幕/配音同一个解析器拆的——这里的 speaker 就是成片里被配音的那个;舞台提示已剥),以及 is_key_moment(1=关键镜,走高端图模)与 emotion_intensity(1-10)。核对「台词有没有丢/谁说的/关键镜是哪几镜/情绪曲线」用这一次调用即可,不用逐镜拉;update_shot 改完台词也在这里核对。画面/视频/首尾帧提示词仍只在 get_shot_prompts 逐镜读。★每镜还带**结构化状态**:frame_status/video_status(ready/pending/authorizing/rejected/failed/none/not_required)、★video_status=ready 只表示视频已生成,不等于画面验收通过。video_quality_issues 若含 terminal_cut:status=suspected 表示片尾疑似短促切镜,cut_at_s/tail_duration_s 给出位置;status=unavailable 表示探测未完成,不能当检测通过。两者均暂停本次自动尾帧回写与续接,先复核视频;字段缺席不代表做过检测,也不要直接重试收费生成。★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。照 retryable 判该重试还是该改内容,别解析中文。★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。★若某镜带 degraded_frames:[{frame_type,reason,reason_label,since,hint}],表示该帧是系统在同因连拒熔断后**放行**的(判据照记未拒),URL 上与干净帧无区别但需人工复核;不满意按 hint 修正输入后 generate_shot_frame 重生该帧。★terminal_desc_missing=true:该镜标为「状态改变」却三处都没说结束时什么样——**出尾帧前**就能看出来,现在整集一次拿到(此前只有 get_shot_prompts 能逐镜问,一集几十次没人会去问)。先 update_shot 把结束状态写进 last_frame_prompt 再出尾帧:照现状硬出的历史成功率 9.4%,写了终态的 40.2%,而每次被拒都照常扣费。确实该「几乎不变」的镜才用 generate_shot_frame 的 allow_missing_terminal 放行。★first_frame_source/last_frame_source='upload' 表示该帧是**外部上传图**(绕开了身份锚/画风锚/best-of-N/帧审计整条质量链路)——人物·服装·画风漂移排查先看这些镜;外部图导致的漂移不是平台生成质量问题,修复正路是删掉外部图改走 generate_shot_frame 平台重生。★若某镜带 reopen_pair_id:该镜首尾帧同时生成时只有一侧真的有问题、另一侧是无辜陪拒,原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。★每镜还带**绑定**(只有 ID):character_ids(本镜绑定的角色)、character_bindings[{character_id,presence}](presence=on_screen 在画面 / voice_only 只有声音、不进画面)、scene_id、prop_ids、active_wardrobe_id。出图注入谁的定妆图/哪张场景图/哪些道具图由这几项决定;角色名对照 get_characters、道具名对照 get_props。改绑用 update_shot 的 character_ids(★全量覆盖,先从这里读现值再改,漏传即解绑)与 character_presence;改完再读一次本工具核对。character_bindings 缺席 = 这次没读到(不是没绑),空数组才是没绑。★每镜带 **seam_state**(本镜与上一镜的镜间接缝,与官网帧时间线同一判据):ok=已续接(首帧就是上镜尾帧,或平台做过首尾帧衔接、已落地且之后两侧都没再重生) / unchained=该连续却没接上(标了连续从没接过,或平台发起的衔接重生没落地:被拒/失败/还在生成——本镜 frame_status 会是 failed/processing;或衔接审过之后本镜首帧又被重生过) / broken=接过但没接上(seam_failed_dims 给出哪几维不连续:characters/wardrobe/props/lighting/scene;seam_audit_status=stale 且没有维度 = 上一镜尾帧在衔接之后又重生过,本镜首帧接的还是旧尾帧) / intended=有意切换(硬切/换场/时间跳跃/景别大跳/插入镜/外部上传帧),不用管 / missing=两侧帧没齐 / unknown=没标意图也没接过(系统没判,不是有问题) / na=首镜或旁白卡。seam_audit_status=pending 表示衔接已落地、平台的衔接审计还没出结论。出视频前只需处理 unchained 与 broken:整集用 chain_frames(先 dry_run),单道用 chain_shot_from_prev / chain_shot_from。",
6267
6384
  "tags": [
6268
6385
  "episodes"
6269
6386
  ],
@@ -8958,6 +9075,53 @@
8958
9075
  }
8959
9076
  }
8960
9077
  },
9078
+ "/storyboards/{storyboard_id}/asset-versions": {
9079
+ "get": {
9080
+ "operationId": "get_asset_versions",
9081
+ "summary": "只读查询一个镜头的全部图片/视频版本、历史查看链接、依赖 ID 与版本哈希,以及已生成→与当前输入一致→审核有效→已采用四项独立事实",
9082
+ "description": "只读查询一个镜头的全部图片/视频版本、历史查看链接、依赖 ID 与版本哈希,以及已生成→与当前输入一致→审核有效→已采用四项独立事实。历史缺少依赖记录时显示未知,不补造快照。免费。",
9083
+ "tags": [
9084
+ "storyboards"
9085
+ ],
9086
+ "parameters": [
9087
+ {
9088
+ "name": "storyboard_id",
9089
+ "in": "path",
9090
+ "required": true,
9091
+ "schema": {
9092
+ "type": "integer",
9093
+ "exclusiveMinimum": 0
9094
+ }
9095
+ }
9096
+ ],
9097
+ "responses": {
9098
+ "200": {
9099
+ "description": "StarReel envelope",
9100
+ "content": {
9101
+ "application/json": {
9102
+ "schema": {
9103
+ "type": "object",
9104
+ "properties": {
9105
+ "code": {
9106
+ "type": "integer"
9107
+ },
9108
+ "message": {
9109
+ "type": "string"
9110
+ },
9111
+ "data": {
9112
+ "description": "Operation result payload"
9113
+ }
9114
+ }
9115
+ }
9116
+ }
9117
+ }
9118
+ },
9119
+ "402": {
9120
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
9121
+ }
9122
+ }
9123
+ }
9124
+ },
8961
9125
  "/storyboards/{storyboard_id}/chain-from": {
8962
9126
  "post": {
8963
9127
  "operationId": "chain_shot_from",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starreel/mcp",
3
- "version": "0.1.104",
3
+ "version": "0.1.106",
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.104",
5
+ "version": "0.1.106",
6
6
  "websiteUrl": "https://starreel.ai",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@starreel/mcp",
11
- "version": "0.1.104",
11
+ "version": "0.1.106",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  },