@starreel/mcp 0.1.207 → 0.1.209

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
@@ -641,6 +641,20 @@ content that will be rejected.
641
641
  `upload_shot_frame` is for art the customer already owns — the one exception is
642
642
  a **local touch-up of this shot's own platform candidate** (option 2 below).
643
643
 
644
+ **Only a small part of the frame is wrong?** (a face, an open mouth, a fringe of
645
+ halo pixels, a stray object) — use `quote_local_frame_edit` → `local_frame_edit`
646
+ instead of redrawing the whole frame or fixing it in an outside tool. Box the area
647
+ with normalized `regions` (≤ 40% of the frame) and say what it should become; the
648
+ platform pastes only that area back onto the original, so everything outside the
649
+ box stays pixel-identical. Face/mouth edits need `character_id`; the portrait is **not** sent
650
+ (with it the model redraws the portrait instead of the frame), the instruction
651
+ asks for the same person and the result is re-audited for identity. Results are **candidates, not the new frame**: show `composited_url`
652
+ from `get_local_frame_edit` to the customer, then `adopt_local_frame_edit` the one
653
+ they pick. Each candidate is charged; candidates the platform rejects are **not
654
+ refunded** — tell the customer that with the quote. Rolled out per drama and per `edit_kind`:
655
+ a 403 `LOCAL_FRAME_EDIT_UNAVAILABLE` lists `open_kinds`; for any other kind fall
656
+ back to `generate_shot_frame`.
657
+
644
658
  **When a shot frame fails, offer the customer three choices** (both
645
659
  `get_frame_candidates` and `get_frame_retry_diagnosis` return them as
646
660
  `recovery_options`, ordered free → free → paid; `needs_attention=false` means
@@ -251,6 +251,10 @@
251
251
  "update_acceptance_criterion": "Edit a customer acceptance item (free). Changing the text / category / shot / stages resets all three states of that item (the requirement changed, old conclusions no longer count); re-run the review to check it. To delete, use delete_acceptance_criterion. item_id comes from get_acceptance_criteria. (Editing customer acceptance items requires explicit client consent in every execution mode, including autopilot.)",
252
252
  "confirm_acceptance_criterion": "Record the **customer's own** confirmation of an acceptance item (free): accepted / rejected / pending (undo). Only the client state is written; the platform auto review and your QC conclusion are untouched. ★Call it only after the customer has explicitly stated their decision, with confirm_client_statement:true; you must never confirm on the customer's behalf, autopilot included.",
253
253
  "delete_acceptance_criterion": "Delete a customer acceptance item (free; its three states go with it). item_id comes from get_acceptance_criteria. (Deleting customer acceptance items requires explicit client consent in every execution mode, including autopilot.)",
254
+ "quote_local_frame_edit": "Quote: how many credits a **local edit of one frame of one shot** costs (fix a face, close a mouth, clean halo edges, remove a stray object). Zero cost. Use it when the customer only wants a small part of the image changed — do not edit it in an outside image tool and upload_shot_frame it back: outside tools also change details the customer already approved, bypass the identity anchors and audits, and break the provenance chain. To redraw the whole frame use quote_shot_frame / generate_shot_frame. The platform pastes the edited area back onto the original through a feathered mask: pixels outside the boxes stay unchanged. ★Billing: each candidate is charged as one image (unit_points × candidates; the image count is fixed, so estimated_points is the actual charge and equals typical_points). **Candidates rejected by the platform checks (visible seam, edit not applied, identity audit failed) are never refunded** — tell the customer this together with the points. Vendor failures are refunded automatically. ★Rolled out per drama and per edit_kind; otherwise 403 LOCAL_FRAME_EDIT_UNAVAILABLE, whose open_kinds lists the kinds open to every drama (e.g. object_remove) — for any other kind fall back to generate_shot_frame. Face edits without character_id → 400 CHARACTER_REQUIRED; face edits do not send the character portrait (only the cropped base), identity is checked by the audit after pasting back.",
255
+ "local_frame_edit": "After confirmation, **locally edit one frame of one shot** (async, charged). Parameters must equal the quote_local_frame_edit call exactly (any change to regions / instruction / kind / character / candidates / base image → 409 QUOTE_PARAMS_CHANGED; re-quote for free). Returns edit_id; poll with get_local_frame_edit. ★**It never replaces the current frame automatically**: show the candidates (composited_url) to the customer first; only adopt_local_frame_edit writes the chosen one into the shot and marks the shot video as needing regeneration. ★Rejected candidates are charged and not refunded. Requires the review_storyboards review_token (and asset_review_token on rollout dramas), same as generate_shot_frame.",
256
+ "get_local_frame_edit": "Check progress and results of a local frame edit (free). status=running → keep waiting; when completed, look at each candidate: composited_url (the result pasted back onto the original — show this to the customer), verdict (pass = usable; warn = usable but needs a human look — REGION_SEAM_WARN possible seam / EDIT_NOT_APPLIED barely changed / IDENTITY_AUDIT_UNAVAILABLE identity not audited; reject = not recommended — REGION_MISALIGNED misaligned paste / IDENTITY_MISMATCH face no longer matches the character after the edit / IDENTITY_AUDIT_REJECTED frame audit failed), metrics, identity_audit, identity_compare (face edits: identity score and threshold). Download and look at composited_url yourself, tell the customer, then adopt_local_frame_edit the one they pick. Rejected candidates are not refunded.",
257
+ "adopt_local_frame_edit": "Adopt a local-edit candidate as this shot's current frame (free). Same follow-up as an uploaded frame: the shot video is marked for regeneration and adjacent seams are repaired. ★Only after the customer has looked and chosen. If the frame changed after the edit → 409 BASE_FRAME_CHANGED (start a new edit on the current frame); verdict=reject candidates are refused by default (409 CANDIDATE_REJECTED) — pass accept_rejected:true only when the customer insists after seeing it.",
254
258
  "audit_seam_directions": "Pre-video seam direction check (advisory, never blocks any step): for every pair of adjacent shots, compares \"previous shot's last frame (or first frame if none) ↔ this shot's first frame\" for the same subject jumping left/right sides of the frame (a reversed eyeline is noted with it), reversed motion direction, and shot-size jumps (same subject, extreme long ↔ close-up). Eyeline alone and key-light direction are observed but not reported: production replay showed too many false positives on those (better to miss than to nag). Shots that look fine alone but jump when cut together usually fail on these. Complements audit_seams, which checks identity/wardrobe/props/object state but not direction or position. ★When: after first frames (and needed last frames) are done and chain_frames has run, before review_frames / generate_videos. Scene changes, declared jump cuts, insert shots and title/black cards are skipped automatically. ★dry_run first (default, free): returns the seams to observe plus estimated_points (upper bound) and typical_points (usual cost); tell the client both — billed by actual text tokens. After the client agrees, pass dry_run=false + confirm_usage_billing=true. Execution is asynchronous and returns immediately; read results with get_seam_directions a minute or two later. Seams already observed with unchanged frames are not billed again.",
255
259
  "get_seam_directions": "(Free) Read audit_seam_directions results: each issue gives the seam shot numbers, the problem (subject jumps sides, reversed motion, shot-size jump) and fixes (chain_shot_from mode=reframe to regenerate this shot's first frame anchored on the previous last frame / update_shot to state facing then generate_shot_frame / align_prev_shot when the previous shot already has video / split_shot to insert an intermediate shot size). Results are advisory: explain them to the client and let the client pick which to fix; intentional reverse shots, turns or impact cuts can be ignored. not_audited>0 = seams not observed yet or frames changed since; running=true = still running. review_frames' seam_direction_advisory is a summary of the same results. This tool only looks at pre-video still frames; after videos are generated, check seams with preview_seams (free short-clip previews)."
256
260
  }
