@starreel/mcp 0.1.69 → 0.1.71
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 +12 -1
- package/dist/tools/produce.js +23 -2
- package/openapi.json +10 -4
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -72,7 +72,8 @@ announces a condensed version as MCP `instructions` at connect time.
|
|
|
72
72
|
| A finished **shot list** (per-shot seconds / shot size / camera move) | `get_storyboard_table_spec` (the contract: shot-size / camera-move vocabulary, body layout, text-card syntax, a prompt for the external AI) → `check_storyboard_table` (same parser as the import; clear `errors`, read every `warning` — a missing duration, an unrecognised shot size or an empty body all get imported as-is) → `import_storyboard_table` (defaults to `auto_complete`: one background batch fills the professional fields and expands every shot's platform-built base description into full image / video prompts — metered text, tell the customer first; `auto_complete: false` imports only) → `get_autofill_status` until `done` → `review_storyboards` | `rewrite_script` + `generate_storyboards` — strips every production parameter (measured: 8 shots / 36 s became 20 shots / 109 s); importing without the check; reviewing before the completion batch finishes (the token expires when shots change) |
|
|
73
73
|
| **Structured data** — their own tool / spreadsheet export, or an external AI producing JSON (cast + scenes + shots in one go) | `get_bulk_import_spec` (contract + template + worked example + enums, same source as the validator) → `check_bulk_import` (same zod schema; unresolved character / scene references, dead shots and stage directions inside dialogue are surfaced) → `bulk_import_storyboards` (`mode: "replace"` only with the customer's explicit OK; defaults to `auto_complete`: professional fields for every shot, full image / video prompts only for shots that had no `image_prompt` — prompts you supply yourself are kept verbatim — metered text, tell the customer first) → `get_autofill_status` until `done` → `review_storyboards` | converting the JSON to text for `import_storyboard_table`; hand-building shots with `update_shot`; reviewing before the completion batch finishes |
|
|
74
74
|
| Their own portraits / scene / prop / shot images | `upload_image` · `set_character_portrait` · `upload_scene_image` · `upload_prop_sheet` · `upload_shot_frame` | rendering a "fix" elsewhere and uploading it — use `generate_shot_frame` |
|
|
75
|
-
| Their own **footage** for a shot (screen recording, product b-roll, an existing clip) | `upload_shot_footage` → that shot is no longer AI-generated (frames/video skipped, final cut uses the clip as-is, duration written back from the clip); `clear_shot_footage`
|
|
75
|
+
| Their own **footage** for a shot (screen recording, product b-roll, an existing clip) | `upload_shot_footage` → that shot is no longer AI-generated (frames/video skipped, final cut uses the clip as-is, duration written back from the clip); **it overwrites whatever AI video that shot already had**, and afterwards every AI video call on it (including `edit_video_shot`) is refused with **409** until you `clear_shot_footage` or pass `replace_user_footage: true` | pasting an externally AI-generated clip to "fix" a shot — it carries none of this film's identity / style anchors; use `regenerate_shot_video` instead |
|
|
76
|
+
| A clip that should **drive the motion** of an AI shot (a blocking/previz pass, a dance or action reference) | `edit_video_shot` with `reference_video_urls` — the shot keeps its AI video and borrows the clip's movement. To make the clip itself the source and restyle it in place, `upload_shot_footage` it first, then `edit_video_shot` with `replace_user_footage: true` | `upload_shot_footage` alone — that registers the clip as the finished shot, so nothing gets restyled and every later AI call on it returns 409 |
|
|
76
77
|
| A scene plate that came out wrong (backdrop, era, light, layout) | `get_scene_prompt` → `update_scene` (`image_prompt`) → `regenerate_scene_image`; already-rendered shot frames still anchor on the old plate, so regenerate those shots too | re-running `generate_scene_images` (it only fills scenes that have **no** plate — it will not touch this one) |
|
|
77
78
|
| A voice sample / a required voice | `clone_voice` → `speak_with_voice` → `set_character_voice` / `assign_voices` | cloning without the rights-holder's consent |
|
|
78
79
|
| A song + lyrics | `create_drama` (`project_type: "mv"`) → `set_mv_lyrics` → `generate_mv_story` → `generate_mv_script` | `rewrite_script` (blocked for MV) |
|
|
@@ -213,6 +214,16 @@ content that will be rejected.
|
|
|
213
214
|
on hailuo-3 / wan3.0 / wan3.0-prime — `edit_video_shot` rejects
|
|
214
215
|
`start_sec`/`end_sec` on them. `edit_video_shot` also takes a per-call
|
|
215
216
|
`model` so one shot can be edited on a different engine than the drama's.
|
|
217
|
+
**Negative phrasing backfires.** If the receipt carries
|
|
218
|
+
`edit_instruction_negation_advisory`, the instruction contained phrases like
|
|
219
|
+
"don't use X" / "不能采用X". Video models read nouns as positive cues, so the
|
|
220
|
+
thing you forbade is often exactly what gets performed — the forbidden item is
|
|
221
|
+
the most salient one in the model's prior. It is advisory only (the job was
|
|
222
|
+
submitted), but on the next pass **replace the negation with a positive
|
|
223
|
+
description** — state what the shot should do (the opening gesture, where the
|
|
224
|
+
hands are, the beat timing). Measured: an instruction saying "do not use the
|
|
225
|
+
reference image's raised-arm pose" produced exactly that raised arm at the
|
|
226
|
+
opening, overriding the source video's motion.
|
|
216
227
|
**How to choose (guide the customer proactively)**: ① realistic live-action
|
|
217
228
|
dramas → `seedance-2.5` (best instruction-following and face detail), or
|
|
218
229
|
`hailuo-3` to cut cost to ~1/3 (slower, ~6 min/shot); ② stylized / animated /
|
package/dist/tools/produce.js
CHANGED
|
@@ -903,6 +903,11 @@ export function registerProduceTools(server, client) {
|
|
|
903
903
|
'登记后该镜不再 AI 出图/出视频(generate_videos 会跳过它,单镜重生会被拒),终拼原样使用,镜头时长按素材真实长度回写,' +
|
|
904
904
|
'首/尾帧从素材抽帧供帧链与预览用。免费。适用:宣传片里的到账界面录屏、后台大屏实录、产品实拍、客户已有的成片片段。' +
|
|
905
905
|
'⚠️ 别用它把外部 AI 生成的视频贴进来"改画面"——那不带本片身份锚/画风锚,人物·画风必漂;要改画面走 regenerate_shot_video。' +
|
|
906
|
+
'⚠️★**会覆盖这一镜已有的 AI 成片**(video_url 被替换成你传的素材;旧成片仍在但不再是本镜的在用视频,终拼将拼进素材)。' +
|
|
907
|
+
'⚠️★**要拿一段视频当「动作/运镜参考」让 AI 照着重绘,用的不是本工具**——那是 edit_video_shot 的 reference_video_urls' +
|
|
908
|
+
'(或 generate_videos 的参考视频通道)。本工具的语义是「这段视频**就是**成片本身,不再生成」。' +
|
|
909
|
+
'两者传的是同一个文件,结果天差地别:走本工具会让该镜从此被出视频守卫拒(含 edit_video_shot),' +
|
|
910
|
+
'得先 clear_shot_footage 或显式 replace_user_footage 才能继续。' +
|
|
906
911
|
'要换回 AI 生成请先 clear_shot_footage。', {
|
|
907
912
|
storyboard_id: z.number().int().positive(),
|
|
908
913
|
file_path: z.string().describe('本地视频路径(mp4/mov/webm/m4v,≤300MB)'),
|
|
@@ -926,6 +931,12 @@ export function registerProduceTools(server, client) {
|
|
|
926
931
|
server.tool('edit_video_shot', '确认后就地编辑某镜视频:按 instruction 改,可带参考图/视频/音频,或用 start_sec/end_sec 做区间替换。' +
|
|
927
932
|
'可用 model 为本次编辑单独选引擎(与剧引擎可不同):hailuo-3=MiniMax H3 强保真编辑约1/3成本;wan3.0/wan3.0-prime=WAN 3.0 强语义编辑约4折(环境可能跟随指令扩写);' +
|
|
928
933
|
'H3/WAN 均不支持 start_sec/end_sec 区间(传了会 400),编辑/续写的输入视频在 H3/WAN 上另按秒计费。' +
|
|
934
|
+
'\n★回执里出现 `edit_instruction_negation_advisory` = 你的指令里有**否定式约束**(「不能采用X」「不要出现X」)。' +
|
|
935
|
+
'视频模型把名词当正向线索,写「不要 X」往往反而把 X 演出来——被否定的那个动作/物件恰恰是模型先验里最显眼的。' +
|
|
936
|
+
'这不是拦截,任务已照常提交;但**下一轮改指令时务必删掉否定句,改成正向描述**(把该做什么写具体:起手动作、手的位置、每一拍的时值),' +
|
|
937
|
+
'否则同一个毛病会一直复现。已实测:客户写「不能采用参考图举手单脚的静态舞姿」,成片开头的抬臂手势就被参考图那个举手带跑了。' +
|
|
938
|
+
'\n★收到 **409「本镜是用户上传的实拍素材」** = 这一镜被 upload_shot_footage 登记成了实拍素材镜,不是模型或引擎的问题,换引擎重试无用。' +
|
|
939
|
+
'两条出路:要以该素材为源做 AI 重绘 → 带 replace_user_footage=true 重发;要恢复成普通 AI 镜 → 先 clear_shot_footage。' +
|
|
929
940
|
CONFIRM_HINT, {
|
|
930
941
|
storyboard_id: z.number().int().positive(),
|
|
931
942
|
quote_id: z.string().describe('来自 quote_edit_video_shot'),
|
|
@@ -936,13 +947,23 @@ export function registerProduceTools(server, client) {
|
|
|
936
947
|
reference_audio_urls: z.array(z.string()).max(3).optional(),
|
|
937
948
|
start_sec: z.number().optional().describe('区间替换起点秒'),
|
|
938
949
|
end_sec: z.number().optional().describe('区间替换终点秒'),
|
|
950
|
+
replace_user_footage: z.boolean().optional().describe('本镜是实拍素材镜(upload_shot_footage 传过)时,显式允许以它为源做编辑并用 AI 产物覆盖它。' +
|
|
951
|
+
'不传则被守卫拒(409,带中文出路)。想保留素材就别传,改用 clear_shot_footage 换回 AI 生成。'),
|
|
939
952
|
}, async ({ storyboard_id, ...rest }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/edit/generate`, rest)));
|
|
940
953
|
server.tool('quote_regenerate_shot_video', '报价:重生某镜视频要多少点。返回 quote_id。零扣费。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/regen/quote`)));
|
|
941
|
-
server.tool('regenerate_shot_video', '确认后重生某镜视频(可选新 prompt)。' +
|
|
954
|
+
server.tool('regenerate_shot_video', '确认后重生某镜视频(可选新 prompt)。' +
|
|
955
|
+
'\n★收到 **409「本镜是用户上传的实拍素材」** = 该镜被 upload_shot_footage 登记成实拍素材镜,不是模型问题,换引擎无用;' +
|
|
956
|
+
'要用 AI 视频覆盖它就带 replace_user_footage=true,要保留素材就别重生。' +
|
|
957
|
+
CONFIRM_HINT, {
|
|
942
958
|
storyboard_id: z.number().int().positive(),
|
|
943
959
|
quote_id: z.string().describe('来自 quote_regenerate_shot_video'),
|
|
944
960
|
prompt: z.string().optional().describe('可选:覆盖该镜视频 prompt'),
|
|
945
|
-
|
|
961
|
+
replace_user_footage: z.boolean().optional().describe('本镜是实拍素材镜时,显式允许用 AI 重生的视频覆盖它(不传则被守卫拒 409)。'),
|
|
962
|
+
}, async ({ storyboard_id, quote_id, prompt, replace_user_footage }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/regen/generate`, {
|
|
963
|
+
quote_id,
|
|
964
|
+
...(prompt ? { prompt } : {}),
|
|
965
|
+
...(replace_user_footage !== undefined ? { replace_user_footage } : {}),
|
|
966
|
+
})));
|
|
946
967
|
server.tool('split_shot', '把某镜按首尾帧拆成两镜(结构操作)。免费。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/split`)));
|
|
947
968
|
server.tool('trim_shot', '裁剪某镜时长(in_ms/out_ms)。免费;返回后需 rerender_episode 重拼成片。', {
|
|
948
969
|
storyboard_id: z.number().int().positive(),
|
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 → portraits & sheets → storyboards → 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). 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.71",
|
|
6
|
+
"description": "Turn a script into a finished, downloadable short-drama episode over REST.\n\nPipeline: script → AI rewrite → cast/scenes/props extraction → portraits & sheets → storyboards → 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). 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.71 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -8244,7 +8244,7 @@
|
|
|
8244
8244
|
"post": {
|
|
8245
8245
|
"operationId": "edit_video_shot",
|
|
8246
8246
|
"summary": "确认后就地编辑某镜视频:按 instruction 改,可带参考图/视频/音频,或用 start_sec/end_sec 做区间替换",
|
|
8247
|
-
"description": "确认后就地编辑某镜视频:按 instruction 改,可带参考图/视频/音频,或用 start_sec/end_sec 做区间替换。可用 model 为本次编辑单独选引擎(与剧引擎可不同):hailuo-3=MiniMax H3 强保真编辑约1/3成本;wan3.0/wan3.0-prime=WAN 3.0 强语义编辑约4折(环境可能跟随指令扩写);H3/WAN 均不支持 start_sec/end_sec 区间(传了会 400),编辑/续写的输入视频在 H3/WAN
|
|
8247
|
+
"description": "确认后就地编辑某镜视频:按 instruction 改,可带参考图/视频/音频,或用 start_sec/end_sec 做区间替换。可用 model 为本次编辑单独选引擎(与剧引擎可不同):hailuo-3=MiniMax H3 强保真编辑约1/3成本;wan3.0/wan3.0-prime=WAN 3.0 强语义编辑约4折(环境可能跟随指令扩写);H3/WAN 均不支持 start_sec/end_sec 区间(传了会 400),编辑/续写的输入视频在 H3/WAN 上另按秒计费。\n★回执里出现 `edit_instruction_negation_advisory` = 你的指令里有**否定式约束**(「不能采用X」「不要出现X」)。视频模型把名词当正向线索,写「不要 X」往往反而把 X 演出来——被否定的那个动作/物件恰恰是模型先验里最显眼的。这不是拦截,任务已照常提交;但**下一轮改指令时务必删掉否定句,改成正向描述**(把该做什么写具体:起手动作、手的位置、每一拍的时值),否则同一个毛病会一直复现。已实测:客户写「不能采用参考图举手单脚的静态舞姿」,成片开头的抬臂手势就被参考图那个举手带跑了。\n★收到 **409「本镜是用户上传的实拍素材」** = 这一镜被 upload_shot_footage 登记成了实拍素材镜,不是模型或引擎的问题,换引擎重试无用。两条出路:要以该素材为源做 AI 重绘 → 带 replace_user_footage=true 重发;要恢复成普通 AI 镜 → 先 clear_shot_footage。⚠️ 批量报价确认流程:先调对应的 quote_* 工具,把返回的 estimated_points 原样告诉用户,用户明确同意后,才用返回的 quote_id 调本工具。不要擅自确认。",
|
|
8248
8248
|
"tags": [
|
|
8249
8249
|
"storyboards"
|
|
8250
8250
|
],
|
|
@@ -8309,6 +8309,9 @@
|
|
|
8309
8309
|
},
|
|
8310
8310
|
"end_sec": {
|
|
8311
8311
|
"type": "number"
|
|
8312
|
+
},
|
|
8313
|
+
"replace_user_footage": {
|
|
8314
|
+
"type": "boolean"
|
|
8312
8315
|
}
|
|
8313
8316
|
},
|
|
8314
8317
|
"required": [
|
|
@@ -8836,7 +8839,7 @@
|
|
|
8836
8839
|
"post": {
|
|
8837
8840
|
"operationId": "regenerate_shot_video",
|
|
8838
8841
|
"summary": "确认后重生某镜视频(可选新 prompt)",
|
|
8839
|
-
"description": "确认后重生某镜视频(可选新 prompt)
|
|
8842
|
+
"description": "确认后重生某镜视频(可选新 prompt)。\n★收到 **409「本镜是用户上传的实拍素材」** = 该镜被 upload_shot_footage 登记成实拍素材镜,不是模型问题,换引擎无用;要用 AI 视频覆盖它就带 replace_user_footage=true,要保留素材就别重生。⚠️ 批量报价确认流程:先调对应的 quote_* 工具,把返回的 estimated_points 原样告诉用户,用户明确同意后,才用返回的 quote_id 调本工具。不要擅自确认。",
|
|
8840
8843
|
"tags": [
|
|
8841
8844
|
"storyboards"
|
|
8842
8845
|
],
|
|
@@ -8864,6 +8867,9 @@
|
|
|
8864
8867
|
},
|
|
8865
8868
|
"prompt": {
|
|
8866
8869
|
"type": "string"
|
|
8870
|
+
},
|
|
8871
|
+
"replace_user_footage": {
|
|
8872
|
+
"type": "boolean"
|
|
8867
8873
|
}
|
|
8868
8874
|
},
|
|
8869
8875
|
"required": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.71",
|
|
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.71",
|
|
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.71",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|