@starreel/mcp 0.1.96 → 0.1.97
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 +17 -3
- package/dist/tools/produce.js +30 -10
- package/openapi.json +31 -7
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -180,7 +180,13 @@ content that will be rejected.
|
|
|
180
180
|
and `typical_points` is what it usually costs. Give the user both — the upper
|
|
181
181
|
bound alone reads as far more expensive than the job really is, and the
|
|
182
182
|
typical figure alone under-funds the run. Fixed-price models (the Nano Banana
|
|
183
|
-
family) return the two equal.
|
|
183
|
+
family) return the two equal. **Storyboards** are a range for the same
|
|
184
|
+
reason: the AI decides how many shots the script needs, so the shot count
|
|
185
|
+
(`estimated_shots`) is an estimate. The storyboard quote also includes the
|
|
186
|
+
work that runs **automatically** right after breaking (filling empty shot
|
|
187
|
+
fields, one call per shot; a wardrobe timeline when the drama has wardrobe
|
|
188
|
+
assets) — see `price_breakdown`; it is billed together with the breakdown,
|
|
189
|
+
so quote the user the total. Other AI-generation steps (TTS, posters, sheets,
|
|
184
190
|
style locks, MV story/script …) have no quote and bill by usage — still tell
|
|
185
191
|
the user before running them. Never auto-approve large spends for the user.
|
|
186
192
|
|
|
@@ -570,8 +576,16 @@ When the frame or the motion is off in a way the business text cannot express,
|
|
|
570
576
|
edit the shot's prompt bodies directly: `get_shot_prompts` reads the current
|
|
571
577
|
`image_prompt` / `video_prompt` for one shot, `update_shot` writes them back.
|
|
572
578
|
Keep the `@char:N` / `@scene:M` markers the response lists under `asset_tokens`
|
|
573
|
-
|
|
574
|
-
|
|
579
|
+
as they are — but know what they do. They are a supplementary reference channel
|
|
580
|
+
for frame rendering only. Which characters' portraits and which scene plate are
|
|
581
|
+
injected is decided by the shot's bindings, `character_ids` and `scene_id`, which
|
|
582
|
+
`get_storyboards` returns per shot (with `character_bindings`, `prop_ids`,
|
|
583
|
+
`active_wardrobe_id`). Dropping a marker does not take a bound character out of
|
|
584
|
+
the frame; writing a marker for an unbound character pulls that character's image
|
|
585
|
+
in; a `#variant` marker is the only source of that variant image. To take someone
|
|
586
|
+
out of a shot, change `character_ids` (it is a full overwrite — read the current
|
|
587
|
+
list first). If they only speak off-screen, keep them bound and mark them
|
|
588
|
+
`voice_only` through `update_shot`'s `character_presence`. The prompt body
|
|
575
589
|
is only the part you write: the platform still layers identity anchors and
|
|
576
590
|
consistency constraints on top at generation time. Editing a prompt does not
|
|
577
591
|
re-generate anything — regenerate the shot afterwards.
|
package/dist/tools/produce.js
CHANGED
|
@@ -497,8 +497,11 @@ export function registerProduceTools(server, client) {
|
|
|
497
497
|
'定妆图齐了再调一次即批量出设定图。避免只出定妆图导致镜头漂移。图片步,按用量后付不欠费。' +
|
|
498
498
|
'轮询 get_characters 看 image/sheet_url 就绪;每调一次推进一步。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/portraits-and-sheets`)));
|
|
499
499
|
// ---------- 拆镜(storyboards) ----------
|
|
500
|
-
server.tool('quote_storyboards', '报价:把某一集的剧本拆成分镜(storyboards)
|
|
501
|
-
'
|
|
500
|
+
server.tool('quote_storyboards', '报价:把某一集的剧本拆成分镜(storyboards)要多少点。零扣费。返回 quote_id 与一个**区间**:' +
|
|
501
|
+
'estimated_points=预算上沿(按它备余额,拆到一半不会 402)、typical_points=通常花费——两个都告诉用户,' +
|
|
502
|
+
'只报上沿显得贵得离谱,只报典型又会让余额备不够。拆出几镜由 AI 按剧本决定(estimated_shots 是估算),故无法精确到点。' +
|
|
503
|
+
'★price_breakdown 里除「拆镜」外还有拆完**自动**触发的补全(每镜补空字段;有服装资产时排服装时间线)——' +
|
|
504
|
+
'它们随拆镜一起发生、会一起扣费,告诉用户总数时要含在内。拿到后征求同意,再用 quote_id 调 generate_storyboards。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/quote`)));
|
|
502
505
|
server.tool('generate_storyboards', '确认后拆镜:后台跑(分钟级),立即返回 status:generating。用 get_storyboards 轮询。' +
|
|
503
506
|
'★注意:拆镜会**替换整集所有已有分镜**(已调好/已出图的全丢、要重花钱重来)。每镜 5-7 秒是对 AI 出视频' +
|
|
504
507
|
'优化的**正常**时长,别因「一镜偏长」觉得有问题就重拆。已有分镜时后端会拦,确认重拆才带 confirm_replace=true。' +
|
|
@@ -536,7 +539,12 @@ export function registerProduceTools(server, client) {
|
|
|
536
539
|
'修复正路是删掉外部图改走 generate_shot_frame 平台重生。' +
|
|
537
540
|
'★若某镜带 reopen_pair_id:该镜首尾帧同时生成时只有一侧真的有问题、另一侧是无辜陪拒,' +
|
|
538
541
|
'原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,' +
|
|
539
|
-
'不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。'
|
|
542
|
+
'不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。' +
|
|
543
|
+
'★每镜还带**绑定**(只有 ID):character_ids(本镜绑定的角色)、character_bindings[{character_id,presence}]' +
|
|
544
|
+
'(presence=on_screen 在画面 / voice_only 只有声音、不进画面)、scene_id、prop_ids、active_wardrobe_id。' +
|
|
545
|
+
'出图注入谁的定妆图/哪张场景图/哪些道具图由这几项决定;角色名对照 get_characters、道具名对照 get_props。' +
|
|
546
|
+
'改绑用 update_shot 的 character_ids(★全量覆盖,先从这里读现值再改,漏传即解绑)与 character_presence;' +
|
|
547
|
+
'改完再读一次本工具核对。character_bindings 缺席 = 这次没读到(不是没绑),空数组才是没绑。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/storyboards`)));
|
|
540
548
|
// ---------- 在途运行状态(免费):区分「还在跑」和「已经死了」----------
|
|
541
549
|
server.tool('get_run_status', '(★免费·长耗时操作后必用)查这一集当前有没有 agent 正在跑。' +
|
|
542
550
|
'rewrite_script / extract_assets / generate_storyboards 都是**分钟级**后台任务,' +
|
|
@@ -1215,15 +1223,18 @@ export function registerProduceTools(server, client) {
|
|
|
1215
1223
|
const suffix = qs.toString() ? `?${qs.toString()}` : '';
|
|
1216
1224
|
return jsonResult(await client.produceGet(`/episodes/${episode_id}/dialogue-coverage${suffix}`));
|
|
1217
1225
|
});
|
|
1218
|
-
server.tool('update_shot', '逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、时长(duration)、成片变速(speed_factor)
|
|
1226
|
+
server.tool('update_shot', '逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、时长(duration)、成片变速(speed_factor)、角色绑定(character_ids)与画外音标记(character_presence)。只传要改的字段、其余不动。' +
|
|
1219
1227
|
'**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);' +
|
|
1220
|
-
'改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards
|
|
1228
|
+
'改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids)。' +
|
|
1221
1229
|
'★★原声镜(厂商原生音频)改 dialogue 后,本镜视频会被标记「待重生」——因为台词是**烤进视频人声**的,' +
|
|
1222
1230
|
'不重生就终拼,成片里念的仍是改动前的台词(典型现象:台词像是跑到了别的镜头上)。' +
|
|
1223
1231
|
'compose_episode 会以 advisory `stale_video_after_edit` 列出这些镜;正确处置是先 regenerate_shot_video 再终拼。' +
|
|
1224
1232
|
'★也可直接改本镜的四条提示词正文(image_prompt/video_prompt/first_frame_prompt/last_frame_prompt):' +
|
|
1225
1233
|
'改前先用 get_shot_prompts 读现值,' +
|
|
1226
|
-
'别凭空覆盖——正文里的 @char:N / @scene:M
|
|
1234
|
+
'别凭空覆盖——正文里的 @char:N / @scene:M 是出图时的补充参考标记,照原样保留即可。' +
|
|
1235
|
+
'★注入谁的定妆图由 character_ids 决定、背景由 scene_id 决定:删标记不会让已绑定的人从画面消失,' +
|
|
1236
|
+
'要让某人不出现就改 character_ids,他只有声音(画外音)就用 character_presence 标 voice_only;' +
|
|
1237
|
+
'反过来别给未绑定的角色写 @char 标记——会把他的图注入进来。' +
|
|
1227
1238
|
'★★【出尾帧被拦下就是来改这里】出尾帧若报「此镜标为状态改变,但没有任何地方说明结束时是什么样子」' +
|
|
1228
1239
|
'(TERMINAL_DESC_GATE),修法是把**结束时画面是什么样**写进本镜 last_frame_prompt,然后重新出尾帧。' +
|
|
1229
1240
|
'别去重试出图——这类镜(action_motion_class=state_change 却没写终态)的尾帧历史成功率 9.4%,' +
|
|
@@ -1232,6 +1243,14 @@ export function registerProduceTools(server, client) {
|
|
|
1232
1243
|
storyboard_id: z.number().int().positive(),
|
|
1233
1244
|
character_ids: z.array(z.number().int().positive()).optional()
|
|
1234
1245
|
.describe('本镜出场角色 ID 列表(★全量覆盖式,非增量,漏传的角色会被解绑)。决定出图时注入哪些角色的定妆图/设定图——非人角色(动物/生物)也必须绑定,否则形象会漂移。id 必须来自当前集已关联角色'),
|
|
1246
|
+
character_presence: z.array(z.object({
|
|
1247
|
+
character_id: z.number().int().positive(),
|
|
1248
|
+
presence: z.enum(['on_screen', 'voice_only']),
|
|
1249
|
+
})).optional()
|
|
1250
|
+
.describe('画外音标记:[{character_id, presence}]。voice_only = 这一镜他只有声音、人不在画面(画外音/门外说话/电话那头)——' +
|
|
1251
|
+
'出图时他的定妆图、人脸锁、站位、主体脸锚全部跳过,台词与配音不受影响;on_screen = 恢复在画面。' +
|
|
1252
|
+
'角色必须在本镜绑定里(可与 character_ids 同一请求,先改绑再标)。只列要改的角色,没列的不动。' +
|
|
1253
|
+
'★完全没出现在画面、台词也不是他说的 → 直接从 character_ids 去掉,不用标 voice_only'),
|
|
1235
1254
|
title: z.string().optional().describe('镜头标题'),
|
|
1236
1255
|
description: z.string().optional().describe('画面描述'),
|
|
1237
1256
|
shot_type: z.string().optional().describe('景别(如 特写/中景/全景/远景)'),
|
|
@@ -1246,7 +1265,7 @@ export function registerProduceTools(server, client) {
|
|
|
1246
1265
|
shot_intent: z.string().optional().describe('这镜为什么存在(叙事意图)'),
|
|
1247
1266
|
duration: z.number().positive().optional().describe('本镜时长(秒,可带小数如 2.5)。上限=本剧视频引擎的单镜上限,超出直接拒并告知上限(更长内容用 split_shot 拆镜)。有台词时平台按语速律只抬不降,抬了会在回执 speech_duration_note 里说。★改时长不会自动重出视频:已有视频仍是旧长度,要厂商按新时长出就 regenerate_shot_video(报价按新时长算)。★别拿加长治「动作太慢」——同样的动作摊到更长时间里只会更慢,见 qa_tools「动作太慢」'),
|
|
1248
1267
|
speed_factor: z.number().positive().nullable().optional().describe('成片变速:<1 慢镜、>1 快放、null 清除(0.5–2.0,越界被钳到范围内)。只在终拼/剪映导出时变速播放(画面 setpts + 声音 atempo,音高不变),**不重出视频、不扣费**,但会改变本镜在成片里占的时长。适合做慢镜/升格氛围;治不了「动作没演出来」——那是视频内容本身,要改 video_prompt 重出;也治不了一镜塞太多动作(action_overload)——那要拆镜重出。有台词的镜慎用(人声也跟着变快变慢)'),
|
|
1249
|
-
image_prompt: z.string().optional().describe('首帧画面提示词**正文**(全量覆盖本镜现值)。★先 get_shot_prompts 读现值再改;★原样保留其中的 @char:N / @scene:M
|
|
1268
|
+
image_prompt: z.string().optional().describe('首帧画面提示词**正文**(全量覆盖本镜现值)。★先 get_shot_prompts 读现值再改;★原样保留其中的 @char:N / @scene:M 补充参考标记(注入谁由 character_ids / scene_id 决定,删标记不会让已绑定的人消失)。出图时平台会在正文之上再拼身份锚与一致性约束,不必你写。★写法坑:别写「no X / without X / 不要 X / 没有 X」这类否定式约束——图像模型把名词当正向线索,反而把 X 画出来;要正向写出那块画面该有什么(材质/形状/颜色/远近)。保存响应带 image_prompt_negation_advisory 即命中,按其 note 改写'),
|
|
1250
1269
|
video_prompt: z.string().optional().describe('视频(动态/运镜/表演)提示词**正文**(全量覆盖本镜现值)。★同 image_prompt:先读现值、保留 @char/@scene 标记'),
|
|
1251
1270
|
first_frame_prompt: z.string().optional().describe('本镜**开始时**画面是什么样(首帧目标状态正文,全量覆盖现值)。送达提示词里作为 [START FRAME] 段排在最前,优先级高于 image_prompt——所以 image_prompt 改了不生效时,往往是这条在压着它。★同 image_prompt:先 get_shot_prompts 读现值、原样保留 @char/@scene 标记'),
|
|
1252
1271
|
last_frame_prompt: z.string().optional().describe('本镜**结束时**画面是什么样(尾帧目标状态正文,全量覆盖现值)。送达提示词里作为 [END FRAME] 段。★★出尾帧被 TERMINAL_DESC_GATE 拦下时就是补这一条:写清结束时的状态(什么变了/变成什么样),再重新出尾帧。不补而直接重试必然重复被拒且照常扣费。get_shot_prompts 的 terminal_desc_missing=true 即本镜需要它'),
|
|
@@ -1258,9 +1277,10 @@ export function registerProduceTools(server, client) {
|
|
|
1258
1277
|
'first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。' +
|
|
1259
1278
|
'★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——' +
|
|
1260
1279
|
'出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。' +
|
|
1261
|
-
'★逐镜按需:改哪镜读哪镜(整集列表 get_storyboards
|
|
1262
|
-
'★返回的 asset_tokens
|
|
1263
|
-
'
|
|
1280
|
+
'★逐镜按需:改哪镜读哪镜(整集列表 get_storyboards 不含提示词)。' +
|
|
1281
|
+
'★返回的 asset_tokens 是正文里的补充参考标记(@char:N / @scene:M),改写时原样保留即可:' +
|
|
1282
|
+
'本镜注入谁的定妆图由绑定决定(get_storyboards 的 character_ids / scene_id),删标记不会让已绑定的人消失;' +
|
|
1283
|
+
'带 #变体 的标记是那张变体图的唯一来源;给未绑定的角色写标记会把他的图注入进来。' +
|
|
1264
1284
|
'★这是分镜表里的正文层;出图/出视频时平台还会在其上拼身份锚、一致性约束与参考图指令(不在此处,也无需你写)。' +
|
|
1265
1285
|
'改完提示词不会自动重出图/视频,要让画面跟上得再 regen 对应镜。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/prompts`)));
|
|
1266
1286
|
server.tool('rerender_episode', '按当前 timeline 重拼成片(改完镜/裁剪后用)。**免费**(纯 ffmpeg+COS),后台异步。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/re-render`)));
|
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.97",
|
|
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.97 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -6248,7 +6248,7 @@
|
|
|
6248
6248
|
"get": {
|
|
6249
6249
|
"operationId": "get_storyboards",
|
|
6250
6250
|
"summary": "读某一集的分镜列表(供审阅/查进度)",
|
|
6251
|
-
"description": "读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。★每镜带**台词与说话人**:dialogue(原文,无台词为 null)、dialogue_lines([{speaker,text}] 逐行,与字幕/配音同一个解析器拆的——这里的 speaker 就是成片里被配音的那个;舞台提示已剥),以及 is_key_moment(1=关键镜,走高端图模)与 emotion_intensity(1-10)。核对「台词有没有丢/谁说的/关键镜是哪几镜/情绪曲线」用这一次调用即可,不用逐镜拉;update_shot 改完台词也在这里核对。画面/视频/首尾帧提示词仍只在 get_shot_prompts 逐镜读。★每镜还带**结构化状态**:frame_status/video_status(ready/pending/authorizing/rejected/failed/none/not_required)、★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。照 retryable 判该重试还是该改内容,别解析中文。★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。★若某镜带 degraded_frames:[{frame_type,reason,reason_label,since,hint}],表示该帧是系统在同因连拒熔断后**放行**的(判据照记未拒),URL 上与干净帧无区别但需人工复核;不满意按 hint 修正输入后 generate_shot_frame 重生该帧。★terminal_desc_missing=true:该镜标为「状态改变」却三处都没说结束时什么样——**出尾帧前**就能看出来,现在整集一次拿到(此前只有 get_shot_prompts 能逐镜问,一集几十次没人会去问)。先 update_shot 把结束状态写进 last_frame_prompt 再出尾帧:照现状硬出的历史成功率 9.4%,写了终态的 40.2%,而每次被拒都照常扣费。确实该「几乎不变」的镜才用 generate_shot_frame 的 allow_missing_terminal 放行。★first_frame_source/last_frame_source='upload' 表示该帧是**外部上传图**(绕开了身份锚/画风锚/best-of-N/帧审计整条质量链路)——人物·服装·画风漂移排查先看这些镜;外部图导致的漂移不是平台生成质量问题,修复正路是删掉外部图改走 generate_shot_frame 平台重生。★若某镜带 reopen_pair_id:该镜首尾帧同时生成时只有一侧真的有问题、另一侧是无辜陪拒,原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable
|
|
6251
|
+
"description": "读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。★每镜带**台词与说话人**:dialogue(原文,无台词为 null)、dialogue_lines([{speaker,text}] 逐行,与字幕/配音同一个解析器拆的——这里的 speaker 就是成片里被配音的那个;舞台提示已剥),以及 is_key_moment(1=关键镜,走高端图模)与 emotion_intensity(1-10)。核对「台词有没有丢/谁说的/关键镜是哪几镜/情绪曲线」用这一次调用即可,不用逐镜拉;update_shot 改完台词也在这里核对。画面/视频/首尾帧提示词仍只在 get_shot_prompts 逐镜读。★每镜还带**结构化状态**:frame_status/video_status(ready/pending/authorizing/rejected/failed/none/not_required)、★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。照 retryable 判该重试还是该改内容,别解析中文。★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。★若某镜带 degraded_frames:[{frame_type,reason,reason_label,since,hint}],表示该帧是系统在同因连拒熔断后**放行**的(判据照记未拒),URL 上与干净帧无区别但需人工复核;不满意按 hint 修正输入后 generate_shot_frame 重生该帧。★terminal_desc_missing=true:该镜标为「状态改变」却三处都没说结束时什么样——**出尾帧前**就能看出来,现在整集一次拿到(此前只有 get_shot_prompts 能逐镜问,一集几十次没人会去问)。先 update_shot 把结束状态写进 last_frame_prompt 再出尾帧:照现状硬出的历史成功率 9.4%,写了终态的 40.2%,而每次被拒都照常扣费。确实该「几乎不变」的镜才用 generate_shot_frame 的 allow_missing_terminal 放行。★first_frame_source/last_frame_source='upload' 表示该帧是**外部上传图**(绕开了身份锚/画风锚/best-of-N/帧审计整条质量链路)——人物·服装·画风漂移排查先看这些镜;外部图导致的漂移不是平台生成质量问题,修复正路是删掉外部图改走 generate_shot_frame 平台重生。★若某镜带 reopen_pair_id:该镜首尾帧同时生成时只有一侧真的有问题、另一侧是无辜陪拒,原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。★每镜还带**绑定**(只有 ID):character_ids(本镜绑定的角色)、character_bindings[{character_id,presence}](presence=on_screen 在画面 / voice_only 只有声音、不进画面)、scene_id、prop_ids、active_wardrobe_id。出图注入谁的定妆图/哪张场景图/哪些道具图由这几项决定;角色名对照 get_characters、道具名对照 get_props。改绑用 update_shot 的 character_ids(★全量覆盖,先从这里读现值再改,漏传即解绑)与 character_presence;改完再读一次本工具核对。character_bindings 缺席 = 这次没读到(不是没绑),空数组才是没绑。",
|
|
6252
6252
|
"tags": [
|
|
6253
6253
|
"episodes"
|
|
6254
6254
|
],
|
|
@@ -6664,7 +6664,7 @@
|
|
|
6664
6664
|
"post": {
|
|
6665
6665
|
"operationId": "quote_storyboards",
|
|
6666
6666
|
"summary": "报价:把某一集的剧本拆成分镜(storyboards)要多少点",
|
|
6667
|
-
"description": "报价:把某一集的剧本拆成分镜(storyboards)
|
|
6667
|
+
"description": "报价:把某一集的剧本拆成分镜(storyboards)要多少点。零扣费。返回 quote_id 与一个**区间**:estimated_points=预算上沿(按它备余额,拆到一半不会 402)、typical_points=通常花费——两个都告诉用户,只报上沿显得贵得离谱,只报典型又会让余额备不够。拆出几镜由 AI 按剧本决定(estimated_shots 是估算),故无法精确到点。★price_breakdown 里除「拆镜」外还有拆完**自动**触发的补全(每镜补空字段;有服装资产时排服装时间线)——它们随拆镜一起发生、会一起扣费,告诉用户总数时要含在内。拿到后征求同意,再用 quote_id 调 generate_storyboards。",
|
|
6668
6668
|
"tags": [
|
|
6669
6669
|
"episodes"
|
|
6670
6670
|
],
|
|
@@ -8685,8 +8685,8 @@
|
|
|
8685
8685
|
"/storyboards/{storyboard_id}": {
|
|
8686
8686
|
"put": {
|
|
8687
8687
|
"operationId": "update_shot",
|
|
8688
|
-
"summary": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、时长(duration)、成片变速(speed_factor)
|
|
8689
|
-
"description": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、时长(duration)、成片变速(speed_factor)
|
|
8688
|
+
"summary": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、时长(duration)、成片变速(speed_factor)、角色绑定(character_ids)与画外音标记(character_presence)",
|
|
8689
|
+
"description": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、时长(duration)、成片变速(speed_factor)、角色绑定(character_ids)与画外音标记(character_presence)。只传要改的字段、其余不动。**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids)。★★原声镜(厂商原生音频)改 dialogue 后,本镜视频会被标记「待重生」——因为台词是**烤进视频人声**的,不重生就终拼,成片里念的仍是改动前的台词(典型现象:台词像是跑到了别的镜头上)。compose_episode 会以 advisory `stale_video_after_edit` 列出这些镜;正确处置是先 regenerate_shot_video 再终拼。★也可直接改本镜的四条提示词正文(image_prompt/video_prompt/first_frame_prompt/last_frame_prompt):改前先用 get_shot_prompts 读现值,别凭空覆盖——正文里的 @char:N / @scene:M 是出图时的补充参考标记,照原样保留即可。★注入谁的定妆图由 character_ids 决定、背景由 scene_id 决定:删标记不会让已绑定的人从画面消失,要让某人不出现就改 character_ids,他只有声音(画外音)就用 character_presence 标 voice_only;反过来别给未绑定的角色写 @char 标记——会把他的图注入进来。★★【出尾帧被拦下就是来改这里】出尾帧若报「此镜标为状态改变,但没有任何地方说明结束时是什么样子」(TERMINAL_DESC_GATE),修法是把**结束时画面是什么样**写进本镜 last_frame_prompt,然后重新出尾帧。别去重试出图——这类镜(action_motion_class=state_change 却没写终态)的尾帧历史成功率 9.4%,有终态描述的是 40.2%;不补描述就重生,送厂商的提示词里根本没有终态段,画出来仍和首帧一样、还是会被拒,而每次重生都照常扣费。get_shot_prompts 的 terminal_desc_missing=true 就是这个信号。",
|
|
8690
8690
|
"tags": [
|
|
8691
8691
|
"storyboards"
|
|
8692
8692
|
],
|
|
@@ -8715,6 +8715,30 @@
|
|
|
8715
8715
|
"exclusiveMinimum": 0
|
|
8716
8716
|
}
|
|
8717
8717
|
},
|
|
8718
|
+
"character_presence": {
|
|
8719
|
+
"type": "array",
|
|
8720
|
+
"items": {
|
|
8721
|
+
"type": "object",
|
|
8722
|
+
"properties": {
|
|
8723
|
+
"character_id": {
|
|
8724
|
+
"type": "integer",
|
|
8725
|
+
"exclusiveMinimum": 0
|
|
8726
|
+
},
|
|
8727
|
+
"presence": {
|
|
8728
|
+
"type": "string",
|
|
8729
|
+
"enum": [
|
|
8730
|
+
"on_screen",
|
|
8731
|
+
"voice_only"
|
|
8732
|
+
]
|
|
8733
|
+
}
|
|
8734
|
+
},
|
|
8735
|
+
"required": [
|
|
8736
|
+
"character_id",
|
|
8737
|
+
"presence"
|
|
8738
|
+
],
|
|
8739
|
+
"additionalProperties": false
|
|
8740
|
+
}
|
|
8741
|
+
},
|
|
8718
8742
|
"title": {
|
|
8719
8743
|
"type": "string"
|
|
8720
8744
|
},
|
|
@@ -9406,7 +9430,7 @@
|
|
|
9406
9430
|
"get": {
|
|
9407
9431
|
"operationId": "get_shot_prompts",
|
|
9408
9432
|
"summary": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 u",
|
|
9409
|
-
"description": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。★逐镜按需:改哪镜读哪镜(整集列表 get_storyboards
|
|
9433
|
+
"description": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。★逐镜按需:改哪镜读哪镜(整集列表 get_storyboards 不含提示词)。★返回的 asset_tokens 是正文里的补充参考标记(@char:N / @scene:M),改写时原样保留即可:本镜注入谁的定妆图由绑定决定(get_storyboards 的 character_ids / scene_id),删标记不会让已绑定的人消失;带 #变体 的标记是那张变体图的唯一来源;给未绑定的角色写标记会把他的图注入进来。★这是分镜表里的正文层;出图/出视频时平台还会在其上拼身份锚、一致性约束与参考图指令(不在此处,也无需你写)。改完提示词不会自动重出图/视频,要让画面跟上得再 regen 对应镜。",
|
|
9410
9434
|
"tags": [
|
|
9411
9435
|
"storyboards"
|
|
9412
9436
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.97",
|
|
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.97",
|
|
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.97",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|