@starreel/mcp 0.1.138 → 0.1.140

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
@@ -720,6 +720,7 @@ Map the reason to an action:
720
720
  | `copyright` | false | Copyright / trademark / real-person likeness | Switch to generic original imagery |
721
721
  | `face_mismatch` | false | Portrait ≠ the authorized person | Swap the portrait / confirm same person |
722
722
  | `account_overdue` | false | Upstream vendor account overdue (platform-level) | Not self-healable — tell the user; do **not** touch the prompt |
723
+ | `model_unavailable` | false | The chosen image/video model's vendor is paused or temporarily unavailable. `fail_hint` lists the models that are available right now. Whether anything was charged is stated only in the error text — do not promise the user a refund | Ask the user, then switch: `update_project_settings` (`video_engine` / `image_model`) for the whole drama, or `regenerate_shot_video` `model` / `generate_shot_frame` `image_model` for one shot. Retrying unchanged fails again |
723
724
  | `quota_full` | false | Platform vendor-asset quota exhausted | Retry won't help — contact ops |
724
725
  | `insufficient_credits` | false | Balance too low for this call | Stop, prompt to recharge (402) |
725
726
  | `authorizing` | true | Face frame queuing for KYC (not a rejection) | Wait ~1 min, retry |
@@ -851,9 +852,13 @@ the shot is a close-up, or when the picture itself is also wrong.
851
852
  `repair_episode_dialogue` runs in the background — poll it with
852
853
  `get_dialogue_repair_status`. If the status carries `aborted`, the batch stopped
