@starreel/mcp 0.1.128 → 0.1.129
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 +1 -1
- package/dist/tools/produce.js +16 -0
- package/openapi.json +148 -2
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -91,7 +91,7 @@ announces a condensed version as MCP `instructions` at connect time.
|
|
|
91
91
|
| **No sample** — just an idea of the voice (a narrator, a character that deserves its own voice) | `design_voice` (one-sentence description, free) → `get_voice_design` until `done` (candidates arrive as local wav files — let the customer listen) → `save_designed_voice` (pick one; billed like a clone) → `set_character_voice` | generating every line straight from the description — each generation is a different person; naming a real person to imitate their voice |
|
|
92
92
|
| A song + lyrics | `create_drama` (`project_type: "mv"`) → `set_mv_lyrics` → `generate_mv_story` → `generate_mv_script` | `rewrite_script` (blocked for MV) |
|
|
93
93
|
| A product / brand | `create_drama` (`project_type: "ad"` or `"brand_film"`) → `add_product` → `generate_product_sheet` | writing brand copy as dialogue (it gets spoken) |
|
|
94
|
-
| Generated shots / a cut that needs changes | `scan_dialogue_coverage` / `scan_intra_shot_cuts` first, then `get_shot_prompts` · `update_shot` · `replace_shot_dialogue` · `repair_episode_dialogue` · `split_shot` · `trim_shot` · `regenerate_shot_video` · `edit_video_shot` → `rerender_episode`. To put **specific shots on a different video engine** in a whole-episode run, pass `shot_engines` (`{storyboard_id: engine}`) to `quote_videos` (a scene group that contains a picked shot is **split into per-shot generation** — listed in `shot_engines_ungrouped`; its other shots stay on the drama engine but lose the group's one-take continuity, so don't break a good group for one shot; a shot that already has a video is not re-run by the episode run, so picking an engine for it is rejected). Re-quoting after a partial run prices only the shots that will actually be dispatched (`shots_total`; already-finished ones are counted in `shots_already_done`, except that a scene group with any unfinished shot is re-run whole). To make a shot **always** use a different engine (single, batch and regen alike), set `video_engine` with `update_shot` (stored on the shot, shown in the web workbench; such a shot is never put in a scene group; explicit per-call parameters still win). To retry **one shot on a different video engine**, pass `model` to `quote_regenerate_shot_video` (that shot, that regeneration only — the drama's `video_engine` is untouched; the quote pins the engine, so changing it means re-quoting) | re-composing to fix what a clip *says*; switching the whole drama's `video_engine` just to fix one shot |
|
|
94
|
+
| Generated shots / a cut that needs changes | `scan_dialogue_coverage` / `scan_intra_shot_cuts` first, then `get_shot_prompts` · `update_shot` · `replace_shot_dialogue` · `repair_episode_dialogue` · `split_shot` · `trim_shot` · `regenerate_shot_video` · `edit_video_shot` → `rerender_episode`. To put **specific shots on a different video engine** in a whole-episode run, pass `shot_engines` (`{storyboard_id: engine}`) to `quote_videos` (a scene group that contains a picked shot is **split into per-shot generation** — listed in `shot_engines_ungrouped`; its other shots stay on the drama engine but lose the group's one-take continuity, so don't break a good group for one shot; a shot that already has a video is not re-run by the episode run, so picking an engine for it is rejected). Re-quoting after a partial run prices only the shots that will actually be dispatched (`shots_total`; already-finished ones are counted in `shots_already_done`, except that a scene group with any unfinished shot is re-run whole). To make a shot **always** use a different engine (single, batch and regen alike), set `video_engine` with `update_shot` (stored on the shot, shown in the web workbench; such a shot is never put in a scene group; explicit per-call parameters still win). To re-run **one scene group** (one request, keeps in-group continuity) — optionally on a different engine for that run — use `quote_regenerate_scene_group` (`shot_numbers` = exactly one group from `get_scene_group_plan`, optional `video_engine`; the whole group must fit that engine's single-clip limit) → `regenerate_scene_group`. To retry **one shot on a different video engine**, pass `model` to `quote_regenerate_shot_video` (that shot, that regeneration only — the drama's `video_engine` is untouched; the quote pins the engine, so changing it means re-quoting) | re-composing to fix what a clip *says*; switching the whole drama's `video_engine` just to fix one shot |
|
|
95
95
|
| Wants old portraits / sheets / a shot's old tail frame "deleted" | `set_character_portrait` (old assets listed in `old_assets`) · `clear_shot_frame` (old tail frame) → `regenerate_shot_video`; `list_unlinked_assets` lists the drama's unlinked old assets (a history list, not proof of ownership). Both only **unlink** — files are not deleted (`physically_deleted` is always empty; `in_history: false` means the platform kept no record, so save that URL if it matters). Tell the customer exactly that | telling the customer the old image was deleted; writing `last_frame_image: null` through the internal API |
|
|
96
96
|
| Wants an old image **permanently** deleted from storage (not just unlinked) | `preview_delete_asset` → show the customer exactly what it says (blocking references, history that will break, copies) → only after an explicit "confirm delete" → `delete_asset` with the `confirm_token`. Irreversible; only the drama owner; only files with trusted provenance (generated for this drama, or uploaded through the platform with a grant record) | deleting without showing the preview; retrying automatically; treating `list_unlinked_assets` as proof the file is unused |
|
|
97
97
|
| Cross-era drama (scenes in different periods) — checking props fit their period | `get_props` → read each prop's `era_audit` (`form_consistent`, `conflicting_scopes`, `violations`); `audit_prop_era` to re-check after a new sheet. On a conflict: `update_prop` with a precise `era_lock` (dynasty + physical form) → `generate_prop_sheet`, or bind a different prop to those shots. `run_precheck` also lists shots whose bound prop conflicts (`prop-era-conflict`) | trusting the prop's name or description alone; regenerating shot frames before the prop sheet is fixed |
|
package/dist/tools/produce.js
CHANGED
|
@@ -1797,6 +1797,22 @@ export function registerProduceTools(server, client) {
|
|
|
1797
1797
|
quote_id: z.string().describe('来自 quote_align_prev_shot'),
|
|
1798
1798
|
}, async ({ storyboard_id, quote_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/align-prev`, { quote_id })));
|
|
1799
1799
|
server.tool('get_scene_group_plan', '查某一集的场景组规划(镜头如何归组做连续长镜)。免费。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/scene-group-plan`)));
|
|
1800
|
+
server.tool('quote_regenerate_scene_group', '报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点。返回 quote_id。零扣费。' +
|
|
1801
|
+
'shot_numbers 必须正好等于 get_scene_group_plan 里某一组的镜号。' +
|
|
1802
|
+
'\n★可选 video_engine:只为这一次整组重出换引擎(不改剧级 video_engine);报价按它计、quote_id 钉死,regenerate_scene_group 派发的就是它。' +
|
|
1803
|
+
'整组仍一次成片,所以整组总时长必须在该引擎单段上限内(hailuo-3 15s;seedance-2.5/wan3.0 30s)且支持本剧分辨率,否则 400——' +
|
|
1804
|
+
'那种情况改用 update_shot 给个别镜设 video_engine(设了的镜会单独出)。' +
|
|
1805
|
+
'报价按逐镜计(整组失败会逐镜兜底,逐镜是上界),正常路径实扣通常更低。', {
|
|
1806
|
+
episode_id: z.number().int().positive(),
|
|
1807
|
+
shot_numbers: z.array(z.number().int().positive()).min(1).describe('这一组的镜号(storyboard_number,见 get_scene_group_plan)'),
|
|
1808
|
+
video_engine: z.enum(VIDEO_ENGINES).optional().describe('本次整组重出的引擎(缺省=跟随剧 video_engine)'),
|
|
1809
|
+
}, async ({ episode_id, shot_numbers, video_engine }) => jsonResult(await client.producePost(`/episodes/${episode_id}/scene-groups/regenerate/quote`, { shot_numbers, ...(video_engine ? { video_engine } : {}) })));
|
|
1810
|
+
server.tool('regenerate_scene_group', '确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)。' +
|
|
1811
|
+
'分组、引擎都由 quote_id 钉死,这里不能改;报价后组内任一镜被改、或分组变了,quote 作废(409),重新报价即可(免费)。' +
|
|
1812
|
+
CONFIRM_HINT, {
|
|
1813
|
+
episode_id: z.number().int().positive(),
|
|
1814
|
+
quote_id: z.string().describe('来自 quote_regenerate_scene_group'),
|
|
1815
|
+
}, async ({ episode_id, quote_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/scene-groups/regenerate`, { quote_id })));
|
|
1800
1816
|
server.tool('generate_scene_groups', '生成场景组(把连续镜头归组,连续长镜/批量出图的地基)。后台异步。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/scene-groups`)));
|
|
1801
1817
|
server.tool('render_multi_aspect', '把成片按多个画幅(竖/横/方)重渲一版,便于多平台分发。免费(纯 ffmpeg),后台异步。', {
|
|
1802
1818
|
episode_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 → 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.129",
|
|
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.129 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -6785,6 +6785,152 @@
|
|
|
6785
6785
|
}
|
|
6786
6786
|
}
|
|
6787
6787
|
},
|
|
6788
|
+
"/episodes/{episode_id}/scene-groups/regenerate": {
|
|
6789
|
+
"post": {
|
|
6790
|
+
"operationId": "regenerate_scene_group",
|
|
6791
|
+
"summary": "确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)",
|
|
6792
|
+
"description": "确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)。分组、引擎都由 quote_id 钉死,这里不能改;报价后组内任一镜被改、或分组变了,quote 作废(409),重新报价即可(免费)。⚠️ 批量报价确认流程:先调对应的 quote_* 工具,把返回的 estimated_points 原样告诉用户,用户明确同意后,才用返回的 quote_id 调本工具。不要擅自确认。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
6793
|
+
"tags": [
|
|
6794
|
+
"episodes"
|
|
6795
|
+
],
|
|
6796
|
+
"parameters": [
|
|
6797
|
+
{
|
|
6798
|
+
"name": "episode_id",
|
|
6799
|
+
"in": "path",
|
|
6800
|
+
"required": true,
|
|
6801
|
+
"schema": {
|
|
6802
|
+
"type": "integer",
|
|
6803
|
+
"exclusiveMinimum": 0
|
|
6804
|
+
}
|
|
6805
|
+
}
|
|
6806
|
+
],
|
|
6807
|
+
"requestBody": {
|
|
6808
|
+
"required": true,
|
|
6809
|
+
"content": {
|
|
6810
|
+
"application/json": {
|
|
6811
|
+
"schema": {
|
|
6812
|
+
"type": "object",
|
|
6813
|
+
"properties": {
|
|
6814
|
+
"quote_id": {
|
|
6815
|
+
"type": "string",
|
|
6816
|
+
"description": "来自 quote_regenerate_scene_group"
|
|
6817
|
+
}
|
|
6818
|
+
},
|
|
6819
|
+
"required": [
|
|
6820
|
+
"quote_id"
|
|
6821
|
+
]
|
|
6822
|
+
}
|
|
6823
|
+
}
|
|
6824
|
+
}
|
|
6825
|
+
},
|
|
6826
|
+
"responses": {
|
|
6827
|
+
"200": {
|
|
6828
|
+
"description": "StarReel envelope",
|
|
6829
|
+
"content": {
|
|
6830
|
+
"application/json": {
|
|
6831
|
+
"schema": {
|
|
6832
|
+
"type": "object",
|
|
6833
|
+
"properties": {
|
|
6834
|
+
"code": {
|
|
6835
|
+
"type": "integer"
|
|
6836
|
+
},
|
|
6837
|
+
"message": {
|
|
6838
|
+
"type": "string"
|
|
6839
|
+
},
|
|
6840
|
+
"data": {
|
|
6841
|
+
"description": "Operation result payload"
|
|
6842
|
+
}
|
|
6843
|
+
}
|
|
6844
|
+
}
|
|
6845
|
+
}
|
|
6846
|
+
}
|
|
6847
|
+
},
|
|
6848
|
+
"402": {
|
|
6849
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
6850
|
+
}
|
|
6851
|
+
}
|
|
6852
|
+
}
|
|
6853
|
+
},
|
|
6854
|
+
"/episodes/{episode_id}/scene-groups/regenerate/quote": {
|
|
6855
|
+
"post": {
|
|
6856
|
+
"operationId": "quote_regenerate_scene_group",
|
|
6857
|
+
"summary": "报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点",
|
|
6858
|
+
"description": "报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点。返回 quote_id。零扣费。shot_numbers 必须正好等于 get_scene_group_plan 里某一组的镜号。\n★可选 video_engine:只为这一次整组重出换引擎(不改剧级 video_engine);报价按它计、quote_id 钉死,regenerate_scene_group 派发的就是它。整组仍一次成片,所以整组总时长必须在该引擎单段上限内(hailuo-3 15s;seedance-2.5/wan3.0 30s)且支持本剧分辨率,否则 400——那种情况改用 update_shot 给个别镜设 video_engine(设了的镜会单独出)。报价按逐镜计(整组失败会逐镜兜底,逐镜是上界),正常路径实扣通常更低。",
|
|
6859
|
+
"tags": [
|
|
6860
|
+
"episodes"
|
|
6861
|
+
],
|
|
6862
|
+
"parameters": [
|
|
6863
|
+
{
|
|
6864
|
+
"name": "episode_id",
|
|
6865
|
+
"in": "path",
|
|
6866
|
+
"required": true,
|
|
6867
|
+
"schema": {
|
|
6868
|
+
"type": "integer",
|
|
6869
|
+
"exclusiveMinimum": 0
|
|
6870
|
+
}
|
|
6871
|
+
}
|
|
6872
|
+
],
|
|
6873
|
+
"requestBody": {
|
|
6874
|
+
"required": true,
|
|
6875
|
+
"content": {
|
|
6876
|
+
"application/json": {
|
|
6877
|
+
"schema": {
|
|
6878
|
+
"type": "object",
|
|
6879
|
+
"properties": {
|
|
6880
|
+
"shot_numbers": {
|
|
6881
|
+
"type": "array",
|
|
6882
|
+
"items": {
|
|
6883
|
+
"type": "integer",
|
|
6884
|
+
"exclusiveMinimum": 0
|
|
6885
|
+
},
|
|
6886
|
+
"minItems": 1,
|
|
6887
|
+
"description": "这一组的镜号(storyboard_number,见 get_scene_group_plan)"
|
|
6888
|
+
},
|
|
6889
|
+
"video_engine": {
|
|
6890
|
+
"type": "string",
|
|
6891
|
+
"enum": [
|
|
6892
|
+
"seedance-2.5",
|
|
6893
|
+
"hailuo-3",
|
|
6894
|
+
"wan3.0",
|
|
6895
|
+
"wan3.0-prime"
|
|
6896
|
+
]
|
|
6897
|
+
}
|
|
6898
|
+
},
|
|
6899
|
+
"required": [
|
|
6900
|
+
"shot_numbers"
|
|
6901
|
+
]
|
|
6902
|
+
}
|
|
6903
|
+
}
|
|
6904
|
+
}
|
|
6905
|
+
},
|
|
6906
|
+
"responses": {
|
|
6907
|
+
"200": {
|
|
6908
|
+
"description": "StarReel envelope",
|
|
6909
|
+
"content": {
|
|
6910
|
+
"application/json": {
|
|
6911
|
+
"schema": {
|
|
6912
|
+
"type": "object",
|
|
6913
|
+
"properties": {
|
|
6914
|
+
"code": {
|
|
6915
|
+
"type": "integer"
|
|
6916
|
+
},
|
|
6917
|
+
"message": {
|
|
6918
|
+
"type": "string"
|
|
6919
|
+
},
|
|
6920
|
+
"data": {
|
|
6921
|
+
"description": "Operation result payload"
|
|
6922
|
+
}
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6925
|
+
}
|
|
6926
|
+
}
|
|
6927
|
+
},
|
|
6928
|
+
"402": {
|
|
6929
|
+
"description": "Insufficient prepaid balance (never overdrafts); response carries `needed` points"
|
|
6930
|
+
}
|
|
6931
|
+
}
|
|
6932
|
+
}
|
|
6933
|
+
},
|
|
6788
6934
|
"/episodes/{episode_id}/scenes": {
|
|
6789
6935
|
"get": {
|
|
6790
6936
|
"operationId": "get_scenes",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.129",
|
|
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.129",
|
|
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.129",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|