@starreel/mcp 0.1.13 → 0.1.15

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  name: starreel-drama-production
3
3
  description: >-
4
4
  Operating skill for any AI agent driving the StarReel short-drama production
5
- pipeline (script → rewrite → extract → portraits → storyboards → frames →
5
+ pipeline (script → rewrite → extract → portraits + sheets → storyboards → frames →
6
6
  video → voiceover → final cut) over MCP or REST. Covers the ordered workflow,
7
7
  the ten operating disciplines (prepaid billing, quote-before-spend, retryable
8
8
  failure handling, content compliance, tenancy), and a failure playbook.
@@ -28,7 +28,7 @@ One episode, the **full** pipeline — nothing skipped:
28
28
 
29
29
  ```
30
30
  create_drama → set_script(raw) → rewrite_script(AI draft, user may edit)
31
- → extract_assets(cast/scenes/props) → generate_character_portraits(identity anchor)
31
+ → extract_assets(cast/scenes/props) → generate_portraits_and_sheets(portraits + sheets = the shot consistency anchor)
32
32
  → storyboards → frames → videos → generate_tts(voiceover) → compose_episode → final cut (.mp4 link)
33
33
  ```
34
34
 
@@ -90,10 +90,17 @@ content that will be rejected.
90
90
  somewhere else.
91
91
 
92
92
  6. **Follow the pipeline order — do not skip.** `set_script` → `rewrite_script`
93
- → `extract_assets` → portraits → storyboards → frames → videos. Always
93
+ → `extract_assets` → portraits **+ sheets** → storyboards → frames → videos. Always
94
94
  generate frames **before** videos; skipping frames degrades video into
95
- anchorless t2v — wasted money. Lock character portraits before video for
96
- identity consistency.
95
+ anchorless t2v — wasted money. Lock character portraits **and sheets** before
96
+ video: a portrait is one image, but **character sheets (multi-view turnarounds)
97
+ are the shot consistency anchor every frame references** — portraits alone
98
+ leave characters drifting across angle / lighting / wardrobe.
99
+ `generate_portraits_and_sheets` does both (portraits first, then sheets). `generate_frames` makes **first frames only** — you do
100
+ NOT generate first + last together. A **last frame** is optional and never
101
+ auto-made; upload it via `upload_shot_frame` (`frame_type=last_frame`) only to
102
+ pin a shot's ending (a big camera move or reveal). `generate_videos` needs at
103
+ least one first frame in the episode.
97
104
 
98
105
  7. **Poll, don't block; don't hammer.** Long steps return immediately as
99
106
  `status:generating`. Poll `get_pipeline_status` / `get_jobs` /
@@ -23,7 +23,7 @@ const CONFIRM_HINT = '⚠️ 批量报价确认流程:先调对应的 quote_*
23
23
  // → compose_episode → get_final_cut / get_export
24
24
  // 项目设定随时可 update_project_settings;剧目级资产(色彩脚本/动作模板/世界观图/美术圣经)可选增强。
25
25
  const WORKFLOW_HINT = '照完整工作流按序推进,别跳步:set_script(原始)→ rewrite_script(AI改写)→ extract_assets →' +
26
- ' generate_character_portraits → storyboards → frames → videos → compose。用 get_pipeline_status 查进度。';
26
+ ' generate_portraits_and_sheets(定妆图+设定图·镜头一致性根锚,别只出定妆图)→ storyboards → frames → videos → compose。用 get_pipeline_status 查进度。';
27
27
  const ETHNICITY_CODES = [
28
28
  'east_asian', 'southeast_asian', 'south_asian', 'central_asian',
29
29
  'caucasian', 'middle_eastern', 'african', 'latin_american',
@@ -100,7 +100,16 @@ export function registerProduceTools(server, client) {
100
100
  // ---------- 角色定妆图(一致性锚) ----------
101
101
  server.tool('quote_character_portraits', '报价:给缺定妆图的角色批量出定妆图要多少点。返回 portraits_to_generate、estimated_points、quote_id。零扣费。' +
102
102
  '定妆图是身份一致性的锚(缺它角色会漂移),强烈建议出视频前先出。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/portraits/quote`)));
103
- server.tool('generate_character_portraits', '确认后批量出角色定妆图:后台异步。用 get_pipeline_status/get_storyboards 查进度。' + CONFIRM_HINT, { episode_id: z.number().int().positive(), quote_id: z.string().describe('来自 quote_character_portraits') }, async ({ episode_id, quote_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/portraits/generate`, { quote_id })));
103
+ server.tool('generate_character_portraits', '确认后批量出角色定妆图(★仅定妆图):后台异步。定妆图只是单张身份锚——镜头一致性(尤其服装)还需**设定图**,' +
104
+ '出完定妆图强烈建议 generate_character_sheets;或直接用 generate_portraits_and_sheets 一步到位。' +
105
+ '用 get_pipeline_status/get_storyboards 查进度。' + CONFIRM_HINT, { episode_id: z.number().int().positive(), quote_id: z.string().describe('来自 quote_character_portraits') }, async ({ episode_id, quote_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/portraits/generate`, { quote_id })));
106
+ // ---------- 设定图(镜头一致性根锚·批量 / 一键) ----------
107
+ server.tool('generate_character_sheets', '★批量给全剧角色出设定图(多视角 turnaround)。设定图是镜头帧/视频引用的**一致性根锚**——只出定妆图不出设定图,' +
108
+ '镜头人物换角度/换光/服装会漂移(2.5 更直接用设定图切片做骨相锚)。只对缺设定图的角色出(不重复扣费)。' +
109
+ '前置:角色须已有定妆图(缺则拦并提示先出定妆图)。图片步,按用量后付不欠费。轮询 get_characters 看 sheet_url 就绪。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/character-sheets`)));
110
+ server.tool('generate_portraits_and_sheets', '★一键:定妆图 + 设定图(推荐,产线标配)。设定图强依赖定妆图,故智能两阶段——有角色缺定妆图就先派定妆图并提示,' +
111
+ '定妆图齐了再调一次即批量出设定图。避免只出定妆图导致镜头漂移。图片步,按用量后付不欠费。' +
112
+ '轮询 get_characters 看 image/sheet_url 就绪;每调一次推进一步。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/portraits-and-sheets`)));
104
113
  // ---------- 拆镜(storyboards) ----------
105
114
  server.tool('quote_storyboards', '报价:把某一集的剧本拆成分镜(storyboards)要多少点。返回 estimated_points 与 quote_id。零扣费。' +
106
115
  '拿到后把点数告诉用户征求同意,再用 quote_id 调 generate_storyboards。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/quote`)));
@@ -195,7 +204,7 @@ export function registerProduceTools(server, client) {
195
204
  const image_url = await client.uploadLocalFile(file_path, 'image');
196
205
  return jsonResult(await client.producePost(`/characters/${character_id}/portrait`, { image_url }));
197
206
  });
198
- server.tool('upload_shot_frame', '用客户自有图片作为某镜的首帧或尾帧(会把该镜已有视频标为过期待重生)。自动上传+登记。免费。', {
207
+ server.tool('upload_shot_frame', '用客户自有图片作为某镜的首帧(first_frame)或尾帧(last_frame)。尾帧可选、系统不自动生成——仅在想固定某镜结尾画面(大运镜/揭示镜)时传;常规只需首帧。会把该镜已有视频标为过期待重生。自动上传+登记。免费。', {
199
208
  storyboard_id: z.number().int().positive(),
200
209
  file_path: z.string().describe('本地帧图路径'),
201
210
  frame_type: z.enum(['first_frame', 'last_frame']).optional().describe('默认 first_frame'),
@@ -283,7 +292,8 @@ export function registerProduceTools(server, client) {
283
292
  mood: z.string().optional(),
284
293
  }, async ({ scene_id, ...fields }) => jsonResult(await client.producePut(`/scenes/${scene_id}`, fields)));
285
294
  server.tool('delete_scene', '删除一个场景。免费。', { scene_id: z.number().int().positive() }, async ({ scene_id }) => jsonResult(await client.produceDelete(`/scenes/${scene_id}`)));
286
- server.tool('generate_character_sheet', '给角色出三视图设定图(比定妆图更完整的身份锚,一致性更稳)。图片步,按用量后付不欠费。', { character_id: z.number().int().positive(), episode_id: z.number().int().positive().optional() }, async ({ character_id, episode_id }) => jsonResult(await client.producePost(`/characters/${character_id}/sheet`, episode_id ? { episode_id } : {})));
295
+ server.tool('generate_character_sheet', '给**单个**角色出三视图设定图(镜头一致性根锚,所有镜头帧都会引用;比定妆图更完整)。整集批量用 generate_character_sheets。' +
296
+ '前置:该角色已有定妆图。图片步,按用量后付不欠费。', { character_id: z.number().int().positive(), episode_id: z.number().int().positive().optional() }, async ({ character_id, episode_id }) => jsonResult(await client.producePost(`/characters/${character_id}/sheet`, episode_id ? { episode_id } : {})));
287
297
  server.tool('generate_prop_sheet', '给道具 AI 出设定图。图片步,按用量后付不欠费。', { prop_id: z.number().int().positive() }, async ({ prop_id }) => jsonResult(await client.producePost(`/props/${prop_id}/generate-sheet`)));
288
298
  // ========== P2 · 连续性 / 场景组 / 多画幅 ==========
289
299
  server.tool('chain_frames', '整集首尾帧接力链:让每镜首帧承接上镜尾帧,镜间画面连续(比各镜独立出帧更顺)。按用量后付。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/chain-frames`)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starreel/mcp",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
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",