@starreel/mcp 0.1.38 → 0.1.40
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 +27 -0
- package/dist/tools/produce.js +21 -2
- package/package.json +2 -2
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -180,6 +180,33 @@ content that will be rejected.
|
|
|
180
180
|
key in an environment variable or secrets manager, never in code or logs.
|
|
181
181
|
The 15-min token auto-re-exchanges; a leaked key is revoked in Settings.
|
|
182
182
|
|
|
183
|
+
## Script fidelity — auto two-pass rewriting
|
|
184
|
+
|
|
185
|
+
`rewrite_script` routes automatically based on what the user put into
|
|
186
|
+
`set_script`:
|
|
187
|
+
|
|
188
|
+
- **Source is already a screenplay** (scene headers / dialogue-line structure):
|
|
189
|
+
the platform runs a two-pass fidelity rewrite. The user's dialogue is
|
|
190
|
+
byte-locked by machine gates (a missing line is rejected and redone
|
|
191
|
+
internally — you never need to babysit this), and the AI adds **no** hooks,
|
|
192
|
+
twists, or emotional beats of its own. Dramaturgy gaps it detects come back
|
|
193
|
+
in `get_script` → `dramaturgy_suggestions`; relay them to the user and let
|
|
194
|
+
the user decide. Ignoring them blocks nothing.
|
|
195
|
+
- **Source is a novel or outline**: the creative single-pass rewrite runs as
|
|
196
|
+
before (the AI builds hooks and emotional beats).
|
|
197
|
+
|
|
198
|
+
Overrides via `update_project_settings`: `rewrite_pipeline`
|
|
199
|
+
(`auto` default / `two_pass` force fidelity / `single_forced` force creative)
|
|
200
|
+
and `fidelity_enforce: 1` (hard-reject any rewrite that drops a dialogue line,
|
|
201
|
+
a cast member, or an action beat).
|
|
202
|
+
|
|
203
|
+
When the user complains "the AI rewrote my script off course": ① confirm the
|
|
204
|
+
full original went into `set_script`; ② set `rewrite_pipeline: "two_pass"` and
|
|
205
|
+
rerun `rewrite_script`; ③ once the user approves a character's look, lock it
|
|
206
|
+
with `update_character` `profile_locked: 1` so later extractions can't
|
|
207
|
+
overwrite appearance (appearance anchors the portrait and face lock — an
|
|
208
|
+
overwrite means face drift across the whole drama).
|
|
209
|
+
|
|
183
210
|
## Failure playbook
|
|
184
211
|
|
|
185
212
|
Failures surface as a human-readable `message` (MCP throws `Error(message)`;
|
package/dist/tools/produce.js
CHANGED
|
@@ -56,6 +56,12 @@ const WORKFLOW_HINT = '★三档执行策略(别把三档混着问客户):' +
|
|
|
56
56
|
'★两条锁定纪律:①**画幅比例**在 create_drama 即定、drama 级锁定,之后所有出图/出视频/成片都用它、**别中途改**' +
|
|
57
57
|
'(改了已生成内容画幅会不一致、漂移);不设默认 9:16。②**拆镜每镜 5-7 秒是对 AI 出视频优化的正常时长**,' +
|
|
58
58
|
'别因「镜偏长」误判就重拆——generate_storyboards 会**替换整集所有分镜**、已出图白费,已有分镜后端会拦、需 confirm_replace。' +
|
|
59
|
+
'★改写保真(默认 auto 智能路由):set_script 的原稿**本身已是剧本形态**(场景头/对白行结构)时,rewrite_script 自动走两步保真——' +
|
|
60
|
+
'客户台词逐句由机器闸锁定(丢一句即内部拒收重做)、AI 绝不加戏;剧作缺口(钩子/情感锚点)不自动补,写进 get_script 返回的 dramaturgy_suggestions 由客户决定采纳。' +
|
|
61
|
+
'原稿是小说/大纲则自动走创作型改写(AI 铺钩子造情感点),两种客户各得其所、无需手动切换。' +
|
|
62
|
+
'要覆盖默认用 update_project_settings 的 rewrite_pipeline(auto/two_pass/single_forced)与 fidelity_enforce(1=保真硬闸)。' +
|
|
63
|
+
'客户说「AI 把我的剧本改偏了」时的处置:①确认完整原稿已进 set_script;②rewrite_pipeline 设 two_pass 强制保真后重跑 rewrite_script;' +
|
|
64
|
+
'③客户确认角色外观后用 update_character 的 profile_locked=1 锁定档案,防后续提取覆盖外貌导致定妆图换脸。' +
|
|
59
65
|
'用 get_pipeline_status 查进度(按项目类型返回专属步骤)。';
|
|
60
66
|
const ETHNICITY_CODES = [
|
|
61
67
|
'east_asian', 'southeast_asian', 'south_asian', 'central_asian',
|
|
@@ -142,6 +148,8 @@ export function registerProduceTools(server, client) {
|
|
|
142
148
|
project_type: z.enum(['drama', 'ad', 'mv', 'brand_film']).optional()
|
|
143
149
|
.describe('项目类型(默认 drama)。ad=广告(改写走 ad_script_rewriter);mv=音乐(走歌词→故事→剧本子流程);brand_film=品牌微电影(默认16:9)'),
|
|
144
150
|
rewrite_mode: z.enum(['standard', 'director']).optional().describe('AI改写深度:standard 或 director(导演级)'),
|
|
151
|
+
rewrite_pipeline: z.enum(['auto', 'two_pass', 'single_forced']).optional().describe('改写流水线:auto(默认,按原稿形态智能路由——剧本形态走两步保真,小说/大纲走创作改写)/two_pass(强制两步保真,客户自带成熟剧本必选)/single_forced(强制单步创作)'),
|
|
152
|
+
fidelity_enforce: z.number().int().min(0).max(1).optional().describe('1=改写保真硬闸:丢台词/丢人物/丢动作节拍直接拒收重做(客户要求逐句保留时开)'),
|
|
145
153
|
director_style: z.string().optional().describe('导演风格包 key'),
|
|
146
154
|
...PROJECT_SETTINGS_FIELDS,
|
|
147
155
|
}, async (args) => {
|
|
@@ -161,11 +169,12 @@ export function registerProduceTools(server, client) {
|
|
|
161
169
|
}, async ({ episode_id, script }) => jsonResult(await client.producePut(`/episodes/${episode_id}/script`, { content: script })));
|
|
162
170
|
// ---------- AI 改写 / 审阅 / 改稿 ----------
|
|
163
171
|
server.tool('rewrite_script', 'AI 改写:把原始剧本改写成可拍稿(读 content → 写 script_content)。按项目类型自动选改写 agent' +
|
|
172
|
+
'★保真自动路由:原稿已是剧本形态时自动走两步保真(台词逐句机器锁定、AI 不加戏,剧作缺口进 dramaturgy_suggestions 由客户决定);原稿是小说/大纲则走创作型改写。' +
|
|
164
173
|
'(广告走 ad 改写;MV 不走标准改写会被拦)。后台异步(分钟级),文本步按 token 后付、不欠费,无需报价。' +
|
|
165
174
|
'完成后用 get_script 审阅、edit_rewritten_script 改稿。' +
|
|
166
175
|
'★典型耗时 2~4 分钟(生产实测 ≈169 秒)。**60 秒内查不到结果是正常的,不是失败**——' +
|
|
167
176
|
'用 get_run_status 判断还在不在跑,别急着重发。' + WORKFLOW_HINT, { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/rewrite`)));
|
|
168
|
-
server.tool('get_script', '读某一集的原始内容 + AI 改写后的可拍稿 + 改写状态(
|
|
177
|
+
server.tool('get_script', '读某一集的原始内容 + AI 改写后的可拍稿 + 改写状态 + dramaturgy_suggestions(两步保真模式下 AI 识别到但未自动补的剧作缺口——钩子/情感锚点;把它转述给客户决定采纳与否,忽略不影响产线)。免费。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/script`)));
|
|
169
178
|
server.tool('edit_rewritten_script', '客户改 AI 改写后的可拍稿(写 script_content)。只用于修改 AI 改写产出的稿(人工润色/纠正);' +
|
|
170
179
|
'本集还没跑过 rewrite_script 时会被 400 拒——这不是绕过改写的通道,别把自己写好的剧本直接贴进来。免费。', {
|
|
171
180
|
episode_id: z.number().int().positive(),
|
|
@@ -214,6 +223,9 @@ export function registerProduceTools(server, client) {
|
|
|
214
223
|
'fail_reason(sensitive/text_sensitive/copyright/face_mismatch/account_overdue/quota_full/authorizing/' +
|
|
215
224
|
'insufficient_credits/transient)、retryable(true=可重试;false=改内容换图,重试无效)、fail_hint(人读文案)。' +
|
|
216
225
|
'照 retryable 判该重试还是该改内容,别解析中文。' +
|
|
226
|
+
'★first_frame_source/last_frame_source=\'upload\' 表示该帧是**外部上传图**(绕开了身份锚/画风锚/' +
|
|
227
|
+
'best-of-N/帧审计整条质量链路)——人物·服装·画风漂移排查先看这些镜;外部图导致的漂移不是平台生成质量问题,' +
|
|
228
|
+
'修复正路是删掉外部图改走 generate_shot_frame 平台重生。' +
|
|
217
229
|
'★若某镜带 reopen_pair_id:该镜首尾帧同时生成时只有一侧真的有问题、另一侧是无辜陪拒,' +
|
|
218
230
|
'原样传给 generate_shot_frame 的 reopen_pair_id 参数可以只重掷有问题的那一侧(省一半算力/费用,' +
|
|
219
231
|
'不会拿去生成一张这次根本没打算重做的图)。没有这个字段就按 fail_reason/retryable 走常规重试。免费。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/storyboards`)));
|
|
@@ -321,11 +333,16 @@ export function registerProduceTools(server, client) {
|
|
|
321
333
|
description: z.string().optional(),
|
|
322
334
|
tags: z.array(z.string()).optional(),
|
|
323
335
|
aspect_ratio: z.enum(ASPECT_RATIOS).optional(),
|
|
336
|
+
// v0.1.39 — 画幅锁定闸:本剧已有分镜/生成资产后改画幅会被 400 拦(已生成内容会漂移),
|
|
337
|
+
// 确认要改必须显式带 true。通常正解是建剧时定好画幅、之后不改。
|
|
338
|
+
confirm_aspect_change: z.boolean().optional(),
|
|
324
339
|
video_resolution: z.enum(VIDEO_RESOLUTIONS).optional(),
|
|
325
340
|
setting_brief: z.string().optional().describe('世界观 Brief(ERA LOCK)'),
|
|
326
341
|
ethnicity: z.enum(ETHNICITY_CODES).optional().describe('角色族裔锁'),
|
|
327
342
|
ethnicity_note: z.string().optional(),
|
|
328
343
|
rewrite_mode: z.enum(['standard', 'director']).optional(),
|
|
344
|
+
rewrite_pipeline: z.enum(['auto', 'two_pass', 'single_forced']).optional().describe('改写流水线:auto 默认智能路由/two_pass 强制两步保真/single_forced 强制单步创作'),
|
|
345
|
+
fidelity_enforce: z.number().int().min(0).max(1).optional().describe('1=改写保真硬闸(丢台词即拒)'),
|
|
329
346
|
director_style: z.string().optional(),
|
|
330
347
|
theme_statement: z.string().optional().describe('一句话主题'),
|
|
331
348
|
subtitle_preset: z.string().optional(),
|
|
@@ -514,7 +531,8 @@ export function registerProduceTools(server, client) {
|
|
|
514
531
|
server.tool('generate_mv_script', 'MV 项目:据歌词+故事写首集可拍剧本(写 scriptContent)。之后走标准 extract_assets → 分镜 → …。按用量后付。', { drama_id: z.number().int().positive() }, async ({ drama_id }) => jsonResult(await client.producePost(`/dramas/${drama_id}/mv/script`)));
|
|
515
532
|
server.tool('get_mv', 'MV 项目:读歌词/故事/剧本当前状态。免费。', { drama_id: z.number().int().positive() }, async ({ drama_id }) => jsonResult(await client.produceGet(`/dramas/${drama_id}/mv`)));
|
|
516
533
|
// ========== P1 · 资产精修(提取后改设定再出图)==========
|
|
517
|
-
server.tool('update_character', '改角色设定(
|
|
534
|
+
server.tool('update_character', '改角色设定(名字/外貌/年龄段/族裔/性别/性格/戏份/档案锁定)。改后需重出定妆图/相关图。免费。' +
|
|
535
|
+
'★profile_locked=1:客户确认外观后锁定档案,后续 AI 提取不再覆盖外貌/性格/描述——外貌锚着定妆图与人脸锁定,被覆盖=全片换脸;确认满意即锁,要再改先传 0 解锁。', {
|
|
518
536
|
character_id: z.number().int().positive(),
|
|
519
537
|
name: z.string().optional(),
|
|
520
538
|
description: z.string().optional(),
|
|
@@ -524,6 +542,7 @@ export function registerProduceTools(server, client) {
|
|
|
524
542
|
gender: z.string().optional(),
|
|
525
543
|
personality: z.string().optional(),
|
|
526
544
|
role: z.string().optional(),
|
|
545
|
+
profile_locked: z.number().int().min(0).max(1).optional().describe('1=锁定档案(AI 提取不再覆盖外貌/性格/描述,防定妆图换脸);0=解锁'),
|
|
527
546
|
}, async ({ character_id, ...fields }) => jsonResult(await client.producePut(`/characters/${character_id}`, fields)));
|
|
528
547
|
server.tool('delete_character', '删除一个角色(提取误建/合并时用)。免费。', { character_id: z.number().int().positive() }, async ({ character_id }) => jsonResult(await client.produceDelete(`/characters/${character_id}`)));
|
|
529
548
|
server.tool('update_scene', '改场景设定(名字/描述/地点/时段/氛围)。免费。', {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
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",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build": "tsc",
|
|
19
19
|
"dev": "tsx src/index.ts",
|
|
20
20
|
"typecheck": "tsc --noEmit",
|
|
21
|
-
"prepublishOnly": "npm run build"
|
|
21
|
+
"prepublishOnly": "npm run build && node scripts/release-check.mjs"
|
|
22
22
|
},
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=18"
|
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.40",
|
|
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.40",
|
|
12
12
|
"transport": { "type": "stdio" },
|
|
13
13
|
"environmentVariables": [
|
|
14
14
|
{
|