@starreel/mcp 0.1.110 → 0.1.111
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 +16 -0
- package/dist/tools/produce.js +12 -2
- package/openapi.json +72 -3
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -829,6 +829,21 @@ error from `replace_shot_dialogue`) — re-voicing can't fix them; regenerate th
|
|
|
829
829
|
shot instead.
|
|
830
830
|
Either way, `compose_episode` afterwards — the final cut still holds the old audio until you do.
|
|
831
831
|
|
|
832
|
+
**Narration / voice-over is a separate track — use `revoice_narration`, not
|
|
833
|
+
`replace_shot_dialogue`.** On clip-audio projects the narration is mixed into the
|
|
834
|
+
shot's video when it is generated, so `replace_shot_dialogue` refuses
|
|
835
|
+
narration-only shots ("no on-screen line to replace"). To change the narrator's
|
|
836
|
+
voice, set it first (`set_character_voice` on the narrator character, or
|
|
837
|
+
`design_voice`), or edit the narration line with `update_shot`, then call
|
|
838
|
+
`revoice_narration`: it keeps the picture and on-screen lines, silences only the
|
|
839
|
+
narration spans, re-synthesises them in the current voice, mixes them back and
|
|
840
|
+
re-checks — no video regeneration. Shots that mix on-screen lines and narration
|
|
841
|
+
work only when the clause count matches the speech spans heard in the clip;
|
|
842
|
+
otherwise it refuses rather than guess (a wrong guess would silence an actor).
|
|
843
|
+
If the vendor *spoke on its own* in a shot with no lines at all, use
|
|
844
|
+
`replace_shot_dialogue` with `mute_only: true` (free; on clip-audio projects it
|
|
845
|
+
silences any narration in that shot too).
|
|
846
|
+
|
|
832
847
|
Four distinct causes; they need **opposite** fixes, so identify the family first.
|
|
833
848
|
|
|
834
849
|
1. **The line moved after the video was made.** If you edited `dialogue` on a
|
|
@@ -1161,6 +1176,7 @@ Full reference: https://api.shortreelai.com/docs/mcp
|
|
|
1161
1176
|
- `ready` 和生成数量只表示产物存在;当前有效数量使用 `get_pipeline_status.asset_versions_summary.*.current_effective`。换帧后旧视频仍可查看,但失效版本不能混入当前有效汇总。
|
|
1162
1177
|
- `get_asset_versions(storyboard_id)` 查看历史版本链接、依赖 ID/版本哈希及各自状态。历史没有快照时不从当前绑定伪造依赖。
|
|
1163
1178
|
- `get_image_dispatch(image_id)` 查一张镜头帧的派发台账:每张参考图的用途、所属角色、是否送达模型,派发前被剔的图在哪一步因什么被剔(如时代预检点名的冲突物件),以及最终发给模型的提示词。画面「不像某角色/少了某道具」时先查它,确认是参考没送到还是模型没画对,再决定改什么;`ledger` 不是 `full` 时缺失项为 `null`,不能当作已送达。
|
|
1179
|
+
- `get_stale_portrait_frames(episode_id)` 换定妆图后查影响范围:列出在用帧仍基于角色旧资产的镜头,每条附证据(`ledger-old-asset` / `references-previous-asset` / `portrait-born-after-frame`)。`unknown` 是证据不足,不是已过期,不要据此批量重出。先把 `stale` 清单和 `has_video` 告诉客户,由客户决定重出哪些镜——重出帧和视频都要付费。
|
|
1164
1180
|
- `get_asset_binding_repair_plan(episode_id)` 只返回缺失场景绑定的候选和依据,`applied=false`。必须逐项审核,不按名字自动回填,也不自动重新生成客户已完成的片子。
|
|
1165
1181
|
|
|
1166
1182
|
### Original product lettering
|
package/dist/tools/produce.js
CHANGED
|
@@ -527,6 +527,7 @@ export function registerProduceTools(server, client) {
|
|
|
527
527
|
})));
|
|
528
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`)));
|
|
529
529
|
server.tool('get_image_dispatch', '免费只读查询一张镜头帧的派发台账:实际用了哪几张参考图、每张的用途与所属角色、是否送达模型、没送达或派发前被剔除的是哪一步因什么被剔(如时代预检点名的冲突物件),以及真正发给图片模型的最终提示词。用于回答「到底用了哪张图、为什么画面不像」;先查清再决定是否重出,别靠猜反复付费重抽。ledger=partial/none 表示该图生成于台账上线前,缺失字段如实为 null。', { image_id: z.number().int().positive() }, async ({ image_id }) => jsonResult(await client.produceGet(`/images/${image_id}/dispatch`)));
|
|
530
|
+
server.tool('get_stale_portrait_frames', '免费只读查询一集里哪些镜头的在用首帧/尾帧,是拿角色已被换掉的旧资产(旧定妆图、旧设定图、旧身体/发型图)画的。换定妆图后用它确认影响范围,再由客户决定重出哪些镜(重出要付费,本工具不改任何数据)。verdict=stale 必附证据:ledger-old-asset(派发台账直接记录用了旧图)/ references-previous-asset(参考图里有该角色以前的旧资产)/ portrait-born-after-frame(当前定妆图晚于该帧诞生);证不了的标 unknown 并给原因,不当作已过期。has_video=true 表示该镜视频也基于旧帧,重出帧后视频需重生。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/stale-portrait-frames`)));
|
|
530
531
|
server.tool('get_asset_versions', '只读查询一个镜头的全部图片/视频版本、历史查看链接、依赖 ID 与版本哈希,以及已生成→与当前输入一致→审核有效→已采用四项独立事实。历史缺少依赖记录时显示未知,不补造快照。免费。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/asset-versions`)));
|
|
531
532
|
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`)));
|
|
532
533
|
server.tool('get_storyboards', '读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。' +
|
|
@@ -1338,7 +1339,14 @@ export function registerProduceTools(server, client) {
|
|
|
1338
1339
|
'★该镜已有对口型产物时,成片优先用对口型版,换轨不会生效。整集批量用 repair_episode_dialogue。' +
|
|
1339
1340
|
'\n★写回前会对产物复核(与 scan_dialogue_coverage 同一判据):换完仍断音(truncated)、重复念/多念(extra_speech)、' +
|
|
1340
1341
|
'念的不是台词(off_script)→ **不写回**、本次费用自动退回,返回错误说明哪一类——这类镜换音修不好,改用 regenerate_shot_video。' +
|
|
1341
|
-
'成功时返回 verify:verified=false 表示没判出来(转写失败/台词太短),照常写回但没复核过,自己听一下。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/dialogue-replace
|
|
1342
|
+
'成功时返回 verify:verified=false 表示没判出来(转写失败/台词太短),照常写回但没复核过,自己听一下。', { storyboard_id: z.number().int().positive(), mute_only: z.boolean().optional().describe('只静音、不重配(不扣费):把视频原声里的人声段静掉。用于厂商在**没有台词的镜里自己念出声**的情况。★原声剧上本镜的旁白也在原声里,会一起被静掉——要换旁白用 revoice_narration,别用它') }, async ({ storyboard_id, mute_only }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/dialogue-replace`, mute_only ? { mode: 'mute' } : {})));
|
|
1343
|
+
server.tool('revoice_narration', '换某镜**旁白/画外音**的声音(或改过旁白文字后重配)。**不重新生成视频**:保留画面与出镜台词,只把旁白那几段静掉、' +
|
|
1344
|
+
'按当前旁白声音重新合成并混回,再复核。同步调用,按 TTS 档(千字符)计费。' +
|
|
1345
|
+
'★先改好再调:想换声音先 set_character_voice 给「旁白」角色(没有就 design_voice 造一个),想改文字先 update_shot 改 dialogue 里的旁白行。' +
|
|
1346
|
+
'★纯旁白镜(本镜只有旁白)直接可用;**混合镜**(既有出镜台词又有旁白)要求分句数与视频里的语音段数一致,' +
|
|
1347
|
+
'对不上就报错不猜(猜错会把出镜台词一起静掉)——这时只能 regenerate_shot_video。' +
|
|
1348
|
+
'★台词栏没有旁白行会直接报错;厂商在无台词镜里乱念,用 replace_shot_dialogue 的 mute_only。' +
|
|
1349
|
+
'★写回后成片会直接用它(不需要额外开关),rerender_episode 重拼即可;复核不通过不写回,旁白合成费不退。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/dialogue-replace`, { mode: 'narration' })));
|
|
1342
1350
|
server.tool('repair_episode_dialogue', '★整集批量修「台词没念完/念了别的」。默认只修 scan_dialogue_coverage 判为有缺陷的镜' +
|
|
1343
1351
|
'(truncated/off_script/extra_speech);minor_gap 那一族是转写误差、原声本来是好的,不动。' +
|
|
1344
1352
|
'原理与 replace_shot_dialogue 相同:克隆音重配整句 + 静音原声段,**不重新生成视频**——' +
|
|
@@ -1353,9 +1361,11 @@ export function registerProduceTools(server, client) {
|
|
|
1353
1361
|
only_flagged: z.boolean().optional()
|
|
1354
1362
|
.describe('默认 true=只修被判有缺陷的镜。传 false 会把全集可替换镜都重配一遍——既花钱又可能把本来对的音频换坏,除非确有需要别关'),
|
|
1355
1363
|
force: z.boolean().optional().describe('对已有替换产物的镜也重跑(默认跳过,幂等)'),
|
|
1356
|
-
|
|
1364
|
+
mute_only: z.boolean().optional().describe('只静音、不重配(不扣费):把视频原声里的人声段静掉。用于厂商在**没有台词的镜里自己念出声**的情况。★原声剧上本镜的旁白也在原声里,会一起被静掉——要换旁白用 revoice_narration,别用它'),
|
|
1365
|
+
}, async ({ episode_id, only_flagged, force, mute_only }) => jsonResult(await client.producePost(`/episodes/${episode_id}/dialogue-repair`, {
|
|
1357
1366
|
...(only_flagged === undefined ? {} : { only_flagged }),
|
|
1358
1367
|
...(force ? { force: true } : {}),
|
|
1368
|
+
...(mute_only ? { mute_only: true } : {}),
|
|
1359
1369
|
})));
|
|
1360
1370
|
server.tool('get_dialogue_repair_status', '查台词修复的进度(免费)。repair_episode_dialogue 是后台异步串行跑的,用这个轮询。'
|
|
1361
1371
|
+ '\n★这个工具此前**不存在**,而 repair_episode_dialogue 的描述里却写着「进度用 '
|
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.111",
|
|
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.111 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -4043,6 +4043,9 @@
|
|
|
4043
4043
|
},
|
|
4044
4044
|
"force": {
|
|
4045
4045
|
"type": "boolean"
|
|
4046
|
+
},
|
|
4047
|
+
"mute_only": {
|
|
4048
|
+
"type": "boolean"
|
|
4046
4049
|
}
|
|
4047
4050
|
}
|
|
4048
4051
|
}
|
|
@@ -6663,6 +6666,53 @@
|
|
|
6663
6666
|
}
|
|
6664
6667
|
}
|
|
6665
6668
|
},
|
|
6669
|
+
"/episodes/{episode_id}/stale-portrait-frames": {
|
|
6670
|
+
"get": {
|
|
6671
|
+
"operationId": "get_stale_portrait_frames",
|
|
6672
|
+
"summary": "免费只读查询一集里哪些镜头的在用首帧/尾帧,是拿角色已被换掉的旧资产(旧定妆图、旧设定图、旧身体/发型图)画的",
|
|
6673
|
+
"description": "免费只读查询一集里哪些镜头的在用首帧/尾帧,是拿角色已被换掉的旧资产(旧定妆图、旧设定图、旧身体/发型图)画的。换定妆图后用它确认影响范围,再由客户决定重出哪些镜(重出要付费,本工具不改任何数据)。verdict=stale 必附证据:ledger-old-asset(派发台账直接记录用了旧图)/ references-previous-asset(参考图里有该角色以前的旧资产)/ portrait-born-after-frame(当前定妆图晚于该帧诞生);证不了的标 unknown 并给原因,不当作已过期。has_video=true 表示该镜视频也基于旧帧,重出帧后视频需重生。",
|
|
6674
|
+
"tags": [
|
|
6675
|
+
"episodes"
|
|
6676
|
+
],
|
|
6677
|
+
"parameters": [
|
|
6678
|
+
{
|
|
6679
|
+
"name": "episode_id",
|
|
6680
|
+
"in": "path",
|
|
6681
|
+
"required": true,
|
|
6682
|
+
"schema": {
|
|
6683
|
+
"type": "integer",
|
|
6684
|
+
"exclusiveMinimum": 0
|
|
6685
|
+
}
|
|
6686
|
+
}
|
|
6687
|
+
],
|
|
6688
|
+
"responses": {
|
|
6689
|
+
"200": {
|
|
6690
|
+
"description": "StarReel envelope",
|
|
6691
|
+
"content": {
|
|
6692
|
+
"application/json": {
|
|
6693
|
+
"schema": {
|
|
6694
|
+
"type": "object",
|
|
6695
|
+
"properties": {
|
|
6696
|
+
"code": {
|
|
6697
|
+
"type": "integer"
|
|
6698
|
+
},
|
|
6699
|
+
"message": {
|
|
6700
|
+
"type": "string"
|
|
6701
|
+
},
|
|
6702
|
+
"data": {
|
|
6703
|
+
"description": "Operation result payload"
|
|
6704
|
+
}
|
|
6705
|
+
}
|
|
6706
|
+
}
|
|
6707
|
+
}
|
|
6708
|
+
}
|
|
6709
|
+
},
|
|
6710
|
+
"402": {
|
|
6711
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
6712
|
+
}
|
|
6713
|
+
}
|
|
6714
|
+
}
|
|
6715
|
+
},
|
|
6666
6716
|
"/episodes/{episode_id}/storyboards": {
|
|
6667
6717
|
"get": {
|
|
6668
6718
|
"operationId": "get_storyboards",
|
|
@@ -9815,6 +9865,22 @@
|
|
|
9815
9865
|
}
|
|
9816
9866
|
}
|
|
9817
9867
|
],
|
|
9868
|
+
"requestBody": {
|
|
9869
|
+
"required": false,
|
|
9870
|
+
"content": {
|
|
9871
|
+
"application/json": {
|
|
9872
|
+
"schema": {
|
|
9873
|
+
"type": "object",
|
|
9874
|
+
"properties": {
|
|
9875
|
+
"mode": {
|
|
9876
|
+
"type": "string",
|
|
9877
|
+
"description": "(assembled by the client from tool args — see tool 'replace_shot_dialogue')"
|
|
9878
|
+
}
|
|
9879
|
+
}
|
|
9880
|
+
}
|
|
9881
|
+
}
|
|
9882
|
+
}
|
|
9883
|
+
},
|
|
9818
9884
|
"responses": {
|
|
9819
9885
|
"200": {
|
|
9820
9886
|
"description": "StarReel envelope",
|
|
@@ -9840,7 +9906,10 @@
|
|
|
9840
9906
|
"402": {
|
|
9841
9907
|
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
9842
9908
|
}
|
|
9843
|
-
}
|
|
9909
|
+
},
|
|
9910
|
+
"x-also-tools": [
|
|
9911
|
+
"revoice_narration"
|
|
9912
|
+
]
|
|
9844
9913
|
}
|
|
9845
9914
|
},
|
|
9846
9915
|
"/storyboards/{storyboard_id}/edit/generate": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.111",
|
|
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.111",
|
|
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.111",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|