@infimind/video-mcp-cli 1.0.0 → 1.0.1
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/dist/server.js +69 -69
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -25,7 +25,7 @@ export function createServer(token, apiBaseUrl) {
|
|
|
25
25
|
const tools = [
|
|
26
26
|
{
|
|
27
27
|
name: "get_user_info",
|
|
28
|
-
description: "
|
|
28
|
+
description: "获取当前用户的信息,包括用户名、姓名、邮箱、角色、积分和 VIP 状态",
|
|
29
29
|
inputSchema: {
|
|
30
30
|
type: "object",
|
|
31
31
|
properties: {},
|
|
@@ -33,48 +33,48 @@ export function createServer(token, apiBaseUrl) {
|
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
name: "create_video_task",
|
|
36
|
-
description: "
|
|
37
|
-
"
|
|
36
|
+
description: "创建视频生成任务。支持本地文件路径或公网 URL 作为参考图片。" +
|
|
37
|
+
"提示词会根据目标语言自动翻译和优化。",
|
|
38
38
|
inputSchema: {
|
|
39
39
|
type: "object",
|
|
40
40
|
properties: {
|
|
41
41
|
prompt: {
|
|
42
42
|
type: "string",
|
|
43
|
-
description: "
|
|
43
|
+
description: "视频生成提示词,描述你想要创建的内容",
|
|
44
44
|
},
|
|
45
45
|
sourceImage: {
|
|
46
46
|
type: "string",
|
|
47
|
-
description: "
|
|
47
|
+
description: "可选的参考图片 - 可以是本地文件路径(如 /path/to/image.jpg)或公网 URL",
|
|
48
48
|
},
|
|
49
49
|
model: {
|
|
50
50
|
type: "string",
|
|
51
|
-
description: "
|
|
51
|
+
description: "使用的视频模型:sora_video2-15s(默认)或 sora-pro",
|
|
52
52
|
enum: ["sora_video2-15s", "sora-pro"],
|
|
53
53
|
},
|
|
54
54
|
size: {
|
|
55
55
|
type: "string",
|
|
56
|
-
description: "
|
|
56
|
+
description: "视频分辨率(默认:1280x704)",
|
|
57
57
|
enum: ["1280x704", "1920x1080", "1080x1920", "704x1280"],
|
|
58
58
|
},
|
|
59
59
|
seconds: {
|
|
60
60
|
type: "number",
|
|
61
|
-
description: "
|
|
61
|
+
description: "视频时长(秒):10(默认)或 15",
|
|
62
62
|
enum: [10, 15],
|
|
63
63
|
},
|
|
64
64
|
language: {
|
|
65
65
|
type: "string",
|
|
66
|
-
description: "
|
|
66
|
+
description: "视频的目标语言(默认:zh-CN)",
|
|
67
67
|
enum: ["zh-CN", "en-US", "ja-JP", "ko-KR", "es-ES", "fr-FR"],
|
|
68
68
|
},
|
|
69
69
|
count: {
|
|
70
70
|
type: "number",
|
|
71
|
-
description: "
|
|
71
|
+
description: "生成的视频数量(1-10,默认:1)",
|
|
72
72
|
minimum: 1,
|
|
73
73
|
maximum: 10,
|
|
74
74
|
},
|
|
75
75
|
route: {
|
|
76
76
|
type: "string",
|
|
77
|
-
description: "API
|
|
77
|
+
description: "使用的 API 线路:S1(默认)、S2 或 S3",
|
|
78
78
|
enum: ["S1", "S2", "S3"],
|
|
79
79
|
},
|
|
80
80
|
},
|
|
@@ -83,13 +83,13 @@ export function createServer(token, apiBaseUrl) {
|
|
|
83
83
|
},
|
|
84
84
|
{
|
|
85
85
|
name: "get_video_status",
|
|
86
|
-
description: "
|
|
86
|
+
description: "获取视频生成任务的状态,包括进度和视频 URL",
|
|
87
87
|
inputSchema: {
|
|
88
88
|
type: "object",
|
|
89
89
|
properties: {
|
|
90
90
|
taskId: {
|
|
91
91
|
type: "number",
|
|
92
|
-
description: "
|
|
92
|
+
description: "视频生成任务 ID",
|
|
93
93
|
},
|
|
94
94
|
},
|
|
95
95
|
required: ["taskId"],
|
|
@@ -97,14 +97,14 @@ export function createServer(token, apiBaseUrl) {
|
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
name: "create_video_analysis_task",
|
|
100
|
-
description: "
|
|
101
|
-
"
|
|
100
|
+
description: "创建视频拆解任务,将视频拆解为脚本、风格、卖点话术、爆款公式,并生成用于视频创作的提示词。" +
|
|
101
|
+
"支持本地文件路径或公网 URL 作为视频文件。",
|
|
102
102
|
inputSchema: {
|
|
103
103
|
type: "object",
|
|
104
104
|
properties: {
|
|
105
105
|
videoFile: {
|
|
106
106
|
type: "string",
|
|
107
|
-
description: "
|
|
107
|
+
description: "要分析的视频文件 - 可以是本地文件路径(如 /path/to/video.mp4)或公网 URL",
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
required: ["videoFile"],
|
|
@@ -112,13 +112,13 @@ export function createServer(token, apiBaseUrl) {
|
|
|
112
112
|
},
|
|
113
113
|
{
|
|
114
114
|
name: "get_video_analysis_status",
|
|
115
|
-
description: "
|
|
115
|
+
description: "获取视频拆解任务的状态和结果",
|
|
116
116
|
inputSchema: {
|
|
117
117
|
type: "object",
|
|
118
118
|
properties: {
|
|
119
119
|
analysisId: {
|
|
120
120
|
type: "number",
|
|
121
|
-
description: "
|
|
121
|
+
description: "视频拆解任务 ID",
|
|
122
122
|
},
|
|
123
123
|
},
|
|
124
124
|
required: ["analysisId"],
|
|
@@ -154,7 +154,7 @@ export function createServer(token, apiBaseUrl) {
|
|
|
154
154
|
content: [
|
|
155
155
|
{
|
|
156
156
|
type: "text",
|
|
157
|
-
text:
|
|
157
|
+
text: `错误:${errorMessage}`,
|
|
158
158
|
},
|
|
159
159
|
],
|
|
160
160
|
isError: true,
|
|
@@ -169,14 +169,14 @@ export function createServer(token, apiBaseUrl) {
|
|
|
169
169
|
async function handleGetUserInfo(apiBaseUrl, token) {
|
|
170
170
|
const response = await callRestApi(apiBaseUrl, "/mcp/user-info", { token }, "GET");
|
|
171
171
|
const userInfo = [
|
|
172
|
-
`#
|
|
172
|
+
`# 用户信息`,
|
|
173
173
|
``,
|
|
174
|
-
`-
|
|
175
|
-
`-
|
|
176
|
-
`-
|
|
177
|
-
`-
|
|
178
|
-
`-
|
|
179
|
-
`- **VIP
|
|
174
|
+
`- **用户名**: ${response.username}`,
|
|
175
|
+
`- **姓名**: ${response.name || "N/A"}`,
|
|
176
|
+
`- **邮箱**: ${response.email || "N/A"}`,
|
|
177
|
+
`- **角色**: ${response.role === "admin" ? "管理员" : "用户"}`,
|
|
178
|
+
`- **积分**: ${response.credits}`,
|
|
179
|
+
`- **VIP 状态**: ${response.isVip ? "是" : "否"}`,
|
|
180
180
|
].join("\n");
|
|
181
181
|
return {
|
|
182
182
|
content: [
|
|
@@ -203,15 +203,15 @@ async function handleCreateVideoTask(apiBaseUrl, token, args) {
|
|
|
203
203
|
route: args.route || "S1",
|
|
204
204
|
}, "POST");
|
|
205
205
|
const result = [
|
|
206
|
-
`#
|
|
206
|
+
`# 视频生成任务已创建`,
|
|
207
207
|
``,
|
|
208
|
-
`-
|
|
209
|
-
`-
|
|
210
|
-
`-
|
|
211
|
-
`-
|
|
212
|
-
`-
|
|
208
|
+
`- **任务 ID**: ${response.taskId}`,
|
|
209
|
+
`- **消息**: ${response.message}`,
|
|
210
|
+
`- **生成视频数量**: ${response.videoCount}`,
|
|
211
|
+
`- **消耗积分**: ${response.creditsUsed}`,
|
|
212
|
+
`- **剩余积分**: ${response.remainingCredits}`,
|
|
213
213
|
``,
|
|
214
|
-
|
|
214
|
+
`使用任务 ID ${response.taskId} 调用 \`get_video_status\` 查看进度。`,
|
|
215
215
|
].join("\n");
|
|
216
216
|
return {
|
|
217
217
|
content: [
|
|
@@ -227,33 +227,33 @@ async function handleCreateVideoTask(apiBaseUrl, token, args) {
|
|
|
227
227
|
*/
|
|
228
228
|
async function handleGetVideoStatus(apiBaseUrl, token, args) {
|
|
229
229
|
const response = await callRestApi(apiBaseUrl, `/mcp/video/status/${args.taskId}`, { token }, "GET");
|
|
230
|
-
const statusText = response.status === "completed" ? "✅
|
|
231
|
-
response.status === "processing" ? "🔄
|
|
232
|
-
response.status === "failed" ? "❌
|
|
230
|
+
const statusText = response.status === "completed" ? "✅ 已完成" :
|
|
231
|
+
response.status === "processing" ? "🔄 处理中" :
|
|
232
|
+
response.status === "failed" ? "❌ 失败" : `⏳ ${response.status}`;
|
|
233
233
|
let result = [
|
|
234
|
-
`#
|
|
234
|
+
`# 视频生成任务状态`,
|
|
235
235
|
``,
|
|
236
|
-
`-
|
|
237
|
-
`-
|
|
238
|
-
`-
|
|
236
|
+
`- **任务 ID**: ${response.taskId}`,
|
|
237
|
+
`- **状态**: ${statusText}`,
|
|
238
|
+
`- **进度**: ${response.progress}% (${response.completedVideos}/${response.totalVideos} 个视频)`,
|
|
239
239
|
``,
|
|
240
240
|
];
|
|
241
241
|
if (response.videos && response.videos.length > 0) {
|
|
242
|
-
result.push(`##
|
|
242
|
+
result.push(`## 视频列表:`);
|
|
243
243
|
response.videos.forEach((video, index) => {
|
|
244
244
|
const videoStatus = video.status === "completed" ? "✅" :
|
|
245
245
|
video.status === "processing" ? "🔄" :
|
|
246
246
|
video.status === "failed" ? "❌" : "⏳";
|
|
247
247
|
result.push(``);
|
|
248
|
-
result.push(`${index + 1}. ${videoStatus}
|
|
248
|
+
result.push(`${index + 1}. ${videoStatus} 视频 ID: ${video.id}`);
|
|
249
249
|
if (video.videoUrl) {
|
|
250
|
-
result.push(` 📹 [
|
|
250
|
+
result.push(` 📹 [视频链接](${video.videoUrl})`);
|
|
251
251
|
}
|
|
252
252
|
if (video.thumbnailUrl) {
|
|
253
|
-
result.push(` 🖼️ [
|
|
253
|
+
result.push(` 🖼️ [缩略图](${video.thumbnailUrl})`);
|
|
254
254
|
}
|
|
255
255
|
if (video.errorMessage) {
|
|
256
|
-
result.push(` ❌
|
|
256
|
+
result.push(` ❌ 错误: ${video.errorMessage}`);
|
|
257
257
|
}
|
|
258
258
|
});
|
|
259
259
|
}
|
|
@@ -275,14 +275,14 @@ async function handleCreateVideoAnalysisTask(apiBaseUrl, token, args) {
|
|
|
275
275
|
videoFile: args.videoFile,
|
|
276
276
|
}, "POST");
|
|
277
277
|
const result = [
|
|
278
|
-
`#
|
|
278
|
+
`# 视频拆解任务已创建`,
|
|
279
279
|
``,
|
|
280
|
-
`-
|
|
281
|
-
`-
|
|
282
|
-
`-
|
|
283
|
-
`-
|
|
280
|
+
`- **分析 ID**: ${response.analysisId}`,
|
|
281
|
+
`- **消息**: ${response.message}`,
|
|
282
|
+
`- **消耗积分**: ${response.creditsUsed}`,
|
|
283
|
+
`- **剩余积分**: ${response.remainingCredits}`,
|
|
284
284
|
``,
|
|
285
|
-
|
|
285
|
+
`使用分析 ID ${response.analysisId} 调用 \`get_video_analysis_status\` 查看进度。`,
|
|
286
286
|
].join("\n");
|
|
287
287
|
return {
|
|
288
288
|
content: [
|
|
@@ -298,45 +298,45 @@ async function handleCreateVideoAnalysisTask(apiBaseUrl, token, args) {
|
|
|
298
298
|
*/
|
|
299
299
|
async function handleGetVideoAnalysisStatus(apiBaseUrl, token, args) {
|
|
300
300
|
const response = await callRestApi(apiBaseUrl, `/mcp/video-analysis/status/${args.analysisId}`, { token }, "GET");
|
|
301
|
-
const statusText = response.status === "completed" ? "✅
|
|
302
|
-
response.status === "processing" ? "🔄
|
|
303
|
-
response.status === "pending" ? "⏳
|
|
304
|
-
response.status === "failed" ? "❌
|
|
301
|
+
const statusText = response.status === "completed" ? "✅ 已完成" :
|
|
302
|
+
response.status === "processing" ? "🔄 处理中" :
|
|
303
|
+
response.status === "pending" ? "⏳ 等待中" :
|
|
304
|
+
response.status === "failed" ? "❌ 失败" : `⏳ ${response.status}`;
|
|
305
305
|
let result = [
|
|
306
|
-
`#
|
|
306
|
+
`# 视频拆解任务状态`,
|
|
307
307
|
``,
|
|
308
|
-
`-
|
|
309
|
-
`-
|
|
308
|
+
`- **分析 ID**: ${response.analysisId}`,
|
|
309
|
+
`- **状态**: ${statusText}`,
|
|
310
310
|
];
|
|
311
311
|
if (response.conversionProgress !== null) {
|
|
312
|
-
result.push(`-
|
|
312
|
+
result.push(`- **转换进度**: ${response.conversionProgress}%`);
|
|
313
313
|
}
|
|
314
314
|
if (response.status === "completed") {
|
|
315
315
|
result.push(``);
|
|
316
|
-
result.push(`##
|
|
316
|
+
result.push(`## 分析结果:`);
|
|
317
317
|
result.push(``);
|
|
318
318
|
if (response.script) {
|
|
319
|
-
result.push(`### 📝
|
|
319
|
+
result.push(`### 📝 视频脚本`);
|
|
320
320
|
result.push(response.script);
|
|
321
321
|
result.push(``);
|
|
322
322
|
}
|
|
323
323
|
if (response.style) {
|
|
324
|
-
result.push(`### 🎨
|
|
324
|
+
result.push(`### 🎨 视频风格`);
|
|
325
325
|
result.push(response.style);
|
|
326
326
|
result.push(``);
|
|
327
327
|
}
|
|
328
328
|
if (response.sellingPoints) {
|
|
329
|
-
result.push(`### 🎯
|
|
329
|
+
result.push(`### 🎯 卖点话术`);
|
|
330
330
|
result.push(response.sellingPoints);
|
|
331
331
|
result.push(``);
|
|
332
332
|
}
|
|
333
333
|
if (response.viralFormula) {
|
|
334
|
-
result.push(`### 💡
|
|
334
|
+
result.push(`### 💡 爆款公式`);
|
|
335
335
|
result.push(response.viralFormula);
|
|
336
336
|
result.push(``);
|
|
337
337
|
}
|
|
338
338
|
if (response.generatedPrompt) {
|
|
339
|
-
result.push(`### 🎬
|
|
339
|
+
result.push(`### 🎬 生成的提示词(用于 Sora)`);
|
|
340
340
|
result.push(`\`\`\``);
|
|
341
341
|
result.push(response.generatedPrompt);
|
|
342
342
|
result.push(`\`\`\``);
|
|
@@ -344,12 +344,12 @@ async function handleGetVideoAnalysisStatus(apiBaseUrl, token, args) {
|
|
|
344
344
|
}
|
|
345
345
|
else if (response.status === "failed" && response.errorMessage) {
|
|
346
346
|
result.push(``);
|
|
347
|
-
result.push(`### ❌
|
|
347
|
+
result.push(`### ❌ 错误信息`);
|
|
348
348
|
result.push(response.errorMessage);
|
|
349
349
|
}
|
|
350
350
|
if (response.videoFileName) {
|
|
351
351
|
result.push(``);
|
|
352
|
-
result.push(
|
|
352
|
+
result.push(`**源文件**: ${response.videoFileName}`);
|
|
353
353
|
}
|
|
354
354
|
return {
|
|
355
355
|
content: [
|
|
@@ -388,12 +388,12 @@ async function callRestApi(apiBaseUrl, path, params, method = "GET") {
|
|
|
388
388
|
});
|
|
389
389
|
if (!response.ok) {
|
|
390
390
|
const errorText = await response.text();
|
|
391
|
-
throw new Error(`API
|
|
391
|
+
throw new Error(`API 请求失败,状态码 ${response.status}: ${errorText}`);
|
|
392
392
|
}
|
|
393
393
|
const data = await response.json();
|
|
394
394
|
// Check for error in response
|
|
395
395
|
if (data.error) {
|
|
396
|
-
throw new Error(data.error.message || "API
|
|
396
|
+
throw new Error(data.error.message || "API 返回错误");
|
|
397
397
|
}
|
|
398
398
|
return data;
|
|
399
399
|
}
|
package/package.json
CHANGED