853
854
  early on an account-level failure (`credits` = out of points; `account_overdue` =
854
- the platform's upstream vendor account, not yours) and the `remaining` shots never
855
- ran. Resubmitting unchanged will fail the same way — top up for `credits`; for
856
- `account_overdue`, tell the user and retry later instead of looping.
855
+ the platform's upstream vendor account, not yours; `model_unavailable` = the chosen
856
+ video model's vendor is paused or temporarily unavailable) and the `remaining` shots
857
+ never ran. Resubmitting unchanged will fail the same way — top up for `credits`; for
858
+ `account_overdue`, tell the user and retry later instead of looping; for
859
+ `model_unavailable`, the error lists the models available right now — ask the user,
860
+ switch the model, then resubmit. Full-episode video runs (`generate_videos`) stop at
861
+ the first shot for the same reason, so only that one shot shows the failure.
857
862
  Every replaced shot is re-checked before it is written back (same test as
858
863
  `scan_dialogue_coverage`): if the new audio is still cut off, repeats or adds
859
864
  words, or isn't the line, the product is **not** written back and the charge is
@@ -964,6 +969,65 @@ The platform's default shot breakdown still asks for one continuous action per
964
969
  shot. Apply the beat approach shot by shot on complaints; don't rewrite a whole
965
970
  episode this way unprompted.
966
971
 
972
+ ### Action / fight / skill-showcase films (动作片 / 打斗 / 技能展示)
973
+
974
+ When the customer wants a short whose point is the action and the effects (little
975
+ or no dialogue), or brings a reference action clip and asks "can we make this",
976
+ call `get_capabilities_guide` with `section=action_film` first. The short version,
977
+ from an internal measured run (one character, 3 shots, 18 s, `hailuo-3`):
978
+
979
+ - **Assets go through the normal trunk; only the storyboard is yours.** Put a
980
+ one-paragraph action synopsis in `set_script`, then `rewrite_script` →
981
+ `review_script` → `extract_assets` (with the review token — extraction on a
982
+ new drama is rejected without a rewritten script). Then skip
983
+ `generate_storyboards` (AI breakdown splits one continuous move into
984
+ fragments) and write the table yourself: `get_storyboard_table_spec` →
985
+ `check_storyboard_table` → `import_storyboard_table`. Scene headers must use
986
+ the extracted scene names to bind. The import auto-completes in the
987
+ background: poll `get_autofill_status` until done, make your `update_shot`
988
+ prompt edits, and only then run `review_storyboards` for the token that
989
+ `generate_frames` needs (completion or edits invalidate an earlier token).
990
+ - **One big move per 5–7 s shot**, effects in `[VFX: …]` lines.
991
+ - **First frame = wind-up, not impact.** In the measured run the "punch shatters
992
+ the wall" frame was drawn at the moment of impact, so the video could only
993
+ play the aftermath. Set `first_frame_prompt` to the wind-up pose before
994
+ generating frames.
995
+ - **Adjacent continuous-action shots are generated as one group**, and their
996
+ durations get re-split by content (6 s + 5 s came back as ~8 s + 3.7 s). Check
997
+ `get_scene_group_plan` before generating videos.
998
+ - **Tail frames only help shots generated on their own.** Check
999
+ `get_scene_group_plan` first: a grouped shot's tail frame is never sent to
1000
+ the video model (only the group head's first frame is, except Seedance 2.5
1001
+ keyframe groups), so generating it is wasted spend. If a shot truly needs an
1002
+ end-state anchor, give it its own `video_engine` via `update_shot` (that
1003
+ takes it out of the group). For standalone shots: after first frames, call
1004
+ `tail_frame_plan`; for shots with
1005
+ `terminal_desc_missing`, write `last_frame_prompt` via `update_shot`, then
1006
+ run `review_storyboards` **again**, then per shot `quote_shot_frame` →
1007
+ `generate_shot_frame(frame_type=last_frame)` — the edit invalidated the old
1008
+ token. Don't batch tails with `generate_frames`: it ignores grouping and
1009
+ bills grouped shots' tails too. Quotes are single-use; quote scene plates
1010
+ with `quote_scene_images` before `generate_scene_images`.
1011
+ - **Wait between async steps:** `generate_portraits_and_sheets` needs two calls
1012
+ (portraits, poll `get_characters` until ready, then sheets); poll
1013
+ `get_storyboards` until first frames are ready before tail frames, and until
1014
+ tail frames land before reviewing.
1015
+ - **Before videos, run `review_frames`** once all first and tail frames have
1016
+ settled, and pass its token to `generate_videos` (the storyboard token only
1017
+ authorizes frame generation). The guide's `sequence` field lists the whole
1018
+ call order with every gate.
1019
+ - **Pacing:** generated shots tend to end with 2–3 s of lingering (charging,
1020
+ dust settling). Cut it with `trim_shot` (free). Confirm all activity stays
1021
+ inside the window: `recommend_trim_window` for independently generated
1022
+ shots; it returns `applicable=false` for grouped shots — sample frames every
1023
+ 0.25–0.5 s instead and pick `out_ms` by eye.
1024
+ `speed_factor` only speeds up the **whole** shot, including the hit itself.
1025
+ **Per-segment speed ramps inside one shot are not supported**. Offer
1026
+ trimming, or hand off with `export_handoff_pack` for local editing.
1027
+ - Cost reference for that run: about 3,360 points total (video 1,501, images
1028
+ ~1,050, text ~810). Text steps are billed after use and add up. Tell the
1029
+ customer in advance.
1030
+
967
1031
  ### Writing shots yourself — one main action per shot (动作过载 / "像快进")
968
1032
 
969
1033
  When you write storyboards yourself (`bulk_import_storyboards`, `update_shot`,
@@ -14,7 +14,7 @@
14
14
  * ★列表字段(use / tools / run / fix)里每一项以**工具名开头**,括号里写关键参数;
15
15
  * 散文字段里的工具名用反引号包住——referencedTools() 靠这两条约定抽名字。
16
16
  */
17
- export const GUIDE_VERSION = '2026-09-25';
17
+ export const GUIDE_VERSION = '2026-10-13';
18
18
  /** 按客户手上的材料选入口——这是 agent 最常缺的那张表。 */
19
19
  export const ENTRY_POINTS = [
20
20
  {
@@ -354,6 +354,7 @@ export const COMMON_REQUESTS = [
354
354
  { customer_says: '成片里话没说完 / 切太快', do: '先 `scan_dialogue_coverage` / `scan_intra_shot_cuts` 定病因,再按 qa_tools 的 then 修;别默认去加长镜头。' },
355
355
  { customer_says: '下载原图或视频到本地调色、用第三方 AI 后期', do: '`export_handoff_pack` purpose=local_color;只有图片传 media_type=images;按 local_postproduction.color_handoff 执行。' },
356
356
  { customer_says: '我想自己剪', do: '`export_handoff_pack` + `get_handoff_toolchain`,不走 `compose_episode`。' },
357
+ { customer_says: '做动作片 / 打斗 / 技能展示 / 这条参考动作片我们能不能做', do: '先 `get_capabilities_guide` section=action_film:资产照常走 `rewrite_script` → `review_script` → `extract_assets`,分镜改用自己写的表(`import_storyboard_table`)而不是 AI 拆镜,首帧停在起势,拖沓尾段用 `trim_shot` 剪;平台不支持镜内分段变速。' },
357
358
  { customer_says: '要配音 / 不要视频原声', do: '`update_project_settings` use_clip_audio=false → `assign_voices` → `generate_tts` → `compose_episode`。' },
358
359
  ];
359
360
  /**
@@ -604,6 +605,55 @@ export const MODEL_GUIDE = {
604
605
  { scenario: '打斗、流血场面多的写实剧', image_model: 'gpt-image-2.5-flare', video_engine: 'seedance-2.5', resolution: '720p', why: '图被安全拒的镜平台自动换 Nano Banana 2;视频侧把血腥措辞改成中性描述(Seedance 文本审核严)。不要为了过审换 WAN——写实人脸会被拒' },
605
606
  ],
606
607
  };
608
+ /**
609
+ * 动作片 / 打斗 / 技能展示片的制作引导。
610
+ * 出处:2026-10-13 内部测试剧实测(单角色、3 镜 18 秒、无对白的高速动作展示,MiniMax 出视频)。
611
+ * 叙事剧那条路(改写 → AI 拆镜)会把动作镜拆碎;下面每一条都是那次实测踩出来的。
612
+ * ★只写通用方法,不写任何具体角色/招式/剧名(通用 SaaS:钉死的内容会以 few-shot 污染所有租户)。
613
+ */
614
+ export const ACTION_FILM = {
615
+ when: '客户要做动作 / 打斗 / 技能展示 / 特效爆发类短片(无对白或极少对白,看点是动作与特效),或拿来一条参考动作片问「能不能做出来」时走这条。' +
616
+ '有对白、讲连贯故事的剧仍按 pipeline 正常走,只把其中的打斗镜按下面 shot_design 写。',
617
+ setup: [
618
+ '建剧:`create_drama` 一次设好——画幅照参考片(横屏动作片 16:9);art_bible / video_style_prompt 写画风与特效质感(如「2D 动画质感、速度线、动态模糊、能量辉光」);video_negative_prompt 写要压掉的(「画面静止、动作缓慢」);**完全无人声**的片才设 creative_contract speech=forbidden(防厂商自己加台词)——有哪怕一句对白/旁白就别设,否则含台词的镜被预检拦下、视频被强制静音、TTS 也被拒;无配乐需求关 bgm_enabled,无台词再关 show_subtitles。',
619
+ '画风:动画/风格化动作片记得 `update_project_settings` 把 style 从默认 realistic 改成**平台认识的档位键**——日式 2D 动画 anime、国漫 guoman、3D 卡通 c3d(实测 anime 出图即为 2D 动画质感)。别填「2D 动画质感」这类自由描述:认不出的值会退回 realistic,出图提示词仍带着「写实照片」与画风圣经打架。奇幻/仙侠题材先 `set_era_contract` era=fantasy(发光能量、悬浮碎石不会被判「不合时代」)。',
620
+ '入口:资产照常走剧本主干,**只把分镜换成自己写的表**。① `set_script` 写一段动作梗概(人物外观 + 动作经过)→ `rewrite_script` → `review_script` → `extract_assets`(带 review_token;新剧不经改写稿提取会被 400 拒,这一段不能省)——这样才有角色与场景供导入按名字绑定;② 分镜**不调 `generate_storyboards`**(AI 拆镜会把一个连贯动作拆成多个碎镜),改走 `get_storyboard_table_spec` → `check_storyboard_table`(errors 清零)→ `import_storyboard_table`,镜数、秒数、景别、运镜由你定;场景头地点名要与提取出的场景名一致才绑得上。③ 导入默认后台自动补全:`get_autofill_status` 轮询到 done → 再按 shot_design 用 `update_shot` 改首帧/尾帧提示词 → **最后**才 `review_storyboards` 拿 review_token 去出帧(补全或改镜都会让先拿的 token 失效,出帧被 400 拒;改完再审一次即可,免费)。',
621
+ '资产照常齐备:定妆图 + 设定图(`generate_portraits_and_sheets`)、空景基板(`quote_scene_images` → `generate_scene_images`)、`generate_color_script`。提取后先 `get_scenes` 核对:改写可能给一段**连续**动作自行编出时间推进(如同一地点拆出两个时段),这种多出来的场景用 `delete_scene` 删掉、分镜表场景头统一用留下的那个(每个场景都要单独付费出一张基板);剧情里**真有**不同时段(昼夜变化)就保留各自的场景与基板,分镜表场景头的地点和时段要与之对应,否则绑不上或套错光照。',
622
+ ],
623
+ /** 从头到尾的完整调用顺序——三道审查闸与每次改镜后的复审都在里面;各条细节见下面几段。 */
624
+ sequence: '★通则:下面每个 rewrite / extract / generate_* 都是**异步**的,调完立即返回;一律轮询到完成再走下一步——文本 agent 看 `get_run_status`,图看 `get_characters` / `get_storyboards`,基板看 `get_pipeline_status`,视频看 `get_storyboards` 的 video_status。' +
625
+ '`create_drama`(+ `update_project_settings` style / `set_era_contract`)→ `set_script`(动作梗概)→ `rewrite_script` → `get_run_status` 到结束 → `review_script` → `extract_assets`(带 token)→ `get_run_status` 到结束 → `get_scenes` 核对场景 → ' +
626
+ '`check_storyboard_table` → `import_storyboard_table` → `get_autofill_status` 到 done → `update_shot`(首帧起势等)→ `review_storyboards` → ' +
627
+ '`generate_portraits_and_sheets`(第一次只派定妆图)→ `get_characters` 轮询到定妆图 ready → 再调一次 `generate_portraits_and_sheets` 出设定图 → 轮询到 sheet ready;基板 `quote_scene_images` → `generate_scene_images`;`generate_color_script` → `quote_frames` → `generate_frames`(首帧,带分镜 token)→ `get_storyboards` 轮询到首帧全部 ready(出图是异步的)→ ' +
628
+ '`get_scene_group_plan` × `tail_frame_plan` 取交集(只留单独生成、又需要尾帧的镜)→ `update_shot`(last_frame_prompt)→ `review_storyboards`(复审拿新 token)→ 逐镜 `quote_shot_frame` → `generate_shot_frame`(frame_type=last_frame;别用批量 `generate_frames` 出尾帧,它不看分组,会连组内镜一起出、白扣费)→ `get_storyboards` 轮询到尾帧全部落地(还在生成时审查,拿到的 token 会在图落地后失效)→ ' +
629
+ '`review_frames`(★出视频前必过,拿帧层 token)→ `quote_videos` → `generate_videos`(带帧层 token)→ `get_storyboards` 轮询到全部 video_status=ready → `scan_intra_shot_cuts` → `trim_shot` 剪拖沓尾段 → `compose_episode` → `get_final_cut`。' +
630
+ '任何一步之后改了镜,下一个收费步之前都要把对应的 review_* 再跑一次。',
631
+ shot_design: [
632
+ '一镜一个「大招」:5~7 秒写一个主动作 + 它的特效(冲刺/出拳碎物/坠击冲击波各一镜),比一镜塞三个招式稳得多。特效约束写进分镜表的 [VFX: …] 行(一条一行),会硬注入出图。',
633
+ '★首帧停在**起势**,别停在**命中**瞬间:实测「出拳击碎岩壁」一镜的首帧被画成了拳已命中,视频只能从命中往后演,蓄力和出拳过程消失。出帧前用 `update_shot` 写 first_frame_prompt(「拳收在腰侧蓄力、身体前压」这类起势姿态),命中与碎裂留给视频去演。',
634
+ '夸张造型(能量包覆的肢体、巨大化的拳头等)只靠首帧维持不住——实测首帧画出来了,视频里退回成普通手臂缠着能量。要它贯穿全镜,首帧与尾帧都要画出该造型,并在 video_prompt 里写明全程保持。',
635
+ '瞬移 / 闪现类效果模型能做(实测:近景 → 能量闪光 → 人消失 → 远处出现 → 冲回近景,4 秒内循环 3~4 次),在画面叙述里写清「消失—出现—留下光迹」三段即可。',
636
+ '大场面(坠击、冲击波、能量柱)用远景 + 拉远:实测能量柱、强闪白、环形冲击波、碎石与镜头后撤都做出来了;人物在画面里会很小,身份一致性靠定妆图与设定图兜住。',
637
+ ],
638
+ continuity: [
639
+ '相邻的连续动作镜会被自动并成**一组**一次生成(场景组),组内时长会按内容重分:实测 6 秒 + 5 秒两镜生成后变成约 8 秒 + 3.7 秒。这是好事——组内动作衔接最顺——但别拿报价时的秒数去卡剪辑点;出视频前用 `get_scene_group_plan` 看分组。',
640
+ '★尾帧只对**单独生成**的镜有用:先看 `get_scene_group_plan`——被并进组的镜,组视频只送组首镜首帧(唯一例外是 seedance-2.5 的关键帧组),给它出的尾帧根本不会送到视频模型,出了白扣费(实测那次就有一张尾帧落在组内、没被用上)。某镜确实需要终态锚,就让它单独出:`update_shot` 给该镜设 video_engine(设了引擎的镜不进场景组,代价是失去与相邻镜一次成片的连贯),否则接受组内由模型自由衔接、不出尾帧。' +
641
+ '单独生成的镜:首帧出完必调 `tail_frame_plan`:冲刺类「从 A 点到 B 点」的镜会被判为状态改变、需要独立尾帧。出尾帧前先看 `get_storyboards` 的 terminal_desc_missing,为 true 的镜用 `update_shot` 写 last_frame_prompt(结束时人在哪、什么姿态、身后留下什么痕迹),否则尾帧大概率被终态闸拒且照常扣费。写完**再跑一次 `review_storyboards`**,用新 token 逐镜 `quote_shot_frame` → `generate_shot_frame`(frame_type=last_frame)出尾帧——改镜会让出首帧时那个 token 失效;批量 `generate_frames` 出尾帧不看分组,剧里有组内状态改变镜时会一并出、白扣费。报价一次只能用一次,出首帧用掉的 quote_id 不能再拿来出尾帧。首尾帧都出齐后跑 `review_frames`,用它的 token 才能 `generate_videos`(分镜层 token 只放行出帧)。',
642
+ '出完视频用 `scan_intra_shot_cuts` 查镜内乱切;瞬移类的闪切是有意的,别当成故障去重生。',
643
+ ],
644
+ engines: '实测样本(单次,3 镜):hailuo-3 720p,3 镜 18 秒视频 1501 点,无镜内乱切,瞬移 / 碎物 / 冲击波都做出;短板是每镜结尾有 2~3 秒「余韵」(蓄力、烟尘扩散)偏慢,夸张造型不保持。' +
645
+ 'seedance-2.5 同题报价约为 hailuo-3 的 3 倍,动作片未单独实测;wan3.0 最省且动作措辞容易过审,但会在镜内自行换机位(叙事剧实测 11/12 镜)——动作片里这有时反而像剪辑,有时是乱切,先出 1 镜看。' +
646
+ '只出 1 次样本不足以下定论,给客户推荐时说明这是单次实测;要比较引擎就同镜各出一版(`quote_regenerate_shot_video` 传 model)。',
647
+ pacing: [
648
+ '动作片的命门是节奏:参考片几乎每一秒都有动作,生成镜头的结尾常拖 2~3 秒。先抽帧看清楚哪一段在拖,再处理。',
649
+ '★拖沓的**尾段用 `trim_shot` 剪掉**(免费,in_ms/out_ms,之后 `compose_episode` 重拼):把镜头在动作结束、余韵刚起时收住。剪之前先确认保留窗口覆盖全部动作:独立生成的镜用 `recommend_trim_window` 看片内活动点(返回 applicable=true 时);**组内镜它返回 applicable=false**,改为下载该镜视频按 0.25~0.5 秒抽帧人工看动作在哪结束再定 out_ms;终拼预检报 trim_truncation_risk 只是提醒,活动点都在窗口内就可以照拼。',
650
+ 'speed_factor(`update_shot`,0.5~2.0,免费不重生)只能**整镜**统一变速:会把大招本身一起加快,冲击感变飘。只在整镜都偏慢时用。',
651
+ '★平台**不支持镜内分段变速**(同一镜里大招原速、余韵快放)。客户要那种效果:要么接受 `trim_shot` 剪掉余韵(时长相近,只是剪掉而不是快放),要么 `export_handoff_pack` 把镜头交给客户在本地剪辑软件里做分段变速。`split_shot` 不是解法——拆出来的新镜要重出视频、要花钱。',
652
+ '0.1~0.3 秒级的快切蒙太奇平台不会自动做,走 `export_handoff_pack` 交本地后期。',
653
+ ],
654
+ cost_reference: '同一次实测的总花费约 3360 点:视频 1501(hailuo-3,与报价一致)、图片约 1050(定妆 + 设定 + 场景基板 + 3 首帧 + 1 尾帧,落在报价区间内;其中那张尾帧所在镜被并进了组,事后看是白花的)、文本约 810(改写 + 提取 + 导入补全 + 色彩脚本,调用约 60 次)。' +
655
+ '文本步按 token 后付、没有报价,但在这种短片里占比不小,事先要告诉客户。',
656
+ };
607
657
  export const HOW_TO_READ = '先按 entry_points 判客户手上的材料该走哪条通道(这是最常被跳过的一步),再按 pipeline 顺序推进、每道 review_gates 必过;' +
608
658
  '收费步按 billing.quote_flow 报价确认;遇到质量投诉按 qa_tools 的 symptom 选检测工具先定病因。';
609
659
  export function buildGuide() {
@@ -619,9 +669,10 @@ export function buildGuide() {
619
669
  common_requests: COMMON_REQUESTS,
620
670
  local_postproduction: LOCAL_POSTPRODUCTION,
621
671
  model_guide: MODEL_GUIDE,
672
+ action_film: ACTION_FILM,
622
673
  };
623
674
  }
624
- export const GUIDE_SECTIONS = ['entry_points', 'pipeline', 'review_gates', 'qa_tools', 'optional_boosts', 'billing', 'common_requests', 'local_postproduction', 'model_guide'];
675
+ export const GUIDE_SECTIONS = ['entry_points', 'pipeline', 'review_gates', 'qa_tools', 'optional_boosts', 'billing', 'common_requests', 'local_postproduction', 'model_guide', 'action_film'];
625
676
  const head = (s) => /^[a-z][a-z0-9_]*/.exec(s.trim())?.[0] ?? null;
626
677
  const inProse = (s) => [...(s ?? '').matchAll(/`([a-z][a-z0-9_]*)`/g)].map((m) => m[1]);
627
678
  /** 引导里引用到的全部工具名(去重)——哨兵测试用:每一个都必须真的注册了。 */
@@ -668,6 +719,10 @@ export function referencedTools() {
668
719
  for (const m of [...MODEL_GUIDE.image_models, ...MODEL_GUIDE.video_engines]) {
669
720
  [...m.strengths, ...m.weaknesses, m.best_for, m.avoid_for].forEach((s) => inProse(s).forEach(add));
670
721
  }
722
+ // 动作片段:全是散文,工具名都用反引号包住
723
+ ;
724
+ [ACTION_FILM.when, ACTION_FILM.sequence, ...ACTION_FILM.setup, ...ACTION_FILM.shot_design, ...ACTION_FILM.continuity, ACTION_FILM.engines, ...ACTION_FILM.pacing, ACTION_FILM.cost_reference]
725
+ .forEach((s) => inProse(s).forEach(add));
671
726
  return [...out].sort();
672
727
  }
673
728
  /**
@@ -690,6 +745,7 @@ export function buildInstructions() {
690
745
  '长任务异步:generate_* 立即返回,用 get_pipeline_status / get_storyboards / get_run_status 轮询;图片 pending = 还在生成,别重复调(重复扣费)。',
691
746
  '改写成功后只 edit_rewritten_script 点改,别重跑 rewrite_script;角色外观唯一真相源是人物档案(update_character),别写进 visual_lock/art_bible。',
692
747
  '选图片模型/视频引擎、客户问「哪个模型好 / 怎么更省」→ get_capabilities_guide(section=model_guide):各模型实测优劣、价格、决策步骤与推荐组合;建剧时就主动讲给客户定。',
748
+ '做动作 / 打斗 / 技能展示片 → get_capabilities_guide(section=action_film):分镜表直通道、首帧停在起势、并组与节奏剪裁。',
693
749
  '不确定该用哪个工具、客户问「你们能做什么」→ 先调 get_capabilities_guide(免费、本地、不联网)。',
694
750
  ].join('\n');
695
751
  }
@@ -13,7 +13,8 @@ export function registerGuideTools(server) {
13
13
  'common_requests(客户常见原话 → 该做什么)、' +
14
14
  'local_postproduction(★客户要把镜头下载到**自己电脑**上调色 / 第三方 AI 后期 / 剪辑 / 配乐 / 烧字幕 / 优化转场 / 补旁白时的完整流程:' +
15
15
  '阶段顺序、执行位置、逐镜逐句怎么核对声音、什么才算验收完成)、' +
16
- 'model_guide(★图片模型与视频引擎的实测优劣势、价格、选型决策步骤与推荐组合——建剧选型、客户问「哪个模型好 / 为什么手画坏了 / 怎么省钱」时先看)。传 section 只取一段。' +
16
+ 'model_guide(★图片模型与视频引擎的实测优劣势、价格、选型决策步骤与推荐组合——建剧选型、客户问「哪个模型好 / 为什么手画坏了 / 怎么省钱」时先看)、' +
17
+ 'action_film(★动作 / 打斗 / 技能展示片的做法:资产照走改写主干而分镜用自己写的表、首帧停在起势、相邻动作镜并组、拖沓尾段怎么剪、引擎实测与花费参考——客户要做动作片或问「这条参考片能不能做」时先看)。传 section 只取一段。' +
17
18
  '★工具描述回答"这个工具做什么",本工具回答"什么情况下该用哪个"——客户交来的是成品分镜表却被 set_script→rewrite_script 改写成散文,就是没先看这张表。', {
18
19
  section: z.enum(GUIDE_SECTIONS).optional().describe('只取某一段;不传返回全部'),
19
20
  }, async ({ section }) => {
@@ -558,7 +558,9 @@ export function registerProduceTools(server, client) {
558
558
  '两者均暂停本次自动尾帧回写与续接,先复核视频;字段缺席不代表做过检测,也不要直接重试收费生成。' +
559
559
  '★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。' +
560
560
  'fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/' +
561
- 'insufficient_credits/transient/repeat_rejected/diagnosis_required/pair_collateral)、retryable(true=可重试;false=先按fail_hint处理,勿原样重试)、fail_hint(人读文案)。' +
561
+ 'insufficient_credits/transient/repeat_rejected/diagnosis_required/pair_collateral/model_unavailable)、retryable(true=可重试;false=先按fail_hint处理,勿原样重试)、fail_hint(人读文案)。' +
562
+ '★model_unavailable=所选图片/视频模型的厂商已暂停或暂不可用:fail_hint 里列了当前可用的替代模型(扣没扣费以错误文案为准,别替平台向用户承诺已退款),' +
563
+ '问用户后用 update_project_settings 改 video_engine/image_model(或只对本镜用 regenerate_shot_video 的 model / generate_shot_frame 的 image_model)再生成,原样重试只会再失败。' +
562
564
  '★diagnosis_required=同输入同细因连败或已有候选等待判决:先查看已有候选及审计依据。审计故障先重审同一候选,原因未知先复核,不得直接改剧本或重复生成。' +
563
565
  '照 retryable 判该重试还是该改内容,别解析中文。' +
564
566
  '★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。' +
@@ -1528,7 +1530,8 @@ export function registerProduceTools(server, client) {
1528
1530
  + 'dialogue-repair-status 查」——第三方照着找会扑空(2026-09-21 由 MCP 覆盖闸抓出)。'
1529
1531
  + '\n★返回里带 **aborted** = 上一批因整账户级失败被提前中止(kind=account_overdue 平台上游账户欠费 / '
1530
1532
  + 'credits 点数不足),remaining 镜未执行。此时**原样重提必然同因失败**:credits 先充值;'
1531
- + 'account_overdue 不是你的点数问题,停下告知用户稍后再试,别反复重提。'
1533
+ + 'account_overdue 不是你的点数问题,停下告知用户稍后再试,别反复重提;'
1534
+ + 'model_unavailable=所选视频模型的厂商已暂停或暂不可用,error 里列了可用的替代模型,问用户后换模型再提。'
1532
1535
  + '\n★带 **verify_rejected** = 这些镜换完复核没通过(断音/重复念/念错),产物没写回、费用已退——换音修不好,改 regenerate_shot_video。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/dialogue-repair-status`)));
1533
1536
  server.tool('get_shot_name_card', '读这一镜的**人物名片**现值(免费):名字、头衔、显示位置那些。'
1534
1537
  + '\n★改之前先读一遍——set_shot_name_card 是**整体覆盖**,不读就改会把没打算动的字段清掉。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/name-card`)));
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.138",
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.138 tool surface (operationIds match MCP tool names 1:1)."
5
+ "version": "0.1.140",
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.140 tool surface (operationIds match MCP tool names 1:1)."
7
7
  },
8
8
  "servers": [
9
9
  {
@@ -5222,7 +5222,7 @@
5222
5222
  "get": {
5223
5223
  "operationId": "get_dialogue_repair_status",
5224
5224
  "summary": "查台词修复的进度(免费)",
5225
- "description": "查台词修复的进度(免费)。repair_episode_dialogue 是后台异步串行跑的,用这个轮询。\n★这个工具此前**不存在**,而 repair_episode_dialogue 的描述里却写着「进度用 dialogue-repair-status 查」——第三方照着找会扑空(2026-09-21 由 MCP 覆盖闸抓出)。\n★返回里带 **aborted** = 上一批因整账户级失败被提前中止(kind=account_overdue 平台上游账户欠费 / credits 点数不足),remaining 镜未执行。此时**原样重提必然同因失败**:credits 先充值;account_overdue 不是你的点数问题,停下告知用户稍后再试,别反复重提。\n★带 **verify_rejected** = 这些镜换完复核没通过(断音/重复念/念错),产物没写回、费用已退——换音修不好,改 regenerate_shot_video。",
5225
+ "description": "查台词修复的进度(免费)。repair_episode_dialogue 是后台异步串行跑的,用这个轮询。\n★这个工具此前**不存在**,而 repair_episode_dialogue 的描述里却写着「进度用 dialogue-repair-status 查」——第三方照着找会扑空(2026-09-21 由 MCP 覆盖闸抓出)。\n★返回里带 **aborted** = 上一批因整账户级失败被提前中止(kind=account_overdue 平台上游账户欠费 / credits 点数不足),remaining 镜未执行。此时**原样重提必然同因失败**:credits 先充值;account_overdue 不是你的点数问题,停下告知用户稍后再试,别反复重提;model_unavailable=所选视频模型的厂商已暂停或暂不可用,error 里列了可用的替代模型,问用户后换模型再提。\n★带 **verify_rejected** = 这些镜换完复核没通过(断音/重复念/念错),产物没写回、费用已退——换音修不好,改 regenerate_shot_video。",
5226
5226
  "tags": [
5227
5227
  "episodes"
5228
5228
  ],
@@ -8013,7 +8013,7 @@
8013
8013
  "get": {
8014
8014
  "operationId": "get_storyboards",
8015
8015
  "summary": "读某一集的分镜列表(供审阅/查进度)",
8016
- "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/diagnosis_required/pair_collateral)、retryable(true=可重试;false=先按fail_hint处理,勿原样重试)、fail_hint(人读文案)。★diagnosis_required=同输入同细因连败或已有候选等待判决:先查看已有候选及审计依据。审计故障先重审同一候选,原因未知先复核,不得直接改剧本或重复生成。照 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_review.status 为 passed/failed/not_checked/stale;stale 是证据过期,不是画面失败,不据此付费重生。continuity_intent 可用 update_shot 明确。★每镜带 **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。",
8016
+ "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/diagnosis_required/pair_collateral/model_unavailable)、retryable(true=可重试;false=先按fail_hint处理,勿原样重试)、fail_hint(人读文案)。★model_unavailable=所选图片/视频模型的厂商已暂停或暂不可用:fail_hint 里列了当前可用的替代模型(扣没扣费以错误文案为准,别替平台向用户承诺已退款),问用户后用 update_project_settings 改 video_engine/image_model(或只对本镜用 regenerate_shot_video 的 model / generate_shot_frame 的 image_model)再生成,原样重试只会再失败。★diagnosis_required=同输入同细因连败或已有候选等待判决:先查看已有候选及审计依据。审计故障先重审同一候选,原因未知先复核,不得直接改剧本或重复生成。照 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_review.status 为 passed/failed/not_checked/stale;stale 是证据过期,不是画面失败,不据此付费重生。continuity_intent 可用 update_shot 明确。★每镜带 **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。",
8017
8017
  "tags": [
8018
8018
  "episodes"
8019
8019
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starreel/mcp",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
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.138",
5
+ "version": "0.1.140",
6
6
  "websiteUrl": "https://starreel.ai",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@starreel/mcp",
11
- "version": "0.1.138",
11
+ "version": "0.1.140",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  },