@infimind/video-mcp-cli 1.0.12 → 1.0.13

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 CHANGED
@@ -78,6 +78,7 @@ After saving the configuration, restart Claude Desktop for the changes to take e
78
78
  Get information about the authenticated user.
79
79
 
80
80
  **Example usage in Claude:**
81
+
81
82
  ```
82
83
  Get my user information for the video generator
83
84
  ```
@@ -86,28 +87,32 @@ Get my user information for the video generator
86
87
 
87
88
  Create a video generation task.
88
89
 
89
- Supported engines:
90
+ Supported models (pass `model`; `route` is a deprecated legacy alias):
91
+
92
+ - `WA`: 极睿WA专业版 (default; available to non-VIP users)
93
+ - `SD`: 极睿SD专业版 (VIP only)
94
+ - `SD25`: 极睿SD2.5专业版 (VIP only)
95
+ - `HA`: 极睿HA专业版 (VIP only)
96
+ - `H3`: 极睿H3专业版 (VIP only)
90
97
 
91
- - `S2`: 极睿Sa专业版
92
- - `S5`: 极睿Sd专业版 (VIP only)
93
- - `S6`: 极睿Ha专业版 (VIP only)
98
+ `SA` (Sora 2 / route `S2`/`S10`) is retired. Requests that still send it are rejected with `MODEL_RETIRED`; use `WA` instead.
94
99
 
95
100
  Parameter applicability:
96
101
 
97
- | Parameter | S2 极睿Sa专业版 | S5 极睿Sd专业版 | S6 极睿Ha专业版 |
98
- | --- | --- | --- | --- |
99
- | `sourceImage` | Optional single image | Not supported | Standard mode single image |
100
- | `sourceImages` | Not supported | allinone / firstlast images | reference / edit reference images |
101
- | `sourceVideos` | Not supported | allinone reference videos | edit input videos |
102
- | `sourceAudios` | Not supported | allinone reference audio | Not supported |
103
- | `sourceVideoDurationSeconds` | Not supported | dryRun estimate for videos | dryRun estimate for edit video |
104
- | `sourceAudioDurationSeconds` | Not supported | dryRun estimate for audio | Not supported |
105
- | `taskMode` | Not needed | `allinone` / `firstlast` | `standard` / `reference` / `edit` |
106
- | `resolution` | Not supported | `720p` / `1080p` | `720p` / `1080p` |
107
- | `ratio` | Not supported | Not supported | reference or text-to-video standard mode |
108
- | `generateAudio` | Not supported | Optional | Not supported |
109
- | `webSearchEnabled` | Not supported | Optional | Not supported |
110
- | `dryRun` | Optional preflight | Optional preflight | Optional preflight |
102
+ | Parameter | WA 极睿WA专业版 | SD 极睿SD专业版 | HA 极睿HA专业版 |
103
+ | ---------------------------- | ---------------------------------- | --------------------------- | ---------------------------------------- |
104
+ | `sourceImage` | Not supported | Not supported | Standard mode single image |
105
+ | `sourceImages` | allinone / firstlast / edit images | allinone / firstlast images | reference / edit reference images |
106
+ | `sourceVideos` | allinone / edit reference videos | allinone reference videos | edit input videos |
107
+ | `sourceAudios` | allinone / edit reference audio | allinone reference audio | Not supported |
108
+ | `sourceVideoDurationSeconds` | dryRun estimate for videos | dryRun estimate for videos | dryRun estimate for edit video |
109
+ | `sourceAudioDurationSeconds` | dryRun estimate for audio | dryRun estimate for audio | Not supported |
110
+ | `taskMode` | `allinone` / `firstlast` / `edit` | `allinone` / `firstlast` | `standard` / `reference` / `edit` |
111
+ | `resolution` | `480p` / `720p` / `1080p` | `720p` / `1080p` | `720p` / `1080p` |
112
+ | `ratio` | `adaptive` / `16:9` / `9:16` / ... | Not supported | reference or text-to-video standard mode |
113
+ | `generateAudio` | Optional | Optional | Not supported |
114
+ | `webSearchEnabled` | Not supported | Optional | Not supported |
115
+ | `dryRun` | Optional preflight | Optional preflight | Optional preflight |
111
116
 
