@starreel/mcp 0.1.59 → 0.1.61

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/README.md CHANGED
@@ -128,7 +128,7 @@ See the [API docs](https://api.shortreelai.com/docs/mcp).
128
128
  | Identity anchors | `generate_portraits_and_sheets` (portraits + character sheets = the consistency anchor) |
129
129
  | Storyboards | `quote_storyboards` → `generate_storyboards` → `get_storyboards` |
130
130
  | Frames & video | `quote_frames` → `generate_frames` · `quote_videos` → `generate_videos` |
131
- | Audio | `generate_tts` · `generate_bgm` · `generate_sfx` · voice management |
131
+ | Audio | `generate_tts` · `generate_bgm` (steerable via `prompt`) · `get_bgm_prompt_guide` · `generate_sfx` · voice management |
132
132
  | Finishing | `compose_episode` (free) · `get_final_cut` · `render_multi_aspect` · posters & covers |
133
133
  | Localization | `translate_subtitles` · localization jobs |
134
134
  | Ads / MV modes | product library & product sheets · MV lyrics → story → script |
package/SKILL.md CHANGED
@@ -440,8 +440,16 @@ Map the reason to an action:
440
440
  | `insufficient_credits` | false | Balance too low for this call | Stop, prompt to recharge (402) |
441
441
  | `authorizing` | true | Face frame queuing for KYC (not a rejection) | Wait ~1 min, retry |
442
442
  | `transient` | true | BestOfN / quality-gate / rate-limit / network | Back off, retry |
443
+ | `repeat_rejected` | false | Same shot rejected for the same reason until the circuit breaker tripped (auto-clears after 24 h) | Change the prompt / references / contract **first**; a blind retry is a full-price repeat of the same rejection |
444
+ | `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 |
443
445
  | `unknown` | false | Unclassified | Read `fail_hint`; don't auto-retry |
444
446
 
447
+ A shot may also carry `degraded_frames: [{ frame_type, reason, reason_label, since,
448
+ hint }]`. That frame was **released by the system after the same gate rejected it
449
+ repeatedly** (the verdict is recorded, not enforced) — the URL looks like any clean
450
+ frame, but it needs a human look. If it is not acceptable, fix the input the
451
+ `hint` names and regenerate that frame with `generate_shot_frame`.
452
+
445
453
  Three action classes, one decision: **moderation / identity / copyright → change
446
454
  content**; **overdue / token → not self-healable (tell user / wait)**; **network
447
455
  / timeout / transient → retry**. Failed spends are auto-refunded (pre-hold →
@@ -595,7 +603,8 @@ to close") tells the vendor to fit that entire sequence into each 3-second shot.
595
603
  `quote/generate_frames`, `chain_frames`, `quote/generate_videos`
596
604
  - **Audio**: `generate_tts` (required before final cut), `clone_voice`,
597
605
  `speak_with_voice`, `set_character_voice`, `list_voices`, `delete_voice`,
598
- `generate_bgm`, `replace_shot_dialogue`
606
+ `generate_bgm` (optional `prompt` steers the music; read `get_bgm_prompt_guide` first),
607
+ `get_bgm_prompt_guide`, `replace_shot_dialogue`
599
608
  - **Finish**: `compose_episode`, `get_final_cut`, `get_export`,
600
609
  `generate_episode_poster`, `generate_cover`
601
610
  - **Assemble it yourself**: `export_handoff_pack`, `get_handoff_toolchain` —
@@ -248,7 +248,7 @@ export const OPTIONAL_BOOSTS = [
248
248
  { what: '口型同步', tool: 'lipsync_episode', when: 'TTS 配音项目需要对口型时' },
249
249
  { what: '海报 / 封面', tool: 'generate_episode_poster', when: '成片后;`generate_drama_poster` / `generate_cover` 同族' },
250
250
  { what: '音效 / 特效 / 转场(本地库匹配)', tool: 'generate_sfx', when: '免费;`generate_effects` / `generate_transitions` 同族' },
251
- { what: '配乐', tool: 'generate_bgm', when: '按整集情绪弧线生成;终拼自动接管' },
251
+ { what: '配乐', tool: 'generate_bgm', when: '按整集情绪弧线生成;终拼自动接管。客户想指定音乐方向就带 prompt(整集一条),写法先读 `get_bgm_prompt_guide`(免费);不带 prompt 就是全自动' },
252
252
  { what: '字幕翻译', tool: 'translate_subtitles', when: '出海;双语烧录在项目设定里开' },
253
253
  ];
254
254
  export const BILLING = {
@@ -257,7 +257,7 @@ export const BILLING = {
257
257
  'quote_id 一次性、约 15 分钟过期;绝不擅自确认,视频报价可能上万点。',
258
258
  pay_as_you_go: '文本步(改写 / 提取 / 自动填充 / 增强提示词)按 token 后付,无需报价但要事先告知。',
259
259
  free_families: [
260
- '所有 get_* / list_* / scan_* / review_* / check_* / recommend_* / get_capabilities_guide / get_autofill_status',
260
+ '所有 get_* / list_* / scan_* / review_* / check_* / recommend_* / get_capabilities_guide / get_autofill_status / get_bgm_prompt_guide',
261
261
  'compose_episode / rerender_episode / render_multi_aspect / generate_sfx / generate_effects / generate_transitions',
262
262
  'import_storyboard_table / adopt_external_script / get_script_format_spec / check_script_format',
263
263
  'get_storyboard_table_spec / check_storyboard_table / get_bulk_import_spec / check_bulk_import / bulk_import_storyboards',
@@ -454,8 +454,11 @@ export function registerProduceTools(server, client) {
454
454
  '★每镜还带**结构化状态**:frame_status/video_status(ready/pending/authorizing/rejected/failed/none/not_required)、' +
455
455
  '★not_required=旁白/片尾卡镜:帧与视频由成片层渲染,本镜不需要生成——数补齐进度时把它当已完成,别重试。' +
456
456
  'fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/' +
457
- 'insufficient_credits/transient)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。' +
457
+ 'insufficient_credits/transient/repeat_rejected/pair_collateral)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。' +
458
458
  '照 retryable 判该重试还是该改内容,别解析中文。' +
459
+ '★pair_collateral=同镜另一帧未通过、本帧随批结束——**本帧自身没被判不合格,别去改它**:有 reopen_pair_id 就用它只重掷有过错的一侧,否则直接重生本镜。' +
460
+ '★若某镜带 degraded_frames:[{frame_type,reason,reason_label,since,hint}],表示该帧是系统在同因连拒熔断后**放行**的(判据照记未拒),' +
461
+ 'URL 上与干净帧无区别但需人工复核;不满意按 hint 修正输入后 generate_shot_frame 重生该帧。' +
459
462
  '★first_frame_source/last_frame_source=\'upload\' 表示该帧是**外部上传图**(绕开了身份锚/画风锚/' +
460
463
  'best-of-N/帧审计整条质量链路)——人物·服装·画风漂移排查先看这些镜;外部图导致的漂移不是平台生成质量问题,' +
461
464
  '修复正路是删掉外部图改走 generate_shot_frame 平台重生。' +
@@ -818,7 +821,26 @@ export function registerProduceTools(server, client) {
818
821
  })));
819
822
  server.tool('generate_bgm', '给整集生成/更换 AI 配乐(按情绪弧线)。后台异步,按用量后付不欠费。返回情绪弧线段数与预估耗时;' +
820
823
  '用 get_bgm_status 轮询生成进度。★配乐生成/改动**不会自动进已有成片**——完成后必须重新 ' +
821
- 'compose_episode(免费)才能听到;get_final_cut 的 bgm_stale=true 就是在提示这一步。别用 re-render(吃旧时间线,不含新配乐)。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/bgm`)));
824
+ 'compose_episode(免费)才能听到;get_final_cut 的 bgm_stale=true 就是在提示这一步。别用 re-render(吃旧时间线,不含新配乐)。\n' +
825
+ '★prompt 可选:不传=全自动(和以前一样)。传了就是在自动结果上再加方向,整集一条,系统仍按情绪弧线分幕。' +
826
+ '怎么写见 get_bgm_prompt_guide(免费);要点=只写音乐维度(情绪气质/主奏配器/速度动态/厚薄空间/风格参照),' +
827
+ '别写剧情(「主角发现真相时要紧张」→写「紧张,节奏推进感强」)。' +
828
+ '只出纯器乐:要人声/歌词/拟音当乐器都不会生效,会在 prompt_warnings 里点名但**不拦生成**。\n' +
829
+ '★prompt_mode: guide(默认)=你的要求与平台专业护栏(时代与题材匹配/配器节制/高潮保规模/段间差异)一起生效;' +
830
+ 'override=直通,跳过护栏,只保留技术底线(纯器乐/时长/可循环)。override 效果自负,' +
831
+ '**先用 guide 试**,确实拧不过来再换。不传 prompt 时沿用该集上次填的(get_bgm_status 可查)。', {
832
+ episode_id: z.number().int().positive(),
833
+ prompt: z.string().optional().describe('配乐方向,整集一条,≤800 字。只写音乐维度,别写剧情。传空字符串=清除已存的提示词。'
834
+ + '不传=沿用该集上次填的(没填过就是全自动)。'),
835
+ prompt_mode: z.enum(['guide', 'override']).optional().describe('guide(默认)=提示词与平台护栏一起生效;override=直通跳过审美护栏(技术底线仍在)。'),
836
+ }, async ({ episode_id, prompt, prompt_mode }) => jsonResult(await client.producePost(`/episodes/${episode_id}/bgm`, {
837
+ ...(prompt === undefined ? {} : { prompt }),
838
+ ...(prompt_mode ? { prompt_mode } : {}),
839
+ })));
840
+ server.tool('get_bgm_prompt_guide', '取「AI 配乐提示词」的书写规范:两个档位怎么选、该写哪些维度(附可照抄的示例)、' +
841
+ '哪些是写了也不会生效的硬限制(纯器乐/时长/不做音效/不复刻具体曲目)、常见写坏的方式。' +
842
+ '免费,纯静态,与具体剧目无关——写 generate_bgm 的 prompt 之前先读它,别自己猜。' +
843
+ '也适合直接把要点转述给客户看。', {}, async () => jsonResult(await client.produceGet('/bgm-prompt-guide')));
822
844
  server.tool('set_shot_name_card', '给某一镜加/改/清「角色名卡」(画面侧边竖排人物名+朱红印章,终拼时烧进成片,含预览一致的书法字体)。' +
823
845
  'name 传空字符串=清除本镜名卡。免费(纯数据,填了就显示)。适合群像出场镜逐个标注人物名。' +
824
846
  '★别自己下载视频叠字再上传——那会绕开渲染机字体与印章素材,预览/成片不一致。', {
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.59",
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.59 tool surface (operationIds match MCP tool names 1:1)."
5
+ "version": "0.1.61",
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.61 tool surface (operationIds match MCP tool names 1:1)."
7
7
  },
8
8
  "servers": [
9
9
  {
@@ -27,6 +27,10 @@
27
27
  }
28
28
  },
29
29
  "tags": [
30
+ {
31
+ "name": "bgm-prompt-guide",
32
+ "description": "Operations under /bgm-prompt-guide"
33
+ },
30
34
  {
31
35
  "name": "bulk-import",
32
36
  "description": "Operations under /bulk-import"
@@ -85,6 +89,42 @@
85
89
  }
86
90
  ],
87
91
  "paths": {
92
+ "/bgm-prompt-guide": {
93
+ "get": {
94
+ "operationId": "get_bgm_prompt_guide",
95
+ "summary": "取「AI 配乐提示词」的书写规范:两个档位怎么选、该写哪些维度(附可照抄的示例)、哪些是写了也不会生效的硬限制(纯器乐/时长/不做音效/不复刻具体曲目)、常见写坏的方式",
96
+ "description": "取「AI 配乐提示词」的书写规范:两个档位怎么选、该写哪些维度(附可照抄的示例)、哪些是写了也不会生效的硬限制(纯器乐/时长/不做音效/不复刻具体曲目)、常见写坏的方式。免费,纯静态,与具体剧目无关——写 generate_bgm 的 prompt 之前先读它,别自己猜。也适合直接把要点转述给客户看。",
97
+ "tags": [
98
+ "bgm-prompt-guide"
99
+ ],
100
+ "responses": {
101
+ "200": {
102
+ "description": "StarReel envelope",
103
+ "content": {
104
+ "application/json": {
105
+ "schema": {
106
+ "type": "object",
107
+ "properties": {
108
+ "code": {
109
+ "type": "integer"
110
+ },
111
+ "message": {
112
+ "type": "string"
113
+ },
114
+ "data": {
115
+ "description": "Operation result payload"
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ },
122
+ "402": {
123
+ "description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
124
+ }
125
+ }
126
+ }
127
+ },
88
128
  "/bulk-import/lint": {
89
129
  "post": {
90
130
  "operationId": "check_bulk_import",
@@ -2510,7 +2550,7 @@
2510
2550
  "post": {
2511
2551
  "operationId": "generate_bgm",
2512
2552
  "summary": "给整集生成/更换 AI 配乐(按情绪弧线)",
2513
- "description": "给整集生成/更换 AI 配乐(按情绪弧线)。后台异步,按用量后付不欠费。返回情绪弧线段数与预估耗时;用 get_bgm_status 轮询生成进度。★配乐生成/改动**不会自动进已有成片**——完成后必须重新 compose_episode(免费)才能听到;get_final_cut 的 bgm_stale=true 就是在提示这一步。别用 re-render(吃旧时间线,不含新配乐)。",
2553
+ "description": "给整集生成/更换 AI 配乐(按情绪弧线)。后台异步,按用量后付不欠费。返回情绪弧线段数与预估耗时;用 get_bgm_status 轮询生成进度。★配乐生成/改动**不会自动进已有成片**——完成后必须重新 compose_episode(免费)才能听到;get_final_cut 的 bgm_stale=true 就是在提示这一步。别用 re-render(吃旧时间线,不含新配乐)。\n★prompt 可选:不传=全自动(和以前一样)。传了就是在自动结果上再加方向,整集一条,系统仍按情绪弧线分幕。怎么写见 get_bgm_prompt_guide(免费);要点=只写音乐维度(情绪气质/主奏配器/速度动态/厚薄空间/风格参照),别写剧情(「主角发现真相时要紧张」→写「紧张,节奏推进感强」)。只出纯器乐:要人声/歌词/拟音当乐器都不会生效,会在 prompt_warnings 里点名但**不拦生成**。\n★prompt_mode: guide(默认)=你的要求与平台专业护栏(时代与题材匹配/配器节制/高潮保规模/段间差异)一起生效;override=直通,跳过护栏,只保留技术底线(纯器乐/时长/可循环)。override 效果自负,**先用 guide 试**,确实拧不过来再换。不传 prompt 时沿用该集上次填的(get_bgm_status 可查)。",
2514
2554
  "tags": [
2515
2555
  "episodes"
2516
2556
  ],
@@ -2525,6 +2565,28 @@
2525
2565
  }
2526
2566
  }
2527
2567
  ],
2568
+ "requestBody": {
2569
+ "required": false,
2570
+ "content": {
2571
+ "application/json": {
2572
+ "schema": {
2573
+ "type": "object",
2574
+ "properties": {
2575
+ "prompt": {
2576
+ "type": "string"
2577
+ },
2578
+ "prompt_mode": {
2579
+ "type": "string",
2580
+ "enum": [
2581
+ "guide",
2582
+ "override"
2583
+ ]
2584
+ }
2585
+ }
2586
+ }
2587
+ }
2588
+ }
2589
+ },
2528
2590
  "responses": {
2529
2591
  "200": {
2530
2592
  "description": "StarReel envelope",
@@ -4666,7 +4728,7 @@
4666
4728
  "get": {
4667
4729
  "operationId": "get_storyboards",
4668
4730
  "summary": "读某一集的分镜列表(供审阅/查进度)",
4669
- "description": "读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。★每镜还带**结构化状态**: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)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。照 retryable 判该重试还是该改内容,别解析中文。★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 走常规重试。免费。",
4731
+ "description": "读某一集的分镜列表(供审阅/查进度)。含每镜首帧(first_frame_image)与视频(video_url)是否就绪。★每镜还带**结构化状态**: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 重生该帧。★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 走常规重试。免费。",
4670
4732
  "tags": [
4671
4733
  "episodes"
4672
4734
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starreel/mcp",
3
- "version": "0.1.59",
3
+ "version": "0.1.61",
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.59",
5
+ "version": "0.1.61",
6
6
  "websiteUrl": "https://starreel.ai",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@starreel/mcp",
11
- "version": "0.1.59",
11
+ "version": "0.1.61",
12
12
  "transport": {
13
13
  "type": "stdio"
14
14
  },