@cueai/omni-reader-mcp 1.5.2 → 1.5.3
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 +36 -29
- package/dist/cli/agent-config.js +26 -20
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/cube-client.js +42 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ differ from the numbers above, report the live values.
|
|
|
64
64
|
Always use an audited exact version, never an implicit `latest`:
|
|
65
65
|
|
|
66
66
|
```sh
|
|
67
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
67
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 setup
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
The interactive setup supports Hermes, Cursor, Claude Desktop, and generic stdio
|
|
@@ -72,9 +72,9 @@ configuration. Non-interactive installation uses the same argument parsing and w
|
|
|
72
72
|
logic:
|
|
73
73
|
|
|
74
74
|
```sh
|
|
75
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
76
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
77
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
75
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
|
|
76
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 setup --client cursor --add-root /absolute/minimum/root --yes --json
|
|
77
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
When an agent or script runs under a pty (stdin is still a TTY), declare non-interactive
|
|
@@ -82,7 +82,7 @@ mode explicitly with `--headless` (alias `--non-interactive`): no `--yes` is req
|
|
|
82
82
|
stdin is never read:
|
|
83
83
|
|
|
84
84
|
```sh
|
|
85
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
85
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
## Windows configuration
|
|
@@ -101,14 +101,14 @@ automatically; the second is the most robust when you configure by hand.
|
|
|
101
101
|
1. **`cmd` + `npx` (what `setup` writes on Windows)** — `cmd.exe` is a real executable,
|
|
102
102
|
so a client's no-shell spawn works:
|
|
103
103
|
```json
|
|
104
|
-
{ "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.5.
|
|
104
|
+
{ "command": "cmd", "args": ["/d", "/c", "npx", "-y", "@cueai/omni-reader-mcp@1.5.3"] }
|
|
105
105
|
```
|
|
106
106
|
2. **`node` + the package entry (most robust)** — skips `npx` entirely; the absolute
|
|
107
107
|
path must be a stable install you control:
|
|
108
108
|
```json
|
|
109
109
|
{ "command": "node", "args": ["C:\\path\\to\\node_modules\\@cueai\\omni-reader-mcp\\dist\\index.js"] }
|
|
110
110
|
```
|
|
111
|
-
A deliberate local `npm install @cueai/omni-reader-mcp@1.5.
|
|
111
|
+
A deliberate local `npm install @cueai/omni-reader-mcp@1.5.3` gives you that stable
|
|
112
112
|
path. Do not point the entry at an `_npx` cache directory — its hash subdirectory
|
|
113
113
|
changes between installs.
|
|
114
114
|
3. **Never use a session/timestamp directory** — such paths are cleaned up, and the
|
|
@@ -251,16 +251,16 @@ satisfies the constraints.
|
|
|
251
251
|
## Commands
|
|
252
252
|
|
|
253
253
|
```sh
|
|
254
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
255
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
256
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
257
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
254
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 doctor
|
|
255
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 doctor --json
|
|
256
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 clean
|
|
257
|
+
npx -y @cueai/omni-reader-mcp@1.5.3 uninstall --yes --json
|
|
258
258
|
```
|
|
259
259
|
|
|
260
260
|
Running the pinned version without a command starts the stdio MCP server:
|
|
261
261
|
|
|
262
262
|
```sh
|
|
263
|
-
npx -y @cueai/omni-reader-mcp@1.5.
|
|
263
|
+
npx -y @cueai/omni-reader-mcp@1.5.3
|
|
264
264
|
```
|
|
265
265
|
|
|
266
266
|
`doctor --json` returns package/npm/client adapter, Key present/absent, allowed-root
|
|
@@ -269,29 +269,36 @@ status; it never prints the Key, private source paths, or content.
|
|
|
269
269
|
|
|
270
270
|
## Network diagnostics
|
|
271
271
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
API reachability from your machine. The common symptoms:
|
|
272
|
+
Run `npx -y @cueai/omni-reader-mcp@1.5.3 doctor --json` first. Diagnose failures by
|
|
273
|
+
stage instead of guessing an endpoint:
|
|
275
274
|
|
|
276
|
-
|
|
|
275
|
+
| Code | Stage | Meaning |
|
|
277
276
|
|---|---|---|
|
|
278
|
-
| `
|
|
279
|
-
| `
|
|
280
|
-
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
277
|
+
| `CUBE_UNAVAILABLE` | before upload | the control plane could not create a parse grant |
|
|
278
|
+
| `PRINCIPAL_CONCURRENCY_LIMIT` | before upload | the principal already has the maximum active parses; wait for `retry_after`, then retry the same parse |
|
|
279
|
+
| `IIIS_UNAVAILABLE` | after grant creation | the granted upload stage could not complete |
|
|
280
|
+
| `CUBE_PROTOCOL_ERROR` | control-plane response | the response did not match the required contract |
|
|
281
|
+
| `MCP error -32000: Connection closed` | before Bridge starts | the client launcher shape is invalid; see Windows configuration |
|
|
282
|
+
|
|
283
|
+
Use only the compatibility and endpoint facts reported by `doctor`. Do not guess or
|
|
284
|
+
publish service hosts or ports, hard-code IP addresses, modify hosts files, or probe an
|
|
285
|
+
endpoint copied from logs. If an enterprise network policy blocks a required connection,
|
|
286
|
+
provide the redacted `doctor --json` result to support for the applicable egress
|
|
287
|
+
requirements.
|
|
288
|
+
|
|
289
|
+
If the secure parse environment is reachable but a specific public URL fails to parse
|
|
290
|
+
(`parse_timeout` / parse failed) while it works in a browser, that is a fetch-layer
|
|
291
|
+
condition of the source — not a Bridge configuration problem — and it affects the URL
|
|
292
|
+
the same way from every client.
|
|
286
293
|
|
|
287
294
|
## Uninstall and rollback
|
|
288
295
|
|
|
289
|
-
`uninstall --yes --json` removes only a trusted 1.5.
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
results.
|
|
296
|
+
`uninstall --yes --json` removes only a trusted 1.5.2 or 1.5.3 Bridge entry, plus
|
|
297
|
+
the exact broken bare-`npx` Windows entry written by 1.5.1. When a matching trusted
|
|
298
|
+
backup exists, it restores the original URL-only `omni-reader` entry. Uninstall never
|
|
299
|
+
deletes user source files and never silently removes unexpired local results.
|
|
293
300
|
|
|
294
|
-
To roll back from 1.5.
|
|
301
|
+
To roll back from 1.5.3:
|
|
295
302
|
|
|
296
303
|
1. stop recommending or installing that version;
|
|
297
304
|
2. run `uninstall --yes --json` to restore the trusted URL-only entry;
|
package/dist/cli/agent-config.js
CHANGED
|
@@ -4,11 +4,16 @@ import { chmod, lstat, mkdir, open, realpath, rename, unlink, } from "node:fs/pr
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { BRIDGE_RELEASE_VERSION, REMOTE_OMNI_MCP_URL, } from "../constants.js";
|
|
6
6
|
const PACKAGE_SPEC = `@cueai/omni-reader-mcp@${BRIDGE_RELEASE_VERSION}`;
|
|
7
|
-
// The release that the current version is a trusted upgrade from:
|
|
8
|
-
// rollback recognize exactly {previous, current}
|
|
9
|
-
//
|
|
10
|
-
const PREVIOUS_RELEASE_VERSION = "1.5.
|
|
7
|
+
// The release that the current version is a trusted upgrade from: normal upgrade,
|
|
8
|
+
// uninstall, and rollback recognize exactly {previous, current}. Bump this to the
|
|
9
|
+
// version we just published when BRIDGE_RELEASE_VERSION advances.
|
|
10
|
+
const PREVIOUS_RELEASE_VERSION = "1.5.2";
|
|
11
11
|
const PREVIOUS_PACKAGE_SPEC = `@cueai/omni-reader-mcp@${PREVIOUS_RELEASE_VERSION}`;
|
|
12
|
+
// Preserve the one evidenced two-release migration exception: 1.5.1 setup wrote a
|
|
13
|
+
// bare `npx` launcher on Windows, so later setup/uninstall versions must still be able
|
|
14
|
+
// to identify and replace that otherwise-unrunnable entry. 1.5.2 already writes `cmd`.
|
|
15
|
+
const WINDOWS_BARE_NPX_MIGRATION_VERSION = "1.5.1";
|
|
16
|
+
const WINDOWS_BARE_NPX_MIGRATION_SPEC = `@cueai/omni-reader-mcp@${WINDOWS_BARE_NPX_MIGRATION_VERSION}`;
|
|
12
17
|
const LEGACY_PACKAGE_SPEC = "@cueai/omni-reader-mcp";
|
|
13
18
|
const TRUSTED_EXACT_PACKAGE_SPECS = new Set([PREVIOUS_PACKAGE_SPEC, PACKAGE_SPEC]);
|
|
14
19
|
function isRecord(value) {
|
|
@@ -146,10 +151,9 @@ function entryPackageSpec(entry, platform) {
|
|
|
146
151
|
/**
|
|
147
152
|
* Matches the trusted invocation shape for the platform: `cmd /d /c npx -y <spec>` on
|
|
148
153
|
* Windows (runnable by a no-shell spawn; `/d` skips the AutoRun command whose stdout
|
|
149
|
-
* would corrupt MCP stdio frames), `npx -y <spec>` everywhere else.
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* uninstall must still identify it as a trusted entry so 1.5.2 can replace it.
|
|
154
|
+
* would corrupt MCP stdio frames), `npx -y <spec>` everywhere else. Windows also keeps
|
|
155
|
+
* the exact 1.5.1 bare-`npx` migration source: that release wrote an unrunnable entry,
|
|
156
|
+
* while 1.5.2 and later write `cmd` and therefore need no widening exception.
|
|
153
157
|
*/
|
|
154
158
|
function entryInvocationMatches(entry, platform) {
|
|
155
159
|
const args = entry.args;
|
|
@@ -163,12 +167,12 @@ function entryInvocationMatches(entry, platform) {
|
|
|
163
167
|
&& args[3] === "-y"
|
|
164
168
|
&& typeof args[4] === "string"
|
|
165
169
|
&& TRUSTED_EXACT_PACKAGE_SPECS.has(args[4]);
|
|
166
|
-
const
|
|
170
|
+
const migrationNpxForm = entry.command === "npx"
|
|
167
171
|
&& Array.isArray(args)
|
|
168
172
|
&& args.length === 2
|
|
169
173
|
&& args[0] === "-y"
|
|
170
|
-
&& args[1] ===
|
|
171
|
-
return cmdForm ||
|
|
174
|
+
&& args[1] === WINDOWS_BARE_NPX_MIGRATION_SPEC;
|
|
175
|
+
return cmdForm || migrationNpxForm;
|
|
172
176
|
}
|
|
173
177
|
return entry.command === "npx"
|
|
174
178
|
&& Array.isArray(args)
|
|
@@ -629,25 +633,27 @@ export function expectedBridgeVersion(target, value, platform) {
|
|
|
629
633
|
if (!isExpectedOmniEntry(target, value, platform))
|
|
630
634
|
return undefined;
|
|
631
635
|
const packageSpec = entryPackageSpec(value, platform);
|
|
632
|
-
|
|
636
|
+
if (packageSpec === PREVIOUS_PACKAGE_SPEC)
|
|
637
|
+
return PREVIOUS_RELEASE_VERSION;
|
|
638
|
+
if (packageSpec === WINDOWS_BARE_NPX_MIGRATION_SPEC) {
|
|
639
|
+
return WINDOWS_BARE_NPX_MIGRATION_VERSION;
|
|
640
|
+
}
|
|
641
|
+
return BRIDGE_RELEASE_VERSION;
|
|
633
642
|
}
|
|
634
643
|
function isLegacyBridgeEntry(target, value, platform) {
|
|
635
|
-
//
|
|
636
|
-
//
|
|
637
|
-
const
|
|
644
|
+
// Keep the historical unpinned package form recognizable for setup migration;
|
|
645
|
+
// every exact-version form delegates to the single platform policy above.
|
|
646
|
+
const legacyUnpinnedNpx = (entry) => {
|
|
638
647
|
const args = entry.args;
|
|
639
648
|
return entry.command === "npx"
|
|
640
649
|
&& Array.isArray(args)
|
|
641
650
|
&& args.length === 2
|
|
642
651
|
&& args[0] === "-y"
|
|
643
|
-
&&
|
|
644
|
-
&& (args[1] === LEGACY_PACKAGE_SPEC || TRUSTED_EXACT_PACKAGE_SPECS.has(args[1]));
|
|
652
|
+
&& args[1] === LEGACY_PACKAGE_SPEC;
|
|
645
653
|
};
|
|
646
654
|
if (!isRecord(value))
|
|
647
655
|
return false;
|
|
648
|
-
const shapeOk =
|
|
649
|
-
? (legacyNpx(value) || entryInvocationMatches(value, platform))
|
|
650
|
-
: legacyNpx(value);
|
|
656
|
+
const shapeOk = legacyUnpinnedNpx(value) || entryInvocationMatches(value, platform);
|
|
651
657
|
if (!shapeOk)
|
|
652
658
|
return false;
|
|
653
659
|
if (value.env === undefined)
|
package/dist/constants.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare const CUBE_GRANT_PROTOCOL_VERSION = "omni.parse_grant.v1";
|
|
|
6
6
|
export declare const GRANTED_STREAM_PROTOCOL_VERSION = "omni.granted_parse_stream.v1";
|
|
7
7
|
export declare const DEFAULT_CUBE_BASE_URL = "https://mcp.cuecue.cn";
|
|
8
8
|
export declare const DEFAULT_IIIS_GRANTED_BASE_URL = "https://cubefile.ai.iiis.co:9443/omni/granted/";
|
|
9
|
-
export declare const BRIDGE_RELEASE_VERSION = "1.5.
|
|
9
|
+
export declare const BRIDGE_RELEASE_VERSION = "1.5.3";
|
|
10
10
|
export declare const REMOTE_OMNI_MCP_URL = "https://mcp.cuecue.cn/api/omni-reader/mcp/";
|
|
11
11
|
export declare const FOREGROUND_BUDGET_MS = 15000;
|
|
12
12
|
export declare const STATUS_LONG_POLL_MAX_MS = 20000;
|
package/dist/constants.js
CHANGED
|
@@ -6,7 +6,7 @@ export const CUBE_GRANT_PROTOCOL_VERSION = "omni.parse_grant.v1";
|
|
|
6
6
|
export const GRANTED_STREAM_PROTOCOL_VERSION = "omni.granted_parse_stream.v1";
|
|
7
7
|
export const DEFAULT_CUBE_BASE_URL = "https://mcp.cuecue.cn";
|
|
8
8
|
export const DEFAULT_IIIS_GRANTED_BASE_URL = "https://cubefile.ai.iiis.co:9443/omni/granted/";
|
|
9
|
-
export const BRIDGE_RELEASE_VERSION = "1.5.
|
|
9
|
+
export const BRIDGE_RELEASE_VERSION = "1.5.3";
|
|
10
10
|
export const REMOTE_OMNI_MCP_URL = "https://mcp.cuecue.cn/api/omni-reader/mcp/";
|
|
11
11
|
export const FOREGROUND_BUDGET_MS = 15_000;
|
|
12
12
|
export const STATUS_LONG_POLL_MAX_MS = 20_000;
|
package/dist/cube-client.js
CHANGED
|
@@ -25,6 +25,16 @@ const grantResponseSchema = z
|
|
|
25
25
|
protocol_version: z.enum([CUBE_GRANT_PROTOCOL_VERSION, "omni.parse_grant.v2"]),
|
|
26
26
|
})
|
|
27
27
|
.strict();
|
|
28
|
+
const principalConcurrencyErrorSchema = z
|
|
29
|
+
.object({
|
|
30
|
+
code: z.literal("PRINCIPAL_CONCURRENCY_LIMIT"),
|
|
31
|
+
message: z.literal("The maximum number of concurrent parsing operations is already active."),
|
|
32
|
+
file_uploaded: z.literal(false),
|
|
33
|
+
billed: z.literal(false),
|
|
34
|
+
content_released: z.literal(false),
|
|
35
|
+
retryable: z.literal(true),
|
|
36
|
+
})
|
|
37
|
+
.strict();
|
|
28
38
|
// Closed v3 grant response: the exact tuple of the selected direct profile is
|
|
29
39
|
// required before the upload phase may start. The tuple is re-checked against
|
|
30
40
|
// the profile after schema parsing so a drifting server cannot slip through.
|
|
@@ -47,7 +57,7 @@ const grantResponseV3Schema = z
|
|
|
47
57
|
approved_result_max_bytes: z.literal(67108864),
|
|
48
58
|
})
|
|
49
59
|
.strict();
|
|
50
|
-
function bridgeError(code, message, retryable) {
|
|
60
|
+
function bridgeError(code, message, retryable, options = {}) {
|
|
51
61
|
return new OmniBridgeError({
|
|
52
62
|
code,
|
|
53
63
|
message,
|
|
@@ -57,6 +67,9 @@ function bridgeError(code, message, retryable) {
|
|
|
57
67
|
billed: false,
|
|
58
68
|
contentReleased: false,
|
|
59
69
|
retryable,
|
|
70
|
+
...(options.failureScope === undefined ? {} : { failureScope: options.failureScope }),
|
|
71
|
+
...(options.userAction === undefined ? {} : { userAction: options.userAction }),
|
|
72
|
+
...(options.retryAfter === undefined ? {} : { retryAfter: options.retryAfter }),
|
|
60
73
|
});
|
|
61
74
|
}
|
|
62
75
|
function grantRequestBody(input, profile) {
|
|
@@ -137,6 +150,33 @@ function responseError(status) {
|
|
|
137
150
|
}
|
|
138
151
|
return bridgeError("CUBE_UNAVAILABLE", "Cube could not create the parse grant. Retry this same grant request later.", status >= 500);
|
|
139
152
|
}
|
|
153
|
+
function retryAfterSeconds(response) {
|
|
154
|
+
const value = response.headers.get("retry-after");
|
|
155
|
+
if (value === null || !/^\d+$/u.test(value))
|
|
156
|
+
return undefined;
|
|
157
|
+
const seconds = Number(value);
|
|
158
|
+
return Number.isSafeInteger(seconds) && seconds > 0 ? seconds : undefined;
|
|
159
|
+
}
|
|
160
|
+
async function grantResponseError(response) {
|
|
161
|
+
const retryAfter = retryAfterSeconds(response);
|
|
162
|
+
if (response.status === 429 && retryAfter !== undefined) {
|
|
163
|
+
let body;
|
|
164
|
+
try {
|
|
165
|
+
body = await response.json();
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return responseError(response.status);
|
|
169
|
+
}
|
|
170
|
+
if (principalConcurrencyErrorSchema.safeParse(body).success) {
|
|
171
|
+
return bridgeError("PRINCIPAL_CONCURRENCY_LIMIT", "The maximum number of concurrent parsing operations is already active.", true, {
|
|
172
|
+
failureScope: "service",
|
|
173
|
+
userAction: "Wait for retry_after seconds, then retry the same local-file parse.",
|
|
174
|
+
retryAfter,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return responseError(response.status);
|
|
179
|
+
}
|
|
140
180
|
export class CubeGrantClient {
|
|
141
181
|
#journal;
|
|
142
182
|
#apiKey;
|
|
@@ -256,7 +296,7 @@ export class CubeGrantClient {
|
|
|
256
296
|
throw bridgeError("CUBE_UNAVAILABLE", "Cube could not create the parse grant. Retry this same grant request later.", true);
|
|
257
297
|
}
|
|
258
298
|
if (!response.ok) {
|
|
259
|
-
throw
|
|
299
|
+
throw await grantResponseError(response);
|
|
260
300
|
}
|
|
261
301
|
// The v3 response tuple is required before this promise resolves: the
|
|
262
302
|
// upload phase can only start after the negotiated representation is
|