112
117
  Local file paths and public URLs are both supported.
113
118
 
@@ -117,10 +122,12 @@ Media limits:
117
122
 
118
123
  - Local video files: MP4/MOV, up to 50MB each, 2-15 seconds.
119
124
  - Local audio files: MP3/WAV, up to 15MB each, 2-15 seconds.
120
- - S5 allinone: up to 9 images, 3 videos, and 3 audio files.
121
- - S5 firstlast: up to 2 images; the first frame is required.
122
- - S6 reference: up to 9 images.
123
- - S6 edit: up to 1 video and 5 images.
125
+ - WA: up to 10 images, 5 videos, and 5 audio files; fixed 5/10/15/20/25/30-second output (Edit uses smart duration only).
126
+ - SD allinone: up to 9 images, 3 videos, and 3 audio files.
127
+ - SD firstlast: up to 2 images; the first frame is required.
128
+ - SD25 allinone/edit: up to 30 images, 10 videos, and 10 audio files.
129
+ - HA reference: up to 9 images.
130
+ - HA edit: up to 1 video and 5 images.
124
131
 
125
132
  URL safety rules:
126
133
 
@@ -146,17 +153,20 @@ Use `dryRun: true` to validate parameters, VIP access, media rules, and estimate
146
153
  }
147
154
  ```
148
155
 
149
- #### 极睿Sa专业版 - 标准生成
156
+ #### 极睿WA专业版 - 全能参考(默认模型)
150
157
 
151
- S2 uses `sourceImage`, `seconds`, and `size`; do not pass `taskMode` or `resolution`.
158
+ WA is the default model when `model` is omitted. Do not pass `sourceImage` or `webSearchEnabled`.
152
159
 
153
160
  ```json