@@ -55,6 +55,10 @@
55
55
  "generate_frames": "确认后批量出帧:后台异步。用 get_storyboards 轮询,first_frame_image/last_frame_image 逐镜填充即完成。★图片生成较慢——每张几十秒到数分钟(尤其高清模型),整集可能十几分钟。轮询看 frame_status:**pending=还在生成(继续耐心等,别当失败、别重复调 generate_frames,重复触发=白花钱)**、ready=完成、failed=才是真失败。别因为「等了一会儿还没出」就判定生成失败或重试。出视频前必须先出帧,否则视频会退化成无一致性锚点的画面。★**出帧前先把两个锚备齐**:定妆图(generate_portraits_and_sheets,锚人)与空景基板(generate_scene_images,锚景)。缺基板不会拦你,但每个场景的第一镜会没有背景锚(平台的兜底补图只惠及同场景后续镜),背景从首镜起就开始漂。用 get_pipeline_status 的 generate_scene_images 步核对 completed/total。frame_type 要与 quote_frames 用的一致(默认 first_frame)。★这是**批量补缺帧**:只给「缺该帧」的镜出图,已有首帧的镜会跳过——这是正常设计、不是\"系统拒绝重出\"。要**重出/重画某一镜已有的帧**(如换了定妆图要让新图生效),用 generate_shot_frame(单镜重生,平台带身份锚),不是这个工具、更不是自制图 upload_shot_frame。★**本工具默认只出首帧,出帧是两趟**:首帧出完必须调一次免费的 tail_frame_plan——它按平台自己的判据告出哪几镜需要独立尾帧(末态≠首态:大运镜/物体脱手/状态改变,占比约三成,你自己猜不出来),再用 frame_type=last_frame 批量补。生产实测 32 集里 30 集整集只出了首帧、其中 23 集一路出完视频:那些镜出视频时只有首帧一个锚,末态由模型自由发挥。本工具响应体里的 shots_needing_last_frame 就是这个数,不为 0 就别直接去 review_frames。★响应里的 frames_planned 是**计划数,不是已成功数**——本接口在后台派发循环开跑之前就返回了。真实进度只看 get_storyboards 的 first_frame_image / get_jobs 的逐条生成记录;余额不足(402)会中止整批,此时轮询再久也不会有结果,应去查余额而不是继续等。★★**个别镜反复出不来、其余镜都好了**:那不是等得不够久,是这几镜被内容闸连拒。看 get_storyboards 的 fail_reason(repeat_rejected / diagnosis_required / needs_content_fix / contract_rejected),若 diagnosis_required,先按 fail_hint 诊断已有候选;审计错误先重审,证据不足先复核,不要原样重抽或擅自改剧本。然后**跑 run_precheck**(事后也能跑,会告诉你是哪种矛盾),按它的提示用 update_shot 改景别/描述/绑定角色再重生。别继续 generate_frames 空转,也别把客户支去外部工具做图——外部图绕开身份锚与帧审计,人脸服装画风必漂。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
56
56
  "quote_shot_frame": "报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)一律拒收,别再传。★返回两个数:estimated_points 是**上界**(按参考图张数上限估,拿它准备余额就不会中途 402),typical_points 是**通常花费**。两个都告诉客户,只报上界会让人以为贵得多。固定价模型(如 Nano Banana 系列)下两者相等。",
57
57
  "generate_shot_frame": "确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image 变化。\n★继承重开(reopen_pair_id):get_storyboards 某镜带这个字段时,原样传进来可以只重掷首尾帧里真正有问题的那一侧——另一侧此前已经生成好的候选原样保留,不重新生成、不重新计费。传了它就不用再传 frame_type(会被忽略,由平台判定该重哪一侧);quote_id 仍要用 quote_shot_frame 报价(frame_type 传 first_frame 或 last_frame 均可,单帧同价)。若该镜没有 reopen_pair_id 字段(不满足继承条件),这个参数不要传,走常规 frame_type 重试。\n★★出尾帧若被拦下并提示「此镜标为状态改变,但没有任何地方说明结束时是什么样子」:正解是用 update_shot 把结束状态写进 last_frame_prompt 再出,**别直接加 allow_missing_terminal 硬上**——这类镜照现状出尾帧的历史成功率只有 9.4%(有终态描述的 40.2%),硬上多半是白扣一次钱。只有确认这一镜就是要「几乎不变」的画面时才带那个参数。\n★一键出片托管环节:同一镜重出帧最多 3 轮(一次调用算一轮,both 也算一轮),到上限回 **409 AUTOPILOT_SHOT_REGEN_LIMIT**(未派发、未扣费,quote 未消耗)——别换个工具绕,停下问客户:客户同意再出就照常报价、生成时带 customer_approved_more_regens:true(再给一份上限);客户接受现状就往下走,下一步收费调用带 acknowledge_review:true 记下确认。专业模式与客户把控的环节不受这个上限约束。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
