@starreel/mcp 0.1.30 → 0.1.32
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/dist/tools/produce.js +29 -7
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/tools/produce.js
CHANGED
|
@@ -41,6 +41,9 @@ const WORKFLOW_HINT = '★三档执行策略(别把三档混着问客户):' +
|
|
|
41
41
|
'★图片模型默认香蕉2(Nano Banana 2 = gemini-3.1-flash-image·整剧统一画风):create_drama/update_project_settings 的 image_model 设,不传即默认香蕉2;' +
|
|
42
42
|
'可选 gemini-3-pro-image(香蕉Pro·更精细·175点)/gemini-3.1-flash-lite-image(香蕉2 Lite·便宜·31点)/doubao-seedream-5-0-260128(Seedream5.0)/gpt-image-2(ChatGPT Image2);generate_frames 可临时覆盖某次。' +
|
|
43
43
|
'★图片生成慢≠失败:每张几十秒~数分钟、整集可能十几分钟,轮询 get_storyboards 看 frame_status——pending=还在生成(耐心等、别重复调 generate_frames 白花钱)、ready=完成、failed=才是真失败。' +
|
|
44
|
+
'★改某一镜画面 / 换定妆图后要让新图生效,走**单镜重生 generate_shot_frame**(平台自动带该镜身份锚·场景道具参考·画风锚,保全片一致);' +
|
|
45
|
+
'generate_frames 只批量补「缺帧」的镜、已有首帧的镜跳过(正常、不是"拒绝"),尾帧用 frame_type=last_frame 可批量补。换定妆图(set_character_portrait)后响应里的 stale_frames 就是被旧图污染、需逐镜重生的镜。' +
|
|
46
|
+
'★绝不用外部工具自制首尾帧再 upload_shot_frame 来"改画面"——外部图无身份锚/画风锚,人物·服装·画风必漂,那才是废片根源;upload_shot_frame 只用于客户自有真实素材。' +
|
|
44
47
|
'③【可选增强·AI 主动提示客户·报价确认才做】美术圣经生成/视觉锁抽取/色彩脚本/动作模板/场景图/场景组/口型/海报/音效/配乐/字幕翻译——' +
|
|
45
48
|
'这些提升一致性/质量、大多收费。★AI 应主动告知客户这些可做并给报价,客户确认才跑;既不默默跳过、也不擅自扣费。' +
|
|
46
49
|
'★两条锁定纪律:①**画幅比例**在 create_drama 即定、drama 级锁定,之后所有出图/出视频/成片都用它、**别中途改**' +
|
|
@@ -196,8 +199,13 @@ export function registerProduceTools(server, client) {
|
|
|
196
199
|
'原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,' +
|
|
197
200
|
'不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/storyboards`)));
|
|
198
201
|
// ---------- 分镜级 AI 操作:2 个免费质量闸 + 3 个 AI 增强(★都在出图前做)----------
|
|
199
|
-
server.tool('run_precheck', '(★推荐·免费质量闸)
|
|
200
|
-
'强烈建议 generate_frames/generate_videos
|
|
202
|
+
server.tool('run_precheck', '(★推荐·免费质量闸)出图/出视频前跑生成前预检,把会被拒的镜提前揪出。免费、不扣费。' +
|
|
203
|
+
'强烈建议 generate_frames/generate_videos 前调,防白花钱被拒。\n' +
|
|
204
|
+
'查这几类:①真人肖像/克隆音色授权 ②图像审核高危词 ③配音覆盖与大空档 ' +
|
|
205
|
+
'④**指令自相矛盾(kind=prompt-conflict)**——同一镜里互斥的要求(如宽景别却标了特写主体、' +
|
|
206
|
+
'既要站立又要坐姿),这类镜**任何正确的图都满足不了**,不改就会反复被拒并反复扣费,' +
|
|
207
|
+
'出现时应先按提示改分镜再出图,而不是重试。\n' +
|
|
208
|
+
'⚠️ 它**不**检查首帧是否处在"动作发生前"(平台暂无该契约字段),也不替代 get_health_report。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/precheck`)));
|
|
201
209
|
server.tool('get_health_report', '(★推荐·免费诊断)读分镜出体检报告:时长超标/母题覆盖不足/问题镜。纯读、免费。出图前查,识别问题先改再出、别出了片才发现。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/health-report`)));
|
|
202
210
|
server.tool('autofill_storyboards', '(推荐)AI 一键给全集分镜补全空缺字段,默认**只填空缺、不覆盖已有**(overwrite=true 才覆盖)。提升分镜完整性,出图前做。后台异步,文本步后付。', { episode_id: z.number().int().positive(), overwrite: z.boolean().optional().describe('true=覆盖已有字段(默认 false 只填空缺)') }, async ({ episode_id, overwrite }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/autofill`, overwrite ? { overwrite } : {})));
|
|
203
211
|
server.tool('enhance_shot_prompts', '(可选增强·★非必须·有副作用)AI 批量增强全集 image_prompt。★会**改写已有 prompt**(含手调的);且**务必 generate_frames 之前**做——' +
|
|
@@ -206,16 +214,25 @@ export function registerProduceTools(server, client) {
|
|
|
206
214
|
'★前置:该剧已设 motifs(没设=空操作);会**改结尾镜 action/描述**,务必出图前做(否则结尾镜已出图会陈旧)。后台异步,文本步后付。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/complete-motifs`)));
|
|
207
215
|
// ---------- 出首帧(frames) ----------
|
|
208
216
|
server.tool('quote_frames', '报价:给某一集批量出帧要多少点。返回 frames_to_generate、estimated_points、quote_id。零扣费。' +
|
|
209
|
-
'frame_type 默认 first_frame(只给缺首帧的镜出);last_frame 只给「已有首帧且缺尾帧」的镜出;both 两者都补。'
|
|
217
|
+
'frame_type 默认 first_frame(只给缺首帧的镜出);last_frame 只给「已有首帧且缺尾帧」的镜出;both 两者都补。' +
|
|
218
|
+
'★报价按**实际会用的模型与分辨率**分档,响应带 price_breakdown(逐档张数与单价);' +
|
|
219
|
+
'打算在 generate_frames 里临时换模型,报价时就要把同一个 image_model 传进来,否则两边不是一个价。', {
|
|
210
220
|
episode_id: z.number().int().positive(),
|
|
211
221
|
frame_type: FRAME_TYPE_ARG.optional().describe('默认 first_frame;last_frame=补尾帧;both=首尾都补'),
|
|
212
|
-
|
|
222
|
+
image_model: z.string().optional().describe('按这个模型报价(须与随后 generate_frames 传的一致;不传=用 drama 级设定,默认香蕉2)'),
|
|
223
|
+
}, async ({ episode_id, frame_type, image_model }) => jsonResult(await client.producePost(`/episodes/${episode_id}/frames/quote`, { frame_type, image_model })));
|
|
213
224
|
server.tool('generate_frames', '确认后批量出帧:后台异步。用 get_storyboards 轮询,first_frame_image/last_frame_image 逐镜填充即完成。' +
|
|
214
225
|
'★图片生成较慢——每张几十秒到数分钟(尤其高清模型),整集可能十几分钟。轮询看 frame_status:' +
|
|
215
226
|
'**pending=还在生成(继续耐心等,别当失败、别重复调 generate_frames,重复触发=白花钱)**、' +
|
|
216
227
|
'ready=完成、failed=才是真失败。别因为「等了一会儿还没出」就判定生成失败或重试。' +
|
|
217
228
|
'出视频前必须先出帧,否则视频会退化成无一致性锚点的画面。' +
|
|
218
|
-
'frame_type 要与 quote_frames 用的一致(默认 first_frame)
|
|
229
|
+
'frame_type 要与 quote_frames 用的一致(默认 first_frame)。' +
|
|
230
|
+
'★这是**批量补缺帧**:只给「缺该帧」的镜出图,已有首帧的镜会跳过——这是正常设计、不是"系统拒绝重出"。' +
|
|
231
|
+
'要**重出/重画某一镜已有的帧**(如换了定妆图要让新图生效),用 generate_shot_frame(单镜重生,平台带身份锚),不是这个工具、更不是自制图 upload_shot_frame。' +
|
|
232
|
+
'★尾帧能批量出:frame_type=last_frame 会给「已有首帧且缺尾帧」的镜批量补尾帧(尾帧只在想固定某镜结尾画面/大运镜时才需,常规只出首帧)。' +
|
|
233
|
+
'★响应里的 frames_planned 是**计划数,不是已成功数**——本接口在后台派发循环开跑之前就返回了。' +
|
|
234
|
+
'真实进度只看 get_storyboards 的 first_frame_image / get_jobs 的逐条生成记录;' +
|
|
235
|
+
'余额不足(402)会中止整批,此时轮询再久也不会有结果,应去查余额而不是继续等。' + CONFIRM_HINT, {
|
|
219
236
|
episode_id: z.number().int().positive(),
|
|
220
237
|
quote_id: z.string().describe('来自 quote_frames'),
|
|
221
238
|
frame_type: FRAME_TYPE_ARG.optional().describe('默认 first_frame,须与报价时一致'),
|
|
@@ -225,10 +242,12 @@ export function registerProduceTools(server, client) {
|
|
|
225
242
|
}, async ({ episode_id, quote_id, frame_type, image_model }) => jsonResult(await client.producePost(`/episodes/${episode_id}/frames/generate`, { quote_id, frame_type, image_model })));
|
|
226
243
|
// ---------- 单镜出帧/重生(改某一镜的画面走这里,别去外部平台出图再传回来) ----------
|
|
227
244
|
server.tool('quote_shot_frame', '报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。' +
|
|
228
|
-
'客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。'
|
|
245
|
+
'客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。' +
|
|
246
|
+
'★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。', {
|
|
229
247
|
storyboard_id: z.number().int().positive(),
|
|
230
248
|
frame_type: FRAME_TYPE_ARG.optional().describe('默认 first_frame;both=首尾各一张'),
|
|
231
|
-
|
|
249
|
+
image_model: z.string().optional().describe('按这个模型报价(须与随后 generate_shot_frame 传的一致;不传=用 drama 级设定,默认香蕉2)'),
|
|
250
|
+
}, async ({ storyboard_id, frame_type, image_model }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/quote`, { frame_type, image_model })));
|
|
232
251
|
server.tool('generate_shot_frame', '确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、' +
|
|
233
252
|
'场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。' +
|
|
234
253
|
'重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。' +
|
|
@@ -328,6 +347,9 @@ export function registerProduceTools(server, client) {
|
|
|
328
347
|
});
|
|
329
348
|
server.tool('set_character_portrait', '用客户自有图片作为角色定妆图(身份锚,优先级高于 AI 生成;之后 AI 重生默认不覆盖)。' +
|
|
330
349
|
'换图会自动失效并重建派生资产(三视图设定图/发型·身材参考)、重建人脸锁。' +
|
|
350
|
+
'★换图后响应含 stale_frames=[{storyboard_id,storyboard_number,frames}]——这些镜的首帧还是旧定妆图生成的、已被污染。' +
|
|
351
|
+
'要让新定妆图生效:对每个 stale_frame 用 quote_shot_frame+generate_shot_frame 重生该镜(平台会自动以新定妆图/设定图/人脸锁作锚,保全片一致)。' +
|
|
352
|
+
'不必逐镜自己指定模型/首尾帧。★千万别自制首尾帧再 upload_shot_frame——外部图没有角色身份锚/画风锚,人物·服装·画风必漂,那才是废片根源(不是"杜绝废片")。' +
|
|
331
353
|
'传本地文件(file_path,自动上传 COS)或已托管的图片 URL(image_url),二选一。免费。', {
|
|
332
354
|
character_id: z.number().int().positive(),
|
|
333
355
|
file_path: z.string().optional().describe('本地定妆图路径(与 image_url 二选一;自动上传 COS)'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
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.31",
|
|
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.31",
|
|
12
12
|
"transport": { "type": "stdio" },
|
|
13
13
|
"environmentVariables": [
|
|
14
14
|
{
|