@starreel/mcp 0.1.107 → 0.1.108
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 +11 -0
- package/dist/tools/produce.js +15 -7
- package/openapi.json +62 -5
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -144,6 +144,16 @@ Don't ask the user at every step. Sort work into three tiers:
|
|
|
144
144
|
glowing energy, floating landforms and non-human forms as "wrong era",
|
|
145
145
|
dragging the look toward literal historical drama. A single scene can break
|
|
146
146
|
away via `update_scene`'s `era_contract` (scene level outranks episode level).
|
|
147
|
+
**When the era check conflicts with a customer-uploaded portrait** (the upload
|
|
148
|
+
itself, or the body / hair / sheet images derived from it), frame generation
|
|
149
|
+
stops with `400 ERA_USER_REF_CONFLICT` — nothing generated, nothing billed. Do
|
|
150
|
+
not retry blindly and do not pass `allow_era_ref_conflict: true` on your own:
|
|
151
|
+
tell the customer which character and image was flagged, and let them choose —
|
|
152
|
+
keep the look (then pass `allow_era_ref_conflict: true` on `generate_shot_frame`
|
|
153
|
+
/ `generate_frames`; the images are kept, not dropped), fix the portrait, or fix
|
|
154
|
+
the era contract. `generate_frames` dispatches in the background, so a shot
|
|
155
|
+
blocked this way does not error the batch call — after it, read `get_jobs`:
|
|
156
|
+
`frame_dispatch_rejections` lists every refused shot with its `code` and message.
|
|
147
157
|
**Props are a separate chain and the era contract does not reach them.** The
|
|
148
158
|
white-background prop sheet deliberately injects no visual lock and no era
|
|
149
159
|
contract (long lock prose drowns the style words), so a prop's period rests
|
|
@@ -677,6 +687,7 @@ Map the reason to an action:
|
|
|
677
687
|
| `transient` | true | BestOfN / quality-gate / rate-limit / network, or the audit itself failed to run | Back off, retry |
|
|
678
688
|
| `contract_rejected` | true | A **content/contract** rejection (era, composition, shot size, head-count, readable text…) — **not** a network blip. Measured: a blind re-roll clears it about a third of the time | Retry once or twice; if the same reason keeps coming back, read `fail_hint` and change the shot (see *What you can actually change* below) instead of re-rolling |
|
|
679
689
|
| `needs_content_fix` | false | A content/contract conflict that a re-roll almost never clears (measured ≤10%) — most often the character's wardrobe/accessory record conflicting with the approved portrait | Change the shot description / character record **first**, then regenerate. A blind retry is a full-price repeat |
|
|
690
|
+
| `diagnosis_required` | false | Repeated same-input same-reason failures, or an existing candidate awaits a verdict | Call `get_frame_retry_diagnosis` with the image task ID. Reaudit the existing candidate for audit errors; review evidence for unknown reasons. Do not submit an unchanged paid retry or rewrite the script without authorization. |
|
|
680
691
|
| `repeat_rejected` | false | Same shot rejected for the same reason until the circuit breaker tripped (auto-clears after 24 h) | Change the prompt / references / shot design **first** (see *What you can actually change* below); a blind retry is a full-price repeat of the same rejection |
|
|
681
692
|
| `pair_collateral` | true | The **other** frame of this shot failed its audit; this frame was never judged bad — it was only closed out with the batch | Do **not** edit this frame. If the shot carries `reopen_pair_id`, pass it to `generate_shot_frame` to redo only the faulty side; otherwise regenerate the shot |
|
|
682
693
|
| `unknown` | false | Unclassified | Read `fail_hint`; don't auto-retry |
|
package/dist/tools/produce.js
CHANGED
|
@@ -525,6 +525,7 @@ export function registerProduceTools(server, client) {
|
|
|
525
525
|
}, async ({ episode_id, quote_id, confirm_replace, review_token, acknowledge_review }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/generate`, {
|
|
526
526
|
quote_id, review_token, acknowledge_review, ...(confirm_replace ? { confirm_replace } : {}),
|
|
527
527
|
})));
|
|
528
|
+
server.tool('get_frame_retry_diagnosis', '免费只读查询图片任务的连败诊断、证据任务 ID 和下一步动作。diagnosis_required 时先调用本工具:审计故障重审已有候选,未知原因先复核;不得原样重抽或擅自改剧本。', { image_id: z.number().int().positive() }, async ({ image_id }) => jsonResult(await client.produceGet(`/images/${image_id}/diagnosis`)));
|
|
528
529
|
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
530
|
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`)));
|
|
530
531
|
server.tool('get_storyboards', '读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。' +
|
|
@@ -540,7 +541,8 @@ export function registerProduceTools(server, client) {
|
|
|
540
541
|
'两者均暂停本次自动尾帧回写与续接,先复核视频;字段缺席不代表做过检测,也不要直接重试收费生成。' +
|
|
541
542
|
'★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。' +
|
|
542
543
|
'fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/' +
|
|
543
|
-
'insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false
|
|
544
|
+
'insufficient_credits/transient/repeat_rejected/diagnosis_required/pair_collateral)、retryable(true=可重试;false=先按fail_hint处理,勿原样重试)、fail_hint(人读文案)。' +
|
|
545
|
+
'★diagnosis_required=同输入同细因连败或已有候选等待判决:先查看已有候选及审计依据。审计故障先重审同一候选,原因未知先复核,不得直接改剧本或重复生成。' +
|
|
544
546
|
'照 retryable 判该重试还是该改内容,别解析中文。' +
|
|
545
547
|
'★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。' +
|
|
546
548
|
'★若某镜带 degraded_frames:[{frame_type,reason,reason_label,since,hint}],表示该帧是系统在同因连拒熔断后**放行**的(判据照记未拒),' +
|
|
@@ -721,7 +723,8 @@ export function registerProduceTools(server, client) {
|
|
|
721
723
|
'真实进度只看 get_storyboards 的 first_frame_image / get_jobs 的逐条生成记录;' +
|
|
722
724
|
'余额不足(402)会中止整批,此时轮询再久也不会有结果,应去查余额而不是继续等。' +
|
|
723
725
|
'★★**个别镜反复出不来、其余镜都好了**:那不是等得不够久,是这几镜被内容闸连拒。' +
|
|
724
|
-
'看 get_storyboards 的 fail_reason(repeat_rejected / needs_content_fix / contract_rejected),' +
|
|
726
|
+
'看 get_storyboards 的 fail_reason(repeat_rejected / diagnosis_required / needs_content_fix / contract_rejected),' +
|
|
727
|
+
'若 diagnosis_required,先按 fail_hint 诊断已有候选;审计错误先重审,证据不足先复核,不要原样重抽或擅自改剧本。' +
|
|
725
728
|
'然后**跑 run_precheck**(事后也能跑,会告诉你是哪种矛盾),按它的提示用 update_shot 改景别/描述/绑定角色再重生。' +
|
|
726
729
|
'别继续 generate_frames 空转,也别把客户支去外部工具做图——外部图绕开身份锚与帧审计,人脸服装画风必漂。' +
|
|
727
730
|
REVIEW_GATE_HINT('review_storyboards', '分镜') + CONFIRM_HINT, {
|
|
@@ -733,8 +736,9 @@ export function registerProduceTools(server, client) {
|
|
|
733
736
|
'gpt-image-2.5-flare(默认·基础11点+每张参考图18点)/gpt-image-2.5-sunburst(同价·中文字形与细节更准)/' +
|
|
734
737
|
'gemini-3.1-flash-image(Nano Banana 2·71点)/gemini-3-pro-image(Nano Banana Pro·更精细·175点)/' +
|
|
735
738
|
'gemini-3.1-flash-lite-image(Nano Banana 2 Lite·便宜·31点)/doubao-seedream-5-0-260128(Seedream 5.0)'),
|
|
736
|
-
|
|
737
|
-
|
|
739
|
+
allow_era_ref_conflict: z.boolean().optional().describe('★默认不传。时代审核判定客户上传的定妆图(或由它派生的身体/发型/设定图)与时代设定冲突时,出图会被拦下(400 ERA_USER_REF_CONFLICT,未扣费)。**先把冲突原因告诉客户、由客户确认造型无误**后才带 true:这些图保留不剔、照常出图。造型真不对就改定妆图,时代设定错了就 set_era_contract'),
|
|
740
|
+
}, async ({ episode_id, quote_id, frame_type, image_model, review_token, acknowledge_review, allow_era_ref_conflict }) => jsonResult(await client.producePost(`/episodes/${episode_id}/frames/generate`, {
|
|
741
|
+
quote_id, frame_type, image_model, review_token, acknowledge_review, allow_era_ref_conflict,
|
|
738
742
|
})));
|
|
739
743
|
// ---------- 单镜出帧/重生(改某一镜的画面走这里,别去外部平台出图再传回来) ----------
|
|
740
744
|
server.tool('quote_shot_frame', '报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。' +
|
|
@@ -766,7 +770,8 @@ export function registerProduceTools(server, client) {
|
|
|
766
770
|
reopen_pair_id: z.string().optional().describe('来自 get_storyboards 该镜的同名字段;只重掷有问题的那一侧,不必再传 frame_type'),
|
|
767
771
|
image_model: z.string().optional().describe('临时覆盖本次重画的图片模型(★必须与 quote_shot_frame 传的那个一致,否则 400 IMAGE_MODEL_MISMATCH;不传=用 drama 级设定,默认 ChatGPT Image 2.5 Flare);取值同 generate_frames'),
|
|
768
772
|
allow_missing_terminal: z.boolean().optional().describe('★逃生门,默认不传。本镜标为「状态改变」却没写终态时,出尾帧会被前置闸拦下;带 true 表示「我知道,照现状出」。正解是先 update_shot 补 last_frame_prompt——那类镜照现状出的成功率 9.4%,这个参数只用于确认本镜就该「几乎不变」的场合'),
|
|
769
|
-
|
|
773
|
+
allow_era_ref_conflict: z.boolean().optional().describe('★默认不传。时代审核判定客户上传的定妆图(或由它派生的身体/发型/设定图)与时代设定冲突时,出图会被拦下(400 ERA_USER_REF_CONFLICT,未扣费)。**先把冲突原因告诉客户、由客户确认造型无误**后才带 true:这些图保留不剔、照常出图。造型真不对就改定妆图,时代设定错了就 set_era_contract'),
|
|
774
|
+
}, async ({ storyboard_id, quote_id, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, allow_era_ref_conflict }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/generate`, { quote_id, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, allow_era_ref_conflict })));
|
|
770
775
|
// ---------- 出视频(videos,大额) ----------
|
|
771
776
|
server.tool('quote_videos', '报价:给某一集所有分镜批量出视频要多少点(与实际扣费同函数,较准)。返回 estimated_points、quote_id。零扣费。' +
|
|
772
777
|
'⚠️ 视频是大额花费,务必把点数清楚告诉用户并等其确认。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/videos/quote`)));
|
|
@@ -1287,7 +1292,7 @@ export function registerProduceTools(server, client) {
|
|
|
1287
1292
|
})).optional()
|
|
1288
1293
|
.describe('画外音标记:[{character_id, presence}]。voice_only = 这一镜他只有声音、人不在画面(画外音/门外说话/电话那头)——' +
|
|
1289
1294
|
'出图时他的定妆图、人脸锁、站位、主体脸锚全部跳过,台词与配音不受影响;on_screen = 恢复在画面。' +
|
|
1290
|
-
'角色必须在本镜绑定里(可与 character_ids 同一请求,先改绑再标)
|
|
1295
|
+
'角色必须在本镜绑定里(可与 character_ids 同一请求,先改绑再标)。只列要改的角色,没列的不动(空数组 = 不改任何标记)。' +
|
|
1291
1296
|
'★完全没出现在画面、台词也不是他说的 → 直接从 character_ids 去掉,不用标 voice_only'),
|
|
1292
1297
|
title: z.string().optional().describe('镜头标题'),
|
|
1293
1298
|
description: z.string().optional().describe('画面描述'),
|
|
@@ -1439,7 +1444,10 @@ export function registerProduceTools(server, client) {
|
|
|
1439
1444
|
server.tool('get_assets', '读一部剧的全部资产聚合(角色/场景/道具/图片)。免费。', { drama_id: z.number().int().positive() }, async ({ drama_id }) => jsonResult(await client.produceGet(`/dramas/${drama_id}/assets`)));
|
|
1440
1445
|
// ========== P1 · 任务进度 + 成本/预算 ==========
|
|
1441
1446
|
server.tool('get_jobs', '查一部剧的任务队列进度(出图/出视频/合成各阶段的 pending/processing/done/failed)。' +
|
|
1442
|
-
'异步生成后用它看进度。免费。'
|
|
1447
|
+
'异步生成后用它看进度。免费。' +
|
|
1448
|
+
'★整集出帧(generate_frames)是后台逐镜派发,被拒的镜不会出现在任务列表里——看响应的 frame_dispatch_rejections' +
|
|
1449
|
+
'(每镜 storyboard_id/frame_type/code/message)。code=ERA_USER_REF_CONFLICT 表示客户上传的定妆图被时代审核判冲突:' +
|
|
1450
|
+
'把 message 转告客户、由客户确认后,带 allow_era_ref_conflict=true 对那几镜 generate_shot_frame。重启后该列表清空。', { drama_id: z.number().int().positive() }, async ({ drama_id }) => jsonResult(await client.produceGet(`/dramas/${drama_id}/jobs`)));
|
|
1443
1451
|
server.tool('get_drama_bill', '本剧净费用账单(免费)。核账、回答「到底花了多少、钱花在哪、退了多少」时用它,别自己拼流水。' +
|
|
1444
1452
|
'\n· totals / by_kind:每类 charged(扣费)、refunded(已退回)、net(净额)、charges/refunds(笔数)。' +
|
|
1445
1453
|
'**net 才是花费**,与网页「本剧已花费」、get_budget_status 同源;charged 含失败后自动退回的空转,只用于核账。' +
|
package/openapi.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "StarReel Production API",
|
|
5
|
-
"version": "0.1.
|
|
6
|
-
"description": "Turn a script into a finished, downloadable short-drama episode over REST.\n\nPipeline: script → AI rewrite → cast/scenes/props extraction → storyboards → portraits & sheets + scene plates → keyframes → video shots → TTS → final cut (.mp4).\n\n**Billing is prepaid and agent-safe**: big-ticket stages are quote-then-generate (`quote_*` returns a `quote_id`). For video, quote == actual charge. For images the quote is a *range* — models billed per reference image are priced before those are assembled, so `estimated_points` is the upper bound (size the balance by it and a run never dies half-way) and `typical_points` is the usual cost; fixed-price models return the two equal. Insufficient balance returns 402 — nothing half-runs and the account never goes negative.\n\nAuth: exchange your API key at `POST /v1/agent/token` for a 15-minute bearer token.\n\nGenerated from the @starreel/mcp v0.1.
|
|
5
|
+
"version": "0.1.108",
|
|
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.108 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -47,6 +47,10 @@
|
|
|
47
47
|
"name": "episodes",
|
|
48
48
|
"description": "Operations under /episodes"
|
|
49
49
|
},
|
|
50
|
+
{
|
|
51
|
+
"name": "images",
|
|
52
|
+
"description": "Operations under /images"
|
|
53
|
+
},
|
|
50
54
|
{
|
|
51
55
|
"name": "products",
|
|
52
56
|
"description": "Operations under /products"
|
|
@@ -1966,7 +1970,7 @@
|
|
|
1966
1970
|
"get": {
|
|
1967
1971
|
"operationId": "get_jobs",
|
|
1968
1972
|
"summary": "查一部剧的任务队列进度(出图/出视频/合成各阶段的 pending/processing/done/failed)",
|
|
1969
|
-
"description": "查一部剧的任务队列进度(出图/出视频/合成各阶段的 pending/processing/done/failed)
|
|
1973
|
+
"description": "查一部剧的任务队列进度(出图/出视频/合成各阶段的 pending/processing/done/failed)。异步生成后用它看进度。免费。★整集出帧(generate_frames)是后台逐镜派发,被拒的镜不会出现在任务列表里——看响应的 frame_dispatch_rejections(每镜 storyboard_id/frame_type/code/message)。code=ERA_USER_REF_CONFLICT 表示客户上传的定妆图被时代审核判冲突:把 message 转告客户、由客户确认后,带 allow_era_ref_conflict=true 对那几镜 generate_shot_frame。重启后该列表清空。",
|
|
1970
1974
|
"tags": [
|
|
1971
1975
|
"dramas"
|
|
1972
1976
|
],
|
|
@@ -4822,7 +4826,7 @@
|
|
|
4822
4826
|
"post": {
|
|
4823
4827
|
"operationId": "generate_frames",
|
|
4824
4828
|
"summary": "确认后批量出帧:后台异步",
|
|
4825
|
-
"description": "确认后批量出帧:后台异步。用 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 / needs_content_fix / contract_rejected)
|
|
4829
|
+
"description": "确认后批量出帧:后台异步。用 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 自动失效,复审一次即可(仍免费)。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费,不要替客户做这个决定。⚠️ 批量报价确认流程:先调对应的 quote_* 工具,把返回的 estimated_points 原样告诉用户,用户明确同意后,才用返回的 quote_id 调本工具。不要擅自确认。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
4826
4830
|
"tags": [
|
|
4827
4831
|
"episodes"
|
|
4828
4832
|
],
|
|
@@ -4864,6 +4868,9 @@
|
|
|
4864
4868
|
},
|
|
4865
4869
|
"acknowledge_review": {
|
|
4866
4870
|
"type": "boolean"
|
|
4871
|
+
},
|
|
4872
|
+
"allow_era_ref_conflict": {
|
|
4873
|
+
"type": "boolean"
|
|
4867
4874
|
}
|
|
4868
4875
|
},
|
|
4869
4876
|
"required": [
|
|
@@ -6660,7 +6667,7 @@
|
|
|
6660
6667
|
"get": {
|
|
6661
6668
|
"operationId": "get_storyboards",
|
|
6662
6669
|
"summary": "读某一集的分镜列表(供审阅/查进度)",
|
|
6663
|
-
"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
|
|
6670
|
+
"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。",
|
|
6664
6671
|
"tags": [
|
|
6665
6672
|
"episodes"
|
|
6666
6673
|
],
|
|
@@ -8128,6 +8135,53 @@
|
|
|
8128
8135
|
}
|
|
8129
8136
|
}
|
|
8130
8137
|
},
|
|
8138
|
+
"/images/{image_id}/diagnosis": {
|
|
8139
|
+
"get": {
|
|
8140
|
+
"operationId": "get_frame_retry_diagnosis",
|
|
8141
|
+
"summary": "免费只读查询图片任务的连败诊断、证据任务 ID 和下一步动作",
|
|
8142
|
+
"description": "免费只读查询图片任务的连败诊断、证据任务 ID 和下一步动作。diagnosis_required 时先调用本工具:审计故障重审已有候选,未知原因先复核;不得原样重抽或擅自改剧本。",
|
|
8143
|
+
"tags": [
|
|
8144
|
+
"images"
|
|
8145
|
+
],
|
|
8146
|
+
"parameters": [
|
|
8147
|
+
{
|
|
8148
|
+
"name": "image_id",
|
|
8149
|
+
"in": "path",
|
|
8150
|
+
"required": true,
|
|
8151
|
+
"schema": {
|
|
8152
|
+
"type": "integer",
|
|
8153
|
+
"exclusiveMinimum": 0
|
|
8154
|
+
}
|
|
8155
|
+
}
|
|
8156
|
+
],
|
|
8157
|
+
"responses": {
|
|
8158
|
+
"200": {
|
|
8159
|
+
"description": "StarReel envelope",
|
|
8160
|
+
"content": {
|
|
8161
|
+
"application/json": {
|
|
8162
|
+
"schema": {
|
|
8163
|
+
"type": "object",
|
|
8164
|
+
"properties": {
|
|
8165
|
+
"code": {
|
|
8166
|
+
"type": "integer"
|
|
8167
|
+
},
|
|
8168
|
+
"message": {
|
|
8169
|
+
"type": "string"
|
|
8170
|
+
},
|
|
8171
|
+
"data": {
|
|
8172
|
+
"description": "Operation result payload"
|
|
8173
|
+
}
|
|
8174
|
+
}
|
|
8175
|
+
}
|
|
8176
|
+
}
|
|
8177
|
+
}
|
|
8178
|
+
},
|
|
8179
|
+
"402": {
|
|
8180
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
8181
|
+
}
|
|
8182
|
+
}
|
|
8183
|
+
}
|
|
8184
|
+
},
|
|
8131
8185
|
"/products/{product_id}/sheet": {
|
|
8132
8186
|
"post": {
|
|
8133
8187
|
"operationId": "generate_product_sheet",
|
|
@@ -9995,6 +10049,9 @@
|
|
|
9995
10049
|
},
|
|
9996
10050
|
"allow_missing_terminal": {
|
|
9997
10051
|
"type": "boolean"
|
|
10052
|
+
},
|
|
10053
|
+
"allow_era_ref_conflict": {
|
|
10054
|
+
"type": "boolean"
|
|
9998
10055
|
}
|
|
9999
10056
|
},
|
|
10000
10057
|
"required": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.108",
|
|
4
4
|
"mcpName": "ai.starreel/starreel",
|
|
5
5
|
"description": "StarReel MCP server — drive the AI short-drama production pipeline (script → storyboards → frames → video → final cut) from Claude, Cursor, or any MCP client",
|
|
6
6
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
|
|
3
3
|
"name": "ai.starreel/starreel",
|
|
4
4
|
"description": "Turn a script into a finished, downloadable short-drama episode — via MCP or REST.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.108",
|
|
6
6
|
"websiteUrl": "https://starreel.ai",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "@starreel/mcp",
|
|
11
|
-
"version": "0.1.
|
|
11
|
+
"version": "0.1.108",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|