58
+ "quote_local_frame_edit": "报价:**局部修改某一镜的某一帧**(修脸、闭嘴、去毛边、擦掉多出来的东西)要多少点。零扣费。客户只想改画面的一小块时用它,别拿外部图像工具改完再 upload_shot_frame——外部工具会连带改动已确认的其他细节、绕开身份锚与审计、来源链也断了;要整张重画才用 quote_shot_frame / generate_shot_frame。平台把修改区按羽化蒙版贴回原图:框外像素原样保留,只有框内被改。★计费:每个候选按一次出图扣(unit_points × candidates;张数固定,estimated_points 就是实扣,typical_points 与它相等)。**被平台判据拒掉的候选(贴回有接缝、没改到、身份审计不过)一律不退点**——报价时就要把这一点和点数一起讲给客户。厂商出图失败由平台自动退。★按剧、按类型灰度开放:没开放回 403 LOCAL_FRAME_EDIT_UNAVAILABLE,响应里 open_kinds 列出已对所有剧开放的类型(如 object_remove);要改的类型不在里面就只能 generate_shot_frame 整张重画。修脸类不带 character_id 回 400 CHARACTER_REQUIRED;修脸不送定妆图(只送底图局部),贴回后靠身份审计判是不是同一个人。",
59
+ "local_frame_edit": "确认后**局部修改某一镜的某一帧**(异步,扣费)。参数必须与 quote_local_frame_edit 那次完全相同(区域 / 指令 / 类型 / 角色 / 候选数 / 底图任一项变了 → 409 QUOTE_PARAMS_CHANGED,重新报价即可,免费)。返回 edit_id,之后用 get_local_frame_edit 轮询。★**不会自动替换当前帧**:候选出完先给客户看(composited_url),客户选定后调 adopt_local_frame_edit 才写进这一镜、并把本镜视频标为待重生;不采用,当前帧就不变。★被判据拒掉的候选照常计费、不退点。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
60
+ "get_local_frame_edit": "查一次局部返修的进度与结果(免费)。status=running 继续等;completed 后逐个候选看:composited_url(贴回原图后的成品,给客户看的就是它)、verdict(pass=可直接用;warn=能用但要人看——REGION_SEAM_WARN 边界可能有接缝 / EDIT_NOT_APPLIED 基本没改到 / IDENTITY_AUDIT_UNAVAILABLE 身份没审成;reject=不建议用——REGION_MISALIGNED 贴回错位 / IDENTITY_MISMATCH 修脸后与本人比对不像 / IDENTITY_AUDIT_REJECTED 帧审计不过)、metrics、identity_audit、identity_compare(修脸类的身份比对分数与阈值)。下载 composited_url 亲眼看过、讲给客户,客户选定后用 adopt_local_frame_edit。被拒候选不退点。",
61
+ "adopt_local_frame_edit": "采用某个局部返修候选:把它写成这一镜的当前帧(免费)。与上传帧同一套后续处理:本镜视频标为待重生、相邻接缝跟着修。★只在客户看过并选定后调用。返修之后这一帧若已换过 → 409 BASE_FRAME_CHANGED(对当前帧重新发起);verdict=reject 的候选默认拒绝采用(409 CANDIDATE_REJECTED),客户看过坚持要用才带 accept_rejected:true。",
58
62
  "quote_videos": "报价:给某一集批量出视频要多少点(与实际扣费同函数,较准)。返回 estimated_points、quote_id。零扣费。⚠️ 视频是大额花费,务必把点数清楚告诉用户并等其确认。\n★**只计这次真会派发的镜**:已出视频的镜整集续跑时跳过,不重出不计价——shots_total = 这次计价的镜数(不是集内总镜数),shots_already_done = 已出视频、这次跳过的镜数。例外:场景组只要有一镜没出视频就**整组重出**,组内已出的镜同样计价。全部已出视频 ⇒ 400(没有可派发的镜,要重出某镜用 regenerate_shot_video)。报价之后若有镜的视频被清空(变成待出视频),generate_videos 会 409 要求重新报价,不按报价外的镜扣费。\n★**按镜指定视频引擎**:传 shot_engines={分镜id: 引擎} 即只为这些镜、这一次整集生成换引擎(不改剧级 video_engine,其余镜照旧)。报价按它逐镜计价,quote_id 把引擎钉死,generate_videos 派发的就是它——要改引擎必须重新报价。回执 shot_engines = 实际生效的映射;shot_engines_ungrouped = 因含指定镜而**拆成逐镜出**的场景组(场景组的时长与多关键帧是按剧引擎规划的,换引擎整组出会丢镜/丢关键帧;拆组后组内其余镜仍按剧引擎逐镜出,失去组内一次成片的连贯性,所以别为一镜去拆一个好好的组——先看 get_scene_group_plan)。所选引擎必须支持本剧分辨率(seedance-2.5 只有 480p/720p;hailuo-3 只有 720p/1080p;wan3.0/wan3.0-prime 480p~1080p),且镜头时长不超过该引擎单镜上限(seedance-2.5/wan3.0 30s,hailuo-3 15s),否则 400(超长会被厂商截断,要么换引擎要么 split_shot)。指定引擎的镜必须这次会出视频:已出视频的镜整集生成不会重出,给它指定引擎 ⇒ 400;拆成逐镜的场景组只计没出视频的组员。只想重出个别已出过视频的镜,用 quote_regenerate_shot_video 的 model 更省。",
59
63
  "generate_videos": "确认后批量出视频:一条后台链跑完整集,余额不足会自动中止整链(防重复扣)。要求本集已出首帧(未出会被拒)。用 get_storyboards 轮询 video_url 逐镜填充即完成。\n★【镜头图片审查硬闸·免费】本步前必须先调 review_frames:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_frames 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。\n★【完成后质检·免费】出完等它落库(get_storyboards 看 video_status / get_pipeline_status),再调 review_videos 审视频与配音层(缺视频 / 旧帧出的视频 / 片尾硬切 / 意外人声 / 配音缺失 / 音色未分配 / 原声声线过期),修完复审;再按 agent_qc 亲自逐镜看视频、听配音(动作到位、不变脸、台词念全、嗓音对),submit_qc_report 提交;compose_episode 要带它的 review_token。",
