@infimind/video-mcp-cli 1.0.7 → 1.0.9
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 +57 -16
- package/dist/index.js +11 -6
- package/dist/server.js +88 -14
- package/dist/videoRules.d.ts +1 -1
- package/dist/videoRules.js +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -21,7 +21,10 @@ npm install -g @infimind/video-mcp-cli
|
|
|
21
21
|
"mcpServers": {
|
|
22
22
|
"sora-video-generator": {
|
|
23
23
|
"command": "npx",
|
|
24
|
-
"args": ["-y", "@infimind/video-mcp-cli",
|
|
24
|
+
"args": ["-y", "@infimind/video-mcp-cli"],
|
|
25
|
+
"env": {
|
|
26
|
+
"SORA_MCP_TOKEN": "YOUR_TOKEN"
|
|
27
|
+
}
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -48,8 +51,8 @@ Add the following to your Claude Desktop configuration file:
|
|
|
48
51
|
"mcpServers": {
|
|
49
52
|
"sora-video-generator": {
|
|
50
53
|
"command": "sora-mcp",
|
|
51
|
-
"args": ["--token=YOUR_TOKEN_HERE"],
|
|
52
54
|
"env": {
|
|
55
|
+
"SORA_MCP_TOKEN": "YOUR_TOKEN_HERE",
|
|
53
56
|
"SORA_API_URL": "https://your-api-domain.com/api"
|
|
54
57
|
}
|
|
55
58
|
}
|
|
@@ -59,8 +62,11 @@ Add the following to your Claude Desktop configuration file:
|
|
|
59
62
|
|
|
60
63
|
#### Environment Variables
|
|
61
64
|
|
|
65
|
+
- `SORA_MCP_TOKEN` (recommended): Your MCP API token. This avoids exposing the token in process arguments.
|
|
62
66
|
- `SORA_API_URL` (optional): Your API base URL. Defaults to `http://localhost:3000/api`
|
|
63
67
|
|
|
68
|
+
`--token=YOUR_TOKEN` remains supported for backward compatibility. `--token-env=CUSTOM_ENV_NAME` can be used when the token is stored in a different environment variable.
|
|
69
|
+
|
|
64
70
|
### 3. Restart Claude Desktop
|
|
65
71
|
|
|
66
72
|
After saving the configuration, restart Claude Desktop for the changes to take effect.
|
|
@@ -105,6 +111,23 @@ Local file paths and public URLs are both supported. Local files are converted t
|
|
|
105
111
|
|
|
106
112
|
Video inputs support MP4/MOV. Audio inputs support MP3/WAV. The server validates media duration, size, count, resolution, and URL safety before estimating credits or creating tasks.
|
|
107
113
|
|
|
114
|
+
Media limits:
|
|
115
|
+
|
|
116
|
+
- Local video files: MP4/MOV, up to 50MB each, 2-15 seconds.
|
|
117
|
+
- Local audio files: MP3/WAV, up to 15MB each, 2-15 seconds.
|
|
118
|
+
- S5 allinone: up to 9 images, 3 videos, and 3 audio files.
|
|
119
|
+
- S5 firstlast: up to 2 images; the first frame is required.
|
|
120
|
+
- S6 reference: up to 9 images.
|
|
121
|
+
- S6 edit: up to 1 video and 5 images.
|
|
122
|
+
- `inputDurationTier` is not accepted from clients; the server calculates it from the media.
|
|
123
|
+
|
|
124
|
+
URL safety rules:
|
|
125
|
+
|
|
126
|
+
- Only `http` and `https` URLs are accepted.
|
|
127
|
+
- `localhost`, `127.0.0.1`, private network addresses, reserved IP ranges, and `file:` URLs are rejected.
|
|
128
|
+
- Redirect targets are revalidated.
|
|
129
|
+
- Remote files that are too large, not media, or cannot be safely probed are rejected.
|
|
130
|
+
|
|
108
131
|
Use `dryRun: true` to validate parameters, VIP access, estimated credits, and media rules without creating a task or deducting credits. The result includes `success`, `dryRun`, `route`, `engineName`, `taskMode`, `estimatedCredits`, `remainingCredits`, and `validationWarnings`. Specific credit tables are server-side only; use dry run to get the current estimated consumption.
|
|
109
132
|
|
|
110
133
|
#### Dry run before creating a task
|
|
@@ -124,6 +147,8 @@ Use `dryRun: true` to validate parameters, VIP access, estimated credits, and me
|
|
|
124
147
|
|
|
125
148
|
#### 极睿Sa专业版 - 标准生成
|
|
126
149
|
|
|
150
|
+
S2 uses `sourceImage`, `seconds`, and `size`; do not pass `taskMode` or `resolution`.
|
|
151
|
+
|
|
127
152
|
```json
|
|
128
153
|
{
|
|
129
154
|
"prompt": "一个高质感的产品展示视频,柔和布光,镜头缓慢推进",
|
|
@@ -132,7 +157,8 @@ Use `dryRun: true` to validate parameters, VIP access, estimated credits, and me
|
|
|
132
157
|
"seconds": 10,
|
|
133
158
|
"size": "720x1280",
|
|
134
159
|
"language": "zh-CN",
|
|
135
|
-
"count": 1
|
|
160
|
+
"count": 1,
|
|
161
|
+
"dryRun": true
|
|
136
162
|
}
|
|
137
163
|
```
|
|
138
164
|
|
|
@@ -150,7 +176,8 @@ Use `dryRun: true` to validate parameters, VIP access, estimated credits, and me
|
|
|
150
176
|
"size": "720x1280",
|
|
151
177
|
"resolution": "720p",
|
|
152
178
|
"generateAudio": true,
|
|
153
|
-
"webSearchEnabled": false
|
|
179
|
+
"webSearchEnabled": false,
|
|
180
|
+
"dryRun": true
|
|
154
181
|
}
|
|
155
182
|
```
|
|
156
183
|
|
|
@@ -164,7 +191,8 @@ Use `dryRun: true` to validate parameters, VIP access, estimated credits, and me
|
|
|
164
191
|
"sourceImages": ["/path/to/first-frame.jpg", "/path/to/end-frame.jpg"],
|
|
165
192
|
"seconds": 5,
|
|
166
193
|
"size": "1280x720",
|
|
167
|
-
"resolution": "720p"
|
|
194
|
+
"resolution": "720p",
|
|
195
|
+
"dryRun": true
|
|
168
196
|
}
|
|
169
197
|
```
|
|
170
198
|
|
|
@@ -180,7 +208,8 @@ Text-to-video:
|
|
|
180
208
|
"seconds": 5,
|
|
181
209
|
"size": "1280x720",
|
|
182
210
|
"ratio": "16:9",
|
|
183
|
-
"resolution": "720p"
|
|
211
|
+
"resolution": "720p",
|
|
212
|
+
"dryRun": true
|
|
184
213
|
}
|
|
185
214
|
```
|
|
186
215
|
|
|
@@ -194,7 +223,8 @@ Image-to-video:
|
|
|
194
223
|
"sourceImage": "/path/to/product.jpg",
|
|
195
224
|
"seconds": 5,
|
|
196
225
|
"size": "720x1280",
|
|
197
|
-
"resolution": "720p"
|
|
226
|
+
"resolution": "720p",
|
|
227
|
+
"dryRun": true
|
|
198
228
|
}
|
|
199
229
|
```
|
|
200
230
|
|
|
@@ -209,7 +239,8 @@ Image-to-video:
|
|
|
209
239
|
"seconds": 10,
|
|
210
240
|
"size": "720x1280",
|
|
211
241
|
"ratio": "9:16",
|
|
212
|
-
"resolution": "720p"
|
|
242
|
+
"resolution": "720p",
|
|
243
|
+
"dryRun": true
|
|
213
244
|
}
|
|
214
245
|
```
|
|
215
246
|
|
|
@@ -222,11 +253,12 @@ Image-to-video:
|
|
|
222
253
|
"taskMode": "edit",
|
|
223
254
|
"sourceVideos": ["/path/to/input.mp4"],
|
|
224
255
|
"sourceImages": ["/path/to/reference.jpg"],
|
|
225
|
-
"resolution": "720p"
|
|
256
|
+
"resolution": "720p",
|
|
257
|
+
"dryRun": true
|
|
226
258
|
}
|
|
227
259
|
```
|
|
228
260
|
|
|
229
|
-
After creating a task, use `get_video_status` with the returned `taskId` to query progress and video links.
|
|
261
|
+
After dry run succeeds and `estimatedCredits` looks correct, remove `dryRun` or set it to `false` to create the real task. After creating a task, use `get_video_status` with the returned `taskId` to query progress and video links.
|
|
230
262
|
|
|
231
263
|
## Development
|
|
232
264
|
|
|
@@ -245,7 +277,7 @@ npm run build
|
|
|
245
277
|
npm run test:smoke
|
|
246
278
|
|
|
247
279
|
# Run in development mode
|
|
248
|
-
node dist/index.js
|
|
280
|
+
SORA_MCP_TOKEN=YOUR_TOKEN node dist/index.js
|
|
249
281
|
```
|
|
250
282
|
|
|
251
283
|
### Local MCP testing
|
|
@@ -255,7 +287,7 @@ node dist/index.js --token=YOUR_TOKEN
|
|
|
255
287
|
```bash
|
|
256
288
|
cd mcp-server
|
|
257
289
|
npm run build
|
|
258
|
-
npx @modelcontextprotocol/inspector node dist/index.js
|
|
290
|
+
SORA_MCP_TOKEN=YOUR_TOKEN npx @modelcontextprotocol/inspector node dist/index.js
|
|
259
291
|
```
|
|
260
292
|
|
|
261
293
|
Set `SORA_API_URL=http://localhost:3000/api` when testing against a local app server.
|
|
@@ -267,8 +299,9 @@ Set `SORA_API_URL=http://localhost:3000/api` when testing against a local app se
|
|
|
267
299
|
"mcpServers": {
|
|
268
300
|
"sora-video-generator-local": {
|
|
269
301
|
"command": "node",
|
|
270
|
-
"args": ["/absolute/path/to/sora_video_generator/mcp-server/dist/index.js"
|
|
302
|
+
"args": ["/absolute/path/to/sora_video_generator/mcp-server/dist/index.js"],
|
|
271
303
|
"env": {
|
|
304
|
+
"SORA_MCP_TOKEN": "YOUR_TOKEN",
|
|
272
305
|
"SORA_API_URL": "http://localhost:3000/api"
|
|
273
306
|
}
|
|
274
307
|
}
|
|
@@ -283,8 +316,9 @@ Set `SORA_API_URL=http://localhost:3000/api` when testing against a local app se
|
|
|
283
316
|
"mcpServers": {
|
|
284
317
|
"sora-video-generator": {
|
|
285
318
|
"command": "npx",
|
|
286
|
-
"args": ["-y", "@infimind/video-mcp-cli"
|
|
319
|
+
"args": ["-y", "@infimind/video-mcp-cli"],
|
|
287
320
|
"env": {
|
|
321
|
+
"SORA_MCP_TOKEN": "YOUR_TOKEN",
|
|
288
322
|
"SORA_API_URL": "https://your-api-domain.com/api"
|
|
289
323
|
}
|
|
290
324
|
}
|
|
@@ -298,16 +332,23 @@ Set `SORA_API_URL=http://localhost:3000/api` when testing against a local app se
|
|
|
298
332
|
- If `get_video_status` cannot connect, verify `SORA_API_URL` includes `/api`, for example `http://localhost:3000/api`.
|
|
299
333
|
- If S5/S6 returns VIP errors, confirm the MCP token belongs to a VIP user.
|
|
300
334
|
- If S6 reference/edit prompts contain `@图片N`, keep the original markers; those modes skip prompt translation to preserve image references.
|
|
301
|
-
- If local file inputs fail, use absolute paths and supported media types: jpg/png/webp/gif, mp4/mov
|
|
335
|
+
- If local file inputs fail, use absolute paths and supported media types: jpg/png/webp/gif, mp4/mov, mp3/wav.
|
|
302
336
|
|
|
303
337
|
## Publishing
|
|
304
338
|
|
|
305
339
|
```bash
|
|
306
|
-
# Build
|
|
340
|
+
# Build and verify local dist
|
|
307
341
|
npm run build
|
|
342
|
+
npm run test:smoke
|
|
343
|
+
|
|
344
|
+
# Verify the package contents that npm will publish
|
|
345
|
+
npm run test:smoke:package
|
|
308
346
|
|
|
309
347
|
# Publish to npm
|
|
310
348
|
npm publish --access public
|
|
349
|
+
|
|
350
|
+
# Optional after publishing: verify latest through npx
|
|
351
|
+
npm run test:smoke:published
|
|
311
352
|
```
|
|
312
353
|
|
|
313
354
|
## Security
|
package/dist/index.js
CHANGED
|
@@ -4,23 +4,28 @@ import { createServer } from "./server.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* CLI Entry Point for Sora MCP Server
|
|
6
6
|
*
|
|
7
|
-
* Usage: sora-mcp
|
|
7
|
+
* Usage: sora-mcp
|
|
8
8
|
*
|
|
9
9
|
* Environment Variables:
|
|
10
|
+
* SORA_MCP_TOKEN - MCP API token
|
|
10
11
|
* SORA_API_URL - API base URL (default: http://localhost:3000/api)
|
|
11
12
|
*/
|
|
12
13
|
async function main() {
|
|
13
14
|
// Parse command line arguments
|
|
14
15
|
const args = process.argv.slice(2);
|
|
15
16
|
const tokenArg = args.find(arg => arg.startsWith("--token="));
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const tokenEnvArg = args.find(arg => arg.startsWith("--token-env="));
|
|
18
|
+
const explicitTokenEnvName = tokenEnvArg?.split("=")[1];
|
|
19
|
+
const tokenEnvName = explicitTokenEnvName || "SORA_MCP_TOKEN";
|
|
20
|
+
if (tokenEnvArg && !explicitTokenEnvName) {
|
|
21
|
+
console.error("Error: --token-env value is empty");
|
|
22
|
+
console.error("Usage: sora-mcp --token-env=SORA_MCP_TOKEN");
|
|
19
23
|
process.exit(1);
|
|
20
24
|
}
|
|
21
|
-
const
|
|
25
|
+
const tokenFromEnv = process.env[tokenEnvName];
|
|
26
|
+
const token = tokenFromEnv || tokenArg?.split("=")[1];
|
|
22
27
|
if (!token) {
|
|
23
|
-
console.error(
|
|
28
|
+
console.error(`Error: token is required. Set ${tokenEnvName} or pass --token=YOUR_TOKEN.`);
|
|
24
29
|
process.exit(1);
|
|
25
30
|
}
|
|
26
31
|
// Get API URL from environment variable or use default
|
package/dist/server.js
CHANGED
|
@@ -198,6 +198,19 @@ export function createServer(token, apiBaseUrl) {
|
|
|
198
198
|
progress: { type: "number" },
|
|
199
199
|
totalVideos: { type: "number" },
|
|
200
200
|
completedVideos: { type: "number" },
|
|
201
|
+
estimatedCredits: { type: "number" },
|
|
202
|
+
chargedVideos: { type: "number" },
|
|
203
|
+
actualRoute: { type: "string" },
|
|
204
|
+
taskMode: { type: ["string", "null"] },
|
|
205
|
+
retryCount: { type: "number" },
|
|
206
|
+
statusHint: { type: "string" },
|
|
207
|
+
createdAt: { type: ["string", "null"] },
|
|
208
|
+
updatedAt: { type: ["string", "null"] },
|
|
209
|
+
completedAt: { type: ["string", "null"] },
|
|
210
|
+
errorMessage: { type: "string" },
|
|
211
|
+
errorCode: { type: "string" },
|
|
212
|
+
errorCategory: { type: "string" },
|
|
213
|
+
retryable: { type: "boolean" },
|
|
201
214
|
code: { type: "string" },
|
|
202
215
|
message: { type: "string" },
|
|
203
216
|
route: { type: "string" },
|
|
@@ -212,6 +225,14 @@ export function createServer(token, apiBaseUrl) {
|
|
|
212
225
|
videoUrl: { type: ["string", "null"] },
|
|
213
226
|
thumbnailUrl: { type: ["string", "null"] },
|
|
214
227
|
errorMessage: { type: ["string", "null"] },
|
|
228
|
+
errorCode: { type: ["string", "null"] },
|
|
229
|
+
errorCategory: { type: ["string", "null"] },
|
|
230
|
+
retryable: { type: ["boolean", "null"] },
|
|
231
|
+
actualRoute: { type: ["string", "null"] },
|
|
232
|
+
retryCount: { type: "number" },
|
|
233
|
+
creditsCharged: { type: "boolean" },
|
|
234
|
+
createdAt: { type: ["string", "null"] },
|
|
235
|
+
completedAt: { type: ["string", "null"] },
|
|
215
236
|
},
|
|
216
237
|
required: ["id", "status", "videoUrl", "thumbnailUrl", "errorMessage"],
|
|
217
238
|
},
|
|
@@ -570,26 +591,32 @@ function validateCreateVideoArgs(args) {
|
|
|
570
591
|
*/
|
|
571
592
|
async function handleCreateVideoTask(apiBaseUrl, token, args) {
|
|
572
593
|
const normalized = validateCreateVideoArgs(args);
|
|
573
|
-
const
|
|
594
|
+
const isProfessionalRoute = normalized.route === "S5" || normalized.route === "S6";
|
|
595
|
+
const requestBody = {
|
|
574
596
|
token,
|
|
575
597
|
prompt: args.prompt,
|
|
576
|
-
sourceImage: args.sourceImage
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
sourceAudios: await processFileInputs(args.sourceAudios, "audio"),
|
|
598
|
+
sourceImage: args.sourceImage
|
|
599
|
+
? (await processFileInput(args.sourceImage, "image")).data
|
|
600
|
+
: undefined,
|
|
580
601
|
size: args.size || "1280x720",
|
|
581
602
|
seconds: args.seconds || 10,
|
|
582
603
|
language: args.language || "zh-CN",
|
|
583
604
|
count: args.count || 1,
|
|
584
605
|
route: normalized.route,
|
|
585
|
-
taskMode: normalized.taskMode,
|
|
586
|
-
isFirstLastMode: normalized.taskMode === "firstlast",
|
|
587
|
-
resolution: normalized.resolution,
|
|
588
|
-
ratio: args.ratio || undefined,
|
|
589
|
-
generateAudio: args.generateAudio,
|
|
590
|
-
webSearchEnabled: args.webSearchEnabled,
|
|
591
606
|
dryRun: normalized.dryRun,
|
|
592
|
-
}
|
|
607
|
+
};
|
|
608
|
+
if (isProfessionalRoute) {
|
|
609
|
+
requestBody.sourceImages = await processFileInputs(args.sourceImages, "image");
|
|
610
|
+
requestBody.sourceVideos = await processFileInputs(args.sourceVideos, "video");
|
|
611
|
+
requestBody.sourceAudios = await processFileInputs(args.sourceAudios, "audio");
|
|
612
|
+
requestBody.taskMode = normalized.taskMode;
|
|
613
|
+
requestBody.isFirstLastMode = normalized.taskMode === "firstlast";
|
|
614
|
+
requestBody.resolution = normalized.resolution;
|
|
615
|
+
requestBody.ratio = args.ratio || undefined;
|
|
616
|
+
requestBody.generateAudio = args.generateAudio;
|
|
617
|
+
requestBody.webSearchEnabled = args.webSearchEnabled;
|
|
618
|
+
}
|
|
619
|
+
const response = await callRestApi(apiBaseUrl, "/mcp/video/create", requestBody, "POST");
|
|
593
620
|
const route = response.route || normalized.route;
|
|
594
621
|
const engineName = response.engineName || getMcpEngineName(route);
|
|
595
622
|
const taskMode = response.taskMode || normalized.taskMode;
|
|
@@ -650,8 +677,21 @@ async function handleGetVideoStatus(apiBaseUrl, token, args) {
|
|
|
650
677
|
`- **任务 ID**: ${response.taskId}`,
|
|
651
678
|
`- **状态**: ${statusText}`,
|
|
652
679
|
`- **进度**: ${response.progress}% (${response.completedVideos}/${response.totalVideos} 个视频)`,
|
|
680
|
+
response.engineName ? `- **生成引擎**: ${response.engineName}` : undefined,
|
|
681
|
+
response.taskMode ? `- **模式**: ${response.taskMode}` : undefined,
|
|
682
|
+
response.actualRoute ? `- **实际线路**: ${response.actualRoute}` : undefined,
|
|
683
|
+
typeof response.estimatedCredits === "number" ? `- **预估积分**: ${response.estimatedCredits}` : undefined,
|
|
684
|
+
typeof response.chargedVideos === "number" ? `- **已扣费视频**: ${response.chargedVideos}/${response.totalVideos}` : undefined,
|
|
685
|
+
typeof response.retryCount === "number" ? `- **重试次数**: ${response.retryCount}` : undefined,
|
|
653
686
|
``,
|
|
654
|
-
];
|
|
687
|
+
].filter((line) => line !== undefined);
|
|
688
|
+
if (response.errorMessage) {
|
|
689
|
+
result.push(`- **错误**: ${response.errorMessage}`);
|
|
690
|
+
if (response.errorCode) {
|
|
691
|
+
result.push(`- **错误代码**: ${response.errorCode}`);
|
|
692
|
+
}
|
|
693
|
+
result.push(``);
|
|
694
|
+
}
|
|
655
695
|
if (response.videos && response.videos.length > 0) {
|
|
656
696
|
result.push(`## 视频列表:`);
|
|
657
697
|
response.videos.forEach((video, index) => {
|
|
@@ -669,8 +709,23 @@ async function handleGetVideoStatus(apiBaseUrl, token, args) {
|
|
|
669
709
|
if (video.errorMessage) {
|
|
670
710
|
result.push(` ❌ 错误: ${video.errorMessage}`);
|
|
671
711
|
}
|
|
712
|
+
if (video.errorCode) {
|
|
713
|
+
result.push(` 错误代码: ${video.errorCode}`);
|
|
714
|
+
}
|
|
715
|
+
if (video.actualRoute) {
|
|
716
|
+
result.push(` 实际线路: ${video.actualRoute}`);
|
|
717
|
+
}
|
|
718
|
+
if (typeof video.retryCount === "number" && video.retryCount > 0) {
|
|
719
|
+
result.push(` 重试次数: ${video.retryCount}`);
|
|
720
|
+
}
|
|
721
|
+
if (typeof video.creditsCharged === "boolean") {
|
|
722
|
+
result.push(` 已扣费: ${video.creditsCharged ? "是" : "否"}`);
|
|
723
|
+
}
|
|
672
724
|
});
|
|
673
725
|
}
|
|
726
|
+
if (response.statusHint) {
|
|
727
|
+
result.push(``, response.statusHint);
|
|
728
|
+
}
|
|
674
729
|
return {
|
|
675
730
|
content: [
|
|
676
731
|
{
|
|
@@ -685,6 +740,21 @@ async function handleGetVideoStatus(apiBaseUrl, token, args) {
|
|
|
685
740
|
progress: response.progress,
|
|
686
741
|
totalVideos: response.totalVideos,
|
|
687
742
|
completedVideos: response.completedVideos,
|
|
743
|
+
route: response.route,
|
|
744
|
+
engineName: response.engineName,
|
|
745
|
+
taskMode: response.taskMode,
|
|
746
|
+
actualRoute: response.actualRoute,
|
|
747
|
+
retryCount: response.retryCount,
|
|
748
|
+
chargedVideos: response.chargedVideos,
|
|
749
|
+
estimatedCredits: response.estimatedCredits,
|
|
750
|
+
statusHint: response.statusHint,
|
|
751
|
+
createdAt: response.createdAt,
|
|
752
|
+
updatedAt: response.updatedAt,
|
|
753
|
+
completedAt: response.completedAt,
|
|
754
|
+
errorMessage: response.errorMessage,
|
|
755
|
+
errorCode: response.errorCode,
|
|
756
|
+
errorCategory: response.errorCategory,
|
|
757
|
+
retryable: response.retryable,
|
|
688
758
|
videos: response.videos || [],
|
|
689
759
|
},
|
|
690
760
|
};
|
|
@@ -854,7 +924,11 @@ async function callRestApi(apiBaseUrl, path, params, method = "GET") {
|
|
|
854
924
|
const data = await response.json();
|
|
855
925
|
// Check for error in response
|
|
856
926
|
if (data.error) {
|
|
857
|
-
|
|
927
|
+
const toolError = new McpToolError(data.error.message || "API 返回错误", data.error.code || "API_ERROR", data.error.route);
|
|
928
|
+
if (data.error.engineName) {
|
|
929
|
+
toolError.engineName = data.error.engineName;
|
|
930
|
+
}
|
|
931
|
+
throw toolError;
|
|
858
932
|
}
|
|
859
933
|
return data;
|
|
860
934
|
}
|
package/dist/videoRules.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type McpRoute = "S2" | "S5" | "S6";
|
|
2
2
|
export type McpTaskMode = "allinone" | "firstlast" | "standard" | "reference" | "edit";
|
|
3
|
-
export declare const MCP_SERVER_VERSION = "1.0.
|
|
3
|
+
export declare const MCP_SERVER_VERSION = "1.0.9";
|
|
4
4
|
export declare const MCP_VIDEO_STATUS_HINT = "\u4EFB\u52A1\u5DF2\u521B\u5EFA\u540E\uFF0C\u4F7F\u7528 get_video_status \u5E76\u4F20\u5165 taskId \u67E5\u8BE2\u751F\u6210\u8FDB\u5EA6\u548C\u89C6\u9891\u94FE\u63A5\u3002";
|
|
5
5
|
export declare const MCP_VIDEO_DRY_RUN_HINT = "dryRun \u4EC5\u5B8C\u6210\u53C2\u6570\u3001\u6743\u9650\u3001\u79EF\u5206\u548C\u7D20\u6750\u89C4\u5219\u9884\u68C0\uFF0C\u4E0D\u4F1A\u521B\u5EFA\u4EFB\u52A1\u6216\u6263\u8D39\u3002";
|
|
6
6
|
export declare const MCP_VIDEO_ENGINES: Record<McpRoute, {
|
package/dist/videoRules.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const MCP_SERVER_VERSION = "1.0.
|
|
1
|
+
export const MCP_SERVER_VERSION = "1.0.9";
|
|
2
2
|
export const MCP_VIDEO_STATUS_HINT = "任务已创建后,使用 get_video_status 并传入 taskId 查询生成进度和视频链接。";
|
|
3
3
|
export const MCP_VIDEO_DRY_RUN_HINT = "dryRun 仅完成参数、权限、积分和素材规则预检,不会创建任务或扣费。";
|
|
4
4
|
export const MCP_VIDEO_ENGINES = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infimind/video-mcp-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "MCP Server for Sora AI Video Generator - Access video generation features through Claude Desktop",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"build": "tsc",
|
|
16
16
|
"dev": "tsc --watch",
|
|
17
17
|
"test:smoke": "node scripts/smoke-test.mjs",
|
|
18
|
-
"
|
|
18
|
+
"test:smoke:package": "MCP_SMOKE_TARGET=package node scripts/smoke-test.mjs",
|
|
19
|
+
"test:smoke:published": "MCP_SMOKE_TARGET=published node scripts/smoke-test.mjs",
|
|
20
|
+
"prepublishOnly": "npm run build && npm run test:smoke:package"
|
|
19
21
|
},
|
|
20
22
|
"keywords": [
|
|
21
23
|
"mcp",
|