154
161
  {
155
162
  "prompt": "一个高质感的产品展示视频,柔和布光,镜头缓慢推进",
156
- "route": "S2",
157
- "sourceImage": "/path/to/product.jpg",
158
- "seconds": 10,
163
+ "model": "WA",
164
+ "taskMode": "allinone",
165
+ "sourceImages": ["/path/to/product.jpg"],
166
+ "seconds": 5,
159
167
  "size": "720x1280",
168
+ "ratio": "9:16",
169
+ "resolution": "720p",
160
170
  "language": "zh-CN",
161
171
  "count": 1,
162
172
  "dryRun": true
@@ -346,7 +356,9 @@ Set `SORA_API_URL=http://localhost:3000/api` when testing against a local app se
346
356
  "mcpServers": {
347
357
  "sora-video-generator-local": {
348
358
  "command": "node",
349
- "args": ["/absolute/path/to/sora_video_generator/mcp-server/dist/index.js"],
359
+ "args": [
360
+ "/absolute/path/to/sora_video_generator/mcp-server/dist/index.js"
361
+ ],
350
362
  "env": {
351
363
  "SORA_MCP_TOKEN": "YOUR_TOKEN",
352
364
  "SORA_API_URL": "http://localhost:3000/api"
@@ -28,7 +28,8 @@ function assertPermissions() {
28
28
  }
29
29
  }
30
30
  catch (err) {
31
- if (err instanceof Error && err.message.startsWith("credentials directory")) {
31
+ if (err instanceof Error &&
32
+ err.message.startsWith("credentials directory")) {
32
33
  throw err;
33
34
  }
34
35
  }
@@ -17,7 +17,10 @@ export async function exchangeAuthorizationCode(input) {
17
17
  try {
18
18
  resp = await fetch(url, {
19
19
  method: "POST",
20
- headers: { "Content-Type": "application/json", Accept: "application/json" },
20
+ headers: {
21
+ "Content-Type": "application/json",
22
+ Accept: "application/json",
23
+ },
21
24
  body: JSON.stringify(body),
22
25
  });
23
26
  }
@@ -44,7 +47,10 @@ export async function revokeWorkbuddyToken(input) {
44
47
  try {
45
48
  const resp = await fetch(url, {
46
49
  method: "POST",
47
- headers: { "Content-Type": "application/json", Accept: "application/json" },
50
+ headers: {
51
+ "Content-Type": "application/json",
52
+ Accept: "application/json",
53
+ },
48
54
  body: JSON.stringify({
49
55
  token: input.accessToken,
50
56
  installation_id: input.installationId,
@@ -5,7 +5,7 @@
5
5
  * hostname to the server; only the hash of this id is sent.
6
6
  */
7
7
  import { randomBytes } from "node:crypto";
8
- import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from "node:fs";
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync, } from "node:fs";
9
9
  import { dirname } from "node:path";
10
10
  import { installationIdFilePath } from "./paths.js";
11
11
  const INSTALLATION_ID_LENGTH = 32; // 32 bytes base64url = 43 chars
@@ -11,11 +11,11 @@
11
11
  */
12
12
  import { bindLoopback } from "./loopback.js";
13
13
  import { readOrCreateInstallationId } from "./installationId.js";
14
- import { exchangeAuthorizationCode, defaultApiUrl, } from "./exchange.js";
14
+ import { exchangeAuthorizationCode, defaultApiUrl } from "./exchange.js";
15
15
  import { writeCredentials } from "./credentialWriter.js";
16
16
  const TIMEOUT_MS = 5 * 60 * 1000;
17
17
  const PRINT_URL_DEADLINE_MS = 10_000;
18
- const CLI_VERSION = "1.0.12";
18
+ const CLI_VERSION = "1.0.13";
19
19
  function detectPlatform() {
20
20
  return process.platform;
21
21
  }
@@ -5,7 +5,7 @@
5
5
  * `/oauth/callback` and waits for a single GET with `?code=...&state=...`.
6
6
  * Anything else is rejected with 400.
7
7
  */
8
- import { createServer } from "node:http";
8
+ import { createServer, } from "node:http";
9
9
  import { createHash } from "node:crypto";
10
10
  import { generateCodeVerifier, s256Challenge } from "./pkce.js";
11
11
  async function pickRandomPort(hostname) {
@@ -66,7 +66,9 @@ const ERROR_PAGE = (msg) => `<!doctype html>
66
66
  export async function bindLoopback(opts = {}) {
67
67
  const hostname = opts.hostname ?? "127.0.0.1";
68
68
  const port = opts.preferredPort ?? (await pickRandomPort(hostname));
69
- const stateBytes = createHash("sha256").update(`${Date.now()}.${Math.random()}`).digest();
69
+ const stateBytes = createHash("sha256")
70
+ .update(`${Date.now()}.${Math.random()}`)
71
+ .digest();
70
72
  const state = stateBytes.toString("base64url").slice(0, 32);
71
73
  const codeVerifier = generateCodeVerifier();
72
74
  const codeChallenge = s256Challenge(codeVerifier);
@@ -121,7 +123,7 @@ export async function bindLoopback(opts = {}) {
121
123
  server.listen(port, hostname, () => resolve());
122
124
  });
123
125
  const boundPort = server.address()?.port ?? port;
124
- const close = () => new Promise((resolve) => {
126
+ const close = () => new Promise(resolve => {
125
127
  server.close(() => resolve());
126
128
  });
127
129
  const awaitCallback = (timeoutMs) => new Promise((resolve, reject) => {
@@ -132,7 +134,7 @@ export async function bindLoopback(opts = {}) {
132
134
  }
133
135
  }, timeoutMs);
134
136
  callbackPromise
135
- .then((v) => {
137
+ .then(v => {
136
138
  clearTimeout(timer);
137
139
  resolve(v);
138
140
  })
@@ -11,5 +11,5 @@ export function isWorkbuddyTool(name) {
11
11
  export function filterToolsForProfile(tools, profile) {
12
12
  if (profile !== "workbuddy")
13
13
  return tools;
14
- return tools.filter((t) => isWorkbuddyTool(t.name));
14
+ return tools.filter(t => isWorkbuddyTool(t.name));
15
15
  }
@@ -20,7 +20,11 @@ export function runStatus() {
20
20
  if (process.platform !== "win32") {
21
21
  const mode = st.mode & 0o777;
22
22
  if (mode & 0o077) {
23
- return { authenticated: false, reason: "insecure_permissions", filePath: path };
23
+ return {
24
+ authenticated: false,
25
+ reason: "insecure_permissions",
26
+ filePath: path,
27
+ };
24
28
  }
25
29
  }
26
30
  return { authenticated: true, filePath: path };