60
64
  "compose_episode": "把某一集所有镜头视频拼成一条成片(终拼)。**免费**(纯拼接,无需报价确认),后台异步。发起前有终拼预检:缺视频的镜或仍在生成中的视频任务会 400 硬阻断并列出问题镜(blockers),补齐后重试;确要拼部分成片传 force=true(缺视频镜被跳过,成片缺镜,留痕)。响应里的 advisories(时长偏差/孤儿任务/缺TTS/post_production_pending 后期特效未完成)只提醒不阻断,建议逐条处理后再拼。发起后用 get_final_cut 轮询。\n★【视频与配音审查硬闸·免费】本步前必须先调 review_videos:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_videos 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★★【成片前自检·review_videos 通过后、compose_episode 之前】别靠反复导出整片、手工试转场来找问题——逐镜与接缝的问题有专门工具,拼之前按序过一遍:①这一集换过定妆图 / 设定图 / 场景图 / 镜头帧 → 先 get_stale_portrait_frames(episode_id,免费)看哪些镜的在用帧还基于旧资产,拿不准该用哪一版的镜再 get_asset_versions(storyboard_id,免费)逐镜看版本与依赖(unknown 是证据不足、不是已过期;重出要付费,清单讲给客户由客户定);②scan_intra_shot_cuts(episode_id,免费)查厂商在单镜内自行硬切的镜;③逐镜 recommend_trim_window(storyboard_id,免费)看冻结尾段与有效动作区间(组内镜返回 applicable=false,跳过),有推荐就 trim_shot 应用(免费);④audit_seams(episode_id)查相邻镜接缝的剪辑连续性:默认 dry_run 只列待审范围(免费),真执行按实际文本 token 计费,讲给客户、客户明确接受后才带 dry_run:false + confirm_usage_billing:true,结果看 get_storyboards 的 seam_review;⑤再 compose_episode。拼完成片发现跳切 / 拖尾 / 接不上,回到这几个工具按镜定位后只修那几镜,别整片反复导出试错。这些都是提示性检查,不过闸;裁剪与接缝审核不让 review_videos 的 token 失效。\n★【完成后质检·免费】成片出来后跑 review_final_cut(缺镜/字幕放不下/身份锚/跳轴/错别字,proofread=false 则不扣费),结论讲给客户;客户确认后才 confirm_delivery_acceptance(交付验收任何执行模式都须客户明确同意,托管也不例外)。force 只越过终拼预检,不越过审查闸。",
@@ -90,7 +90,7 @@ export const ENTRY_POINTS = [
90
90
  'upload_shot_frame(只用于客户自有真实素材)',
91
91
  'upload_shot_footage(客户自有整段视频当某镜成片:录屏/产品实拍/已有片段;登记后该镜不再 AI 出图出视频,终拼原样用,时长按素材回写;清除用 clear_shot_footage)',
92
92
  ],
93
- avoid: '要「改某一镜画面」走 `generate_shot_frame`(平台自动带该镜身份锚·场景道具参考·画风锚);别在外部工具画好再 `upload_shot_frame`——外部图没有任何锚,人物/服装/画风必漂。',
93
+ avoid: '要「改某一镜画面」走 `generate_shot_frame`(平台自动带该镜身份锚·场景道具参考·画风锚);只改一小块(修脸/闭嘴/去毛边/擦掉多余物件)走 `quote_local_frame_edit` → `local_frame_edit`(框外像素原样保留);别在外部工具画好再 `upload_shot_frame`——外部图没有任何锚,人物/服装/画风必漂。',
94
94
  flow: 'upload_image · set_character_portrait · upload_scene_image · upload_prop_sheet · upload_shot_frame(仅客户自有素材;要改画面走 generate_shot_frame) · upload_shot_footage(整段实拍/录屏当某镜成片)',
95
95
  },
96
96
  {
@@ -253,7 +253,7 @@ export const PIPELINE = [
253
253
  },
254
254
  {
255
255
  step: '7 出帧(镜头图)',
256
- tools: ['run_precheck(免费,揪出必被厂商拒的镜)', 'quote_frames', 'generate_frames', 'tail_frame_plan(免费,首帧出完必调)', 'quote_shot_frame', 'generate_shot_frame(单镜重生)', 'chain_frames(先 dry_run:true 看计划与预估)', 'chain_shot_from_prev(免费,单道接缝)', 'quote_chain_shot_from', 'chain_shot_from', 'quote_align_prev_shot', 'align_prev_shot', 'upload_shot_frame'],
256
+ tools: ['run_precheck(免费,揪出必被厂商拒的镜)', 'quote_frames', 'generate_frames', 'tail_frame_plan(免费,首帧出完必调)', 'quote_shot_frame', 'generate_shot_frame(单镜重生)', 'quote_local_frame_edit', 'local_frame_edit(局部返修·只改框内,灰度剧)', 'get_local_frame_edit', 'adopt_local_frame_edit', 'chain_frames(先 dry_run:true 看计划与预估)', 'chain_shot_from_prev(免费,单道接缝)', 'quote_chain_shot_from', 'chain_shot_from', 'quote_align_prev_shot', 'align_prev_shot', 'upload_shot_frame'],
257
257
  billing: '报价确认后扣点',
258
258
  gate: 'review_frames(镜头图审查;免费;generate_videos 前必过)',
259
259
  note: '★出帧是**两趟**:generate_frames 默认只出首帧,首帧出完必须调一次免费的 `tail_frame_plan` ' +
@@ -319,7 +319,8 @@ export const QA_TOOLS = [
319
319
  ] },
320
320
  { symptom: '动作发生在裁剪窗口之外', run: 'recommend_trim_window', then: ['trim_shot'] },
321
321
  { symptom: '转场 / 接缝看着不对(跳、重影、接不上)', run: 'preview_seams(免费;get_seam_previews 轮询,逐道缝看短片与对照图,别反复导出整片)', then: ['recommend_trim_window → trim_shot(动作没接上)', 'update_shot(transition_type / transition_duration_ms 改转场,免费;之后 compose_episode 重拼才生效)', 'preview_seams(改完只传那道缝的 seams 序号复查——叠化/插镜/遮挡这类补救常带出新问题)'] },
322
- { symptom: '画面多出一个人 / 多出一件道具', run: 'get_storyboards(先看该镜实际用的首帧)', then: ['generate_shot_frame(首帧本身就有→重生首帧再重生视频)', 'split_shot(帧干净、片中长出来→拆成 3~5 秒短镜)'] },
322
+ { symptom: '画面多出一个人 / 多出一件道具', run: 'get_storyboards(先看该镜实际用的首帧)', then: ['local_frame_edit(首帧本身就有、其余都对→edit_kind=object_remove 只擦那一块;灰度剧)', 'generate_shot_frame(首帧本身就有→重生首帧再重生视频)', 'split_shot(帧干净、片中长出来→拆成 3~5 秒短镜)'] },
323
+ { symptom: '镜头图只有一小块不对(脸不像 / 嘴张着 / 边缘毛边 / 手指畸形),其余已经确认', run: 'quote_local_frame_edit(框出那一块,报价免费)', then: ['local_frame_edit(框外像素原样保留;修脸带 character_id)', 'get_local_frame_edit(看 composited_url 与 verdict)', 'adopt_local_frame_edit(客户选定后才写帧)'] },
323
324
  { symptom: '出图 / 出视频前想知道哪些镜会被厂商拒', run: 'run_precheck', then: ['update_shot', 'generate_shot_frame'] },
324
325
  { symptom: '要跑全集 / 想知道整部剧有多少问题、该先修哪几集', run: 'run_drama_precheck', then: ['run_precheck(对 attention 里那几集拿逐条明细)', 'plan_precheck_fix', 'update_shot'] },
325
326
  { symptom: '场景图(空景基板)不对 / 重出还是同一类图', run: 'get_scene_prompt', then: ['update_scene(改 image_prompt 正文——只改地点/时段是让平台重拼,拧不过来)', 'quote_regenerate_scene_image(先报价)', 'regenerate_scene_image(单场重出,覆盖旧图)', 'upload_scene_image(客户自有实拍/外部精修图)', 'quote_scene_lighting_ref → generate_scene_lighting_ref(换图后补打光参考图,先报价)', 'generate_shot_frame(下游镜头帧不会自动跟着重出)'] },
@@ -995,6 +995,41 @@ export function registerProduceTools(server, client) {
995
995
  allow_era_ref_conflict: z.boolean().optional().describe('★默认不传。时代审核判定角色定妆参考与时代设定冲突时,出图会被拦下(未扣费):客户上传的定妆图及其派生图报 400 ERA_USER_REF_CONFLICT,平台生成的定妆图报 era_identity_ref_blocked。**先把冲突原因告诉客户、由客户确认造型无误**后才带 true' + ALWAYS_ASK('allow_era_ref_conflict ') + ':这些图保留不剔、照常出图。造型真不对就改定妆图,时代设定错了就 set_era_contract'),
996
996
  ...SHOT_REGEN_ARG,
997
997
  }, async ({ storyboard_id, quote_id, review_token, asset_review_token, acknowledge_review, auto_acknowledge, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, allow_era_ref_conflict, customer_approved_more_regens }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/generate`, { quote_id, review_token, asset_review_token, acknowledge_review, auto_acknowledge, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, allow_era_ref_conflict, customer_approved_more_regens })));
998
+ // ---------- 镜头图局部返修(只修一小块,其余像素原样保留;按剧灰度) ----------
999
+ const LOCAL_EDIT_ARGS = {
1000
+ storyboard_id: z.number().int().positive(),
1001
+ frame_type: z.enum(['first_frame', 'last_frame']).optional().describe('默认 first_frame'),
1002
+ base_image_url: z.string().describe('★该镜**当前**这一帧的地址(get_storyboards 的 first_frame_image / last_frame_image 原样传)。帧换过会 409 BASE_FRAME_CHANGED,防止改的是旧图'),
1003
+ regions: z.array(z.object({ x: z.number(), y: z.number(), w: z.number(), h: z.number() })).describe('修改区:归一化矩形(0~1,相对画面宽高,x/y 是左上角),1~8 块,合计不超过画面 40%(超过请走 generate_shot_frame 整张重画)。框紧一点:框外像素平台保证不变,框越大越容易连带改到已确认的细节'),
1004
+ instruction: z.string().describe('这块要改成什么,一句话说清(≤500 字),例如「嘴闭上、表情平静」「去掉发丝边缘的白边」'),
1005
+ edit_kind: z.enum(['face', 'mouth', 'hair', 'costume', 'hand', 'edge_cleanup', 'object_remove', 'other']).describe('修改类型。face / mouth = 修脸类:必须带 character_id;face / mouth / hair / costume 生成后会过身份审计'),
1006
+ character_id: z.number().int().positive().optional().describe('修脸类(face / mouth)必填:改的是哪个角色的脸,贴回后按他做身份审计。平台**不送定妆图**(送了模型会直接画成定妆图),只要求「同一个人」。hair / costume 可选'),
1007
+ candidates: z.number().int().min(1).max(4).optional().describe('出几个候选,默认 2,最多 4。每个候选单独计费'),
1008
+ };
1009
+ server.tool('quote_local_frame_edit', '报价:**局部修改某一镜的某一帧**(修脸、闭嘴、去毛边、擦掉多出来的东西)要多少点。零扣费。' +
1010
+ '客户只想改画面的一小块时用它,别拿外部图像工具改完再 upload_shot_frame——外部工具会连带改动已确认的其他细节、绕开身份锚与审计、来源链也断了;' +
1011
+ '要整张重画才用 quote_shot_frame / generate_shot_frame。' +
1012
+ '平台把修改区按羽化蒙版贴回原图:框外像素原样保留,只有框内被改。' +
1013
+ '★计费:每个候选按一次出图扣(unit_points × candidates;张数固定,estimated_points 就是实扣,typical_points 与它相等)。' +
1014
+ '**被平台判据拒掉的候选(贴回有接缝、没改到、身份审计不过)一律不退点**——报价时就要把这一点和点数一起讲给客户。厂商出图失败由平台自动退。' +
1015
+ '★按剧、按类型灰度开放:没开放回 403 LOCAL_FRAME_EDIT_UNAVAILABLE,响应里 open_kinds 列出已对所有剧开放的类型(如 object_remove);要改的类型不在里面就只能 generate_shot_frame 整张重画。' +
1016
+ '修脸类不带 character_id 回 400 CHARACTER_REQUIRED;修脸不送定妆图(只送底图局部),贴回后靠身份审计判是不是同一个人。', LOCAL_EDIT_ARGS, async ({ storyboard_id, ...rest }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/local-edit/quote`, rest)));
1017
+ server.tool('local_frame_edit', '确认后**局部修改某一镜的某一帧**(异步,扣费)。参数必须与 quote_local_frame_edit 那次完全相同(区域 / 指令 / 类型 / 角色 / 候选数 / 底图任一项变了 → 409 QUOTE_PARAMS_CHANGED,重新报价即可,免费)。' +
1018
+ '返回 edit_id,之后用 get_local_frame_edit 轮询。' +
1019
+ '★**不会自动替换当前帧**:候选出完先给客户看(composited_url),客户选定后调 adopt_local_frame_edit 才写进这一镜、并把本镜视频标为待重生;不采用,当前帧就不变。' +
1020
+ '★被判据拒掉的候选照常计费、不退点。' + REVIEW_GATE_HINT('review_storyboards', '分镜') + ASSET_GATE_HINT + CONFIRM_HINT, { ...LOCAL_EDIT_ARGS, quote_id: z.string().describe('来自 quote_local_frame_edit'), ...REVIEW_ARGS, ...ASSET_REVIEW_ARG }, async ({ storyboard_id, ...rest }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/local-edit/generate`, rest)));
1021
+ server.tool('get_local_frame_edit', '查一次局部返修的进度与结果(免费)。status=running 继续等;completed 后逐个候选看:' +
1022
+ 'composited_url(贴回原图后的成品,给客户看的就是它)、verdict(pass=可直接用;warn=能用但要人看——REGION_SEAM_WARN 边界可能有接缝 / EDIT_NOT_APPLIED 基本没改到 / IDENTITY_AUDIT_UNAVAILABLE 身份没审成;' +
1023
+ 'reject=不建议用——REGION_MISALIGNED 贴回错位 / IDENTITY_MISMATCH 修脸后与本人比对不像 / IDENTITY_AUDIT_REJECTED 帧审计不过)、metrics、identity_audit、identity_compare(修脸类的身份比对分数与阈值)。' +
1024
+ '下载 composited_url 亲眼看过、讲给客户,客户选定后用 adopt_local_frame_edit。被拒候选不退点。', { storyboard_id: z.number().int().positive(), edit_id: z.string().describe('来自 local_frame_edit') }, async ({ storyboard_id, edit_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/frame/local-edit/${encodeURIComponent(edit_id)}`)));
1025
+ server.tool('adopt_local_frame_edit', '采用某个局部返修候选:把它写成这一镜的当前帧(免费)。与上传帧同一套后续处理:本镜视频标为待重生、相邻接缝跟着修。' +
1026
+ '★只在客户看过并选定后调用。返修之后这一帧若已换过 → 409 BASE_FRAME_CHANGED(对当前帧重新发起);' +
1027
+ 'verdict=reject 的候选默认拒绝采用(409 CANDIDATE_REJECTED),客户看过坚持要用才带 accept_rejected:true。', {
1028
+ storyboard_id: z.number().int().positive(),
1029
+ edit_id: z.string().describe('来自 local_frame_edit'),
1030
+ generation_id: z.number().int().positive().describe('要采用的候选(get_local_frame_edit 里的 generation_id)'),
1031
+ accept_rejected: z.boolean().optional().describe('默认不传。verdict=reject 的候选客户看过仍坚持要用时才传 true'),
1032
+ }, async ({ storyboard_id, edit_id, generation_id, accept_rejected }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/local-edit/${encodeURIComponent(edit_id)}/adopt`, { generation_id, accept_rejected })));
998
1033
  // ---------- 出视频(videos,大额) ----------
999
1034
  server.tool('quote_videos', '报价:给某一集批量出视频要多少点(与实际扣费同函数,较准)。返回 estimated_points、quote_id。零扣费。' +
1000
1035
  '⚠️ 视频是大额花费,务必把点数清楚告诉用户并等其确认。' +
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.207",
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.207 tool surface (operationIds match MCP tool names 1:1)."
5
+ "version": "0.1.209",
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.209 tool surface (operationIds match MCP tool names 1:1)."
7
7
  },
8
8
  "servers": [
9
9
  {
@@ -13898,6 +13898,420 @@
13898
13898
  }
13899
13899
  }
13900
13900
  },
13901
+ "/storyboards/{storyboard_id}/frame/local-edit/{edit_id}": {
13902
+ "get": {
13903
+ "operationId": "get_local_frame_edit",
13904
+ "summary": "查一次局部返修的进度与结果(免费)",
13905
+ "description": "查一次局部返修的进度与结果(免费)。status=running 继续等;completed 后逐个候选看:composited_url(贴回原图后的成品,给客户看的就是它)、verdict(pass=可直接用;warn=能用但要人看——REGION_SEAM_WARN 边界可能有接缝 / EDIT_NOT_APPLIED 基本没改到 / IDENTITY_AUDIT_UNAVAILABLE 身份没审成;reject=不建议用——REGION_MISALIGNED 贴回错位 / IDENTITY_MISMATCH 修脸后与本人比对不像 / IDENTITY_AUDIT_REJECTED 帧审计不过)、metrics、identity_audit、identity_compare(修脸类的身份比对分数与阈值)。下载 composited_url 亲眼看过、讲给客户,客户选定后用 adopt_local_frame_edit。被拒候选不退点。",
13906
+ "tags": [
13907
+ "storyboards"
13908
+ ],
13909
+ "parameters": [
13910
+ {
13911
+ "name": "storyboard_id",
13912
+ "in": "path",
13913
+ "required": true,
13914
+ "schema": {
13915
+ "type": "integer",
13916
+ "exclusiveMinimum": 0
13917
+ }
13918
+ },
13919
+ {
13920
+ "name": "edit_id",
13921
+ "in": "path",
13922
+ "required": true,
13923
+ "schema": {
13924
+ "type": "string",
13925
+ "description": "来自 local_frame_edit"
13926
+ }
13927
+ }
13928
+ ],
13929
+ "responses": {
13930
+ "200": {
13931
+ "description": "StarReel envelope",
13932
+ "content": {
13933
+ "application/json": {
13934
+ "schema": {
13935
+ "type": "object",
13936
+ "properties": {
13937
+ "code": {
13938
+ "type": "integer"
13939
+ },
13940
+ "message": {
13941
+ "type": "string"
13942
+ },
13943
+ "data": {
13944
+ "description": "Operation result payload"
13945
+ }
13946
+ }
13947
+ }
13948
+ }
13949
+ }
13950
+ },
13951
+ "402": {
13952
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
13953
+ }
13954
+ }
13955
+ }
13956
+ },
13957
+ "/storyboards/{storyboard_id}/frame/local-edit/{edit_id}/adopt": {
13958
+ "post": {
13959
+ "operationId": "adopt_local_frame_edit",
13960
+ "summary": "采用某个局部返修候选:把它写成这一镜的当前帧(免费)",
13961
+ "description": "采用某个局部返修候选:把它写成这一镜的当前帧(免费)。与上传帧同一套后续处理:本镜视频标为待重生、相邻接缝跟着修。★只在客户看过并选定后调用。返修之后这一帧若已换过 → 409 BASE_FRAME_CHANGED(对当前帧重新发起);verdict=reject 的候选默认拒绝采用(409 CANDIDATE_REJECTED),客户看过坚持要用才带 accept_rejected:true。",
13962
+ "tags": [
13963
+ "storyboards"
13964
+ ],
13965
+ "parameters": [
13966
+ {
13967
+ "name": "storyboard_id",
13968
+ "in": "path",
13969
+ "required": true,
13970
+ "schema": {
13971
+ "type": "integer",
13972
+ "exclusiveMinimum": 0
13973
+ }
13974
+ },
13975
+ {
13976
+ "name": "edit_id",
13977
+ "in": "path",
13978
+ "required": true,
13979
+ "schema": {
13980
+ "type": "string",
13981
+ "description": "来自 local_frame_edit"
13982
+ }
13983
+ }
13984
+ ],
13985
+ "requestBody": {
13986
+ "required": true,
13987
+ "content": {
13988
+ "application/json": {
13989
+ "schema": {
13990
+ "type": "object",
13991
+ "properties": {
13992
+ "generation_id": {
13993
+ "type": "integer",
13994
+ "exclusiveMinimum": 0,
13995
+ "description": "要采用的候选(get_local_frame_edit 里的 generation_id)"
13996
+ },
13997
+ "accept_rejected": {
13998
+ "type": "boolean"
13999
+ }
14000
+ },
14001
+ "required": [
14002
+ "generation_id"
14003
+ ]
14004
+ }
14005
+ }
14006
+ }
14007
+ },
14008
+ "responses": {
14009
+ "200": {
14010
+ "description": "StarReel envelope",
14011
+ "content": {
14012
+ "application/json": {
14013
+ "schema": {
14014
+ "type": "object",
14015
+ "properties": {
14016
+ "code": {
14017
+ "type": "integer"
14018
+ },
14019
+ "message": {
14020
+ "type": "string"
14021
+ },
14022
+ "data": {
14023
+ "description": "Operation result payload"
14024
+ }
14025
+ }
14026
+ }
14027
+ }
14028
+ }
14029
+ },
14030
+ "402": {
14031
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
14032
+ }
14033
+ }
14034
+ }
14035
+ },
14036
+ "/storyboards/{storyboard_id}/frame/local-edit/generate": {
14037
+ "post": {
14038
+ "operationId": "local_frame_edit",
14039
+ "summary": "确认后**局部修改某一镜的某一帧**(异步,扣费)",
14040
+ "description": "确认后**局部修改某一镜的某一帧**(异步,扣费)。参数必须与 quote_local_frame_edit 那次完全相同(区域 / 指令 / 类型 / 角色 / 候选数 / 底图任一项变了 → 409 QUOTE_PARAMS_CHANGED,重新报价即可,免费)。返回 edit_id,之后用 get_local_frame_edit 轮询。★**不会自动替换当前帧**:候选出完先给客户看(composited_url),客户选定后调 adopt_local_frame_edit 才写进这一镜、并把本镜视频标为待重生;不采用,当前帧就不变。★被判据拒掉的候选照常计费、不退点。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
14041
+ "tags": [
14042
+ "storyboards"
14043
+ ],
14044
+ "parameters": [
14045
+ {
14046
+ "name": "storyboard_id",
14047
+ "in": "path",
14048
+ "required": true,
14049
+ "schema": {
14050
+ "type": "integer",
14051
+ "exclusiveMinimum": 0
14052
+ }
14053
+ }
14054
+ ],
14055
+ "requestBody": {
14056
+ "required": true,
14057
+ "content": {
14058
+ "application/json": {
14059
+ "schema": {
14060
+ "type": "object",
14061
+ "properties": {
14062
+ "frame_type": {
14063
+ "type": "string",
14064
+ "enum": [
14065
+ "first_frame",
14066
+ "last_frame"
14067
+ ]
14068
+ },
14069
+ "base_image_url": {
14070
+ "type": "string",
14071
+ "description": "★该镜**当前**这一帧的地址(get_storyboards 的 first_frame_image / last_frame_image 原样传)。帧换过会 409 BASE_FRAME_CHANGED,防止改的是旧图"
14072
+ },
14073
+ "regions": {
14074
+ "type": "array",
14075
+ "items": {
14076
+ "type": "object",
14077
+ "properties": {
14078
+ "x": {
14079
+ "type": "number"
14080
+ },
14081
+ "y": {
14082
+ "type": "number"
14083
+ },
14084
+ "w": {
14085
+ "type": "number"
14086
+ },
14087
+ "h": {
14088
+ "type": "number"
14089
+ }
14090
+ },
14091
+ "required": [
14092
+ "x",
14093
+ "y",
14094
+ "w",
14095
+ "h"
14096
+ ],
14097
+ "additionalProperties": false
14098
+ },
14099
+ "description": "修改区:归一化矩形(0~1,相对画面宽高,x/y 是左上角),1~8 块,合计不超过画面 40%(超过请走 generate_shot_frame 整张重画)。框紧一点:框外像素平台保证不变,框越大越容易连带改到已确认的细节"
14100
+ },
14101
+ "instruction": {
14102
+ "type": "string",
14103
+ "description": "这块要改成什么,一句话说清(≤500 字),例如「嘴闭上、表情平静」「去掉发丝边缘的白边」"
14104
+ },
14105
+ "edit_kind": {
14106
+ "type": "string",
14107
+ "enum": [
14108
+ "face",
14109
+ "mouth",
14110
+ "hair",
14111
+ "costume",
14112
+ "hand",
14113
+ "edge_cleanup",
14114
+ "object_remove",
14115
+ "other"
14116
+ ],
14117
+ "description": "修改类型。face / mouth = 修脸类:必须带 character_id;face / mouth / hair / costume 生成后会过身份审计"
14118
+ },
14119
+ "character_id": {
14120
+ "type": "integer",
14121
+ "exclusiveMinimum": 0
14122
+ },
14123
+ "candidates": {
14124
+ "type": "integer",
14125
+ "minimum": 1,
14126
+ "maximum": 4
14127
+ },
14128
+ "quote_id": {
14129
+ "type": "string",
14130
+ "description": "来自 quote_local_frame_edit"
14131
+ },
14132
+ "review_token": {
14133
+ "type": "string"
14134
+ },
14135
+ "acknowledge_review": {
14136
+ "type": "boolean"
14137
+ },
14138
+ "auto_acknowledge": {
14139
+ "type": "boolean"
14140
+ },
14141
+ "asset_review_token": {
14142
+ "type": "string"
14143
+ }
14144
+ },
14145
+ "required": [
14146
+ "base_image_url",
14147
+ "regions",
14148
+ "instruction",
14149
+ "edit_kind",
14150
+ "quote_id"
14151
+ ]
14152
+ }
14153
+ }
14154
+ }
14155
+ },
14156
+ "responses": {
14157
+ "200": {
14158
+ "description": "StarReel envelope",
14159
+ "content": {
14160
+ "application/json": {
14161
+ "schema": {
14162
+ "type": "object",
14163
+ "properties": {
14164
+ "code": {
14165
+ "type": "integer"
14166
+ },
14167
+ "message": {
14168
+ "type": "string"
14169
+ },
14170
+ "data": {
14171
+ "description": "Operation result payload"
14172
+ }
14173
+ }
14174
+ }
14175
+ }
14176
+ }
14177
+ },
14178
+ "402": {
14179
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
14180
+ }
14181
+ }
14182
+ }
14183
+ },
14184
+ "/storyboards/{storyboard_id}/frame/local-edit/quote": {
14185
+ "post": {
14186
+ "operationId": "quote_local_frame_edit",
14187
+ "summary": "报价:**局部修改某一镜的某一帧**(修脸、闭嘴、去毛边、擦掉多出来的东西)要多少点",
14188
+ "description": "报价:**局部修改某一镜的某一帧**(修脸、闭嘴、去毛边、擦掉多出来的东西)要多少点。零扣费。客户只想改画面的一小块时用它,别拿外部图像工具改完再 upload_shot_frame——外部工具会连带改动已确认的其他细节、绕开身份锚与审计、来源链也断了;要整张重画才用 quote_shot_frame / generate_shot_frame。平台把修改区按羽化蒙版贴回原图:框外像素原样保留,只有框内被改。★计费:每个候选按一次出图扣(unit_points × candidates;张数固定,estimated_points 就是实扣,typical_points 与它相等)。**被平台判据拒掉的候选(贴回有接缝、没改到、身份审计不过)一律不退点**——报价时就要把这一点和点数一起讲给客户。厂商出图失败由平台自动退。★按剧、按类型灰度开放:没开放回 403 LOCAL_FRAME_EDIT_UNAVAILABLE,响应里 open_kinds 列出已对所有剧开放的类型(如 object_remove);要改的类型不在里面就只能 generate_shot_frame 整张重画。修脸类不带 character_id 回 400 CHARACTER_REQUIRED;修脸不送定妆图(只送底图局部),贴回后靠身份审计判是不是同一个人。",
14189
+ "tags": [
14190
+ "storyboards"
14191
+ ],
14192
+ "parameters": [
14193
+ {
14194
+ "name": "storyboard_id",
14195
+ "in": "path",
14196
+ "required": true,
14197
+ "schema": {
14198
+ "type": "integer",
14199
+ "exclusiveMinimum": 0
14200
+ }
14201
+ }
14202
+ ],
14203
+ "requestBody": {
14204
+ "required": true,
14205
+ "content": {
14206
+ "application/json": {
14207
+ "schema": {
14208
+ "type": "object",
14209
+ "properties": {
14210
+ "frame_type": {
14211
+ "type": "string",
14212
+ "enum": [
14213
+ "first_frame",
14214
+ "last_frame"
14215
+ ]
14216
+ },
14217
+ "base_image_url": {
14218
+ "type": "string",
14219
+ "description": "★该镜**当前**这一帧的地址(get_storyboards 的 first_frame_image / last_frame_image 原样传)。帧换过会 409 BASE_FRAME_CHANGED,防止改的是旧图"
14220
+ },
14221
+ "regions": {
14222
+ "type": "array",
14223
+ "items": {
14224
+ "type": "object",
14225
+ "properties": {
14226
+ "x": {
14227
+ "type": "number"
14228
+ },
14229
+ "y": {
14230
+ "type": "number"
14231
+ },
14232
+ "w": {
14233
+ "type": "number"
14234
+ },
14235
+ "h": {
14236
+ "type": "number"
14237
+ }
14238
+ },
14239
+ "required": [
14240
+ "x",
14241
+ "y",
14242
+ "w",
14243
+ "h"
14244
+ ],
14245
+ "additionalProperties": false
14246
+ },
14247
+ "description": "修改区:归一化矩形(0~1,相对画面宽高,x/y 是左上角),1~8 块,合计不超过画面 40%(超过请走 generate_shot_frame 整张重画)。框紧一点:框外像素平台保证不变,框越大越容易连带改到已确认的细节"
14248
+ },
14249
+ "instruction": {
14250
+ "type": "string",
14251
+ "description": "这块要改成什么,一句话说清(≤500 字),例如「嘴闭上、表情平静」「去掉发丝边缘的白边」"
14252
+ },
14253
+ "edit_kind": {
14254
+ "type": "string",
14255
+ "enum": [
14256
+ "face",
14257
+ "mouth",
14258
+ "hair",
14259
+ "costume",
14260
+ "hand",
14261
+ "edge_cleanup",
14262
+ "object_remove",
14263
+ "other"
14264
+ ],
14265
+ "description": "修改类型。face / mouth = 修脸类:必须带 character_id;face / mouth / hair / costume 生成后会过身份审计"
14266
+ },
14267
+ "character_id": {
14268
+ "type": "integer",
14269
+ "exclusiveMinimum": 0
14270
+ },
14271
+ "candidates": {
14272
+ "type": "integer",
14273
+ "minimum": 1,
14274
+ "maximum": 4
14275
+ }
14276
+ },
14277
+ "required": [
14278
+ "base_image_url",
14279
+ "regions",
14280
+ "instruction",
14281
+ "edit_kind"
14282
+ ]
14283
+ }
14284
+ }
14285
+ }
14286
+ },
14287
+ "responses": {
14288
+ "200": {
14289
+ "description": "StarReel envelope",
14290
+ "content": {
14291
+ "application/json": {
14292
+ "schema": {
14293
+ "type": "object",
14294
+ "properties": {
14295
+ "code": {
14296
+ "type": "integer"
14297
+ },
14298
+ "message": {
14299
+ "type": "string"
14300
+ },
14301
+ "data": {
14302
+ "description": "Operation result payload"
14303
+ }
14304
+ }
14305
+ }
14306
+ }
14307
+ }
14308
+ },
14309
+ "402": {
14310
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
14311
+ }
14312
+ }
14313
+ }
14314
+ },
13901
14315
  "/storyboards/{storyboard_id}/frame/quote": {
13902
14316
  "post": {
13903
14317
  "operationId": "quote_shot_frame",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starreel/mcp",
3
- "version": "0.1.207",
3
+ "version": "0.1.209",
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.207",
5
+ "version": "0.1.209",
6
6
  "websiteUrl": "https://starreel.ai",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@starreel/mcp",
11
- "version": "0.1.207",
11
+ "version": "0.1.209",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  },