@cueai/omni-reader-mcp 1.1.2 → 1.2.0

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
@@ -1,87 +1,110 @@
1
1
  # @cueai/omni-reader-mcp
2
2
 
3
- Omni Bridge Agent 中统一的本地 stdio facade。用户只需提供来源,Bridge 通过同一个 `parse(source)` 自动处理 HTTPS URL 或已授权目录中的本地文件,无需选择“本地/远程”“上传/URL”或内部服务。
3
+ Omni Bridge is the unified local stdio facade for agents. The user provides only the
4
+ source; Bridge handles an HTTPS URL or a local file inside an authorized directory
5
+ through the same `parse(source)` call — no "local/remote", "upload/URL", or internal
6
+ service choice.
4
7
 
5
- ## 用户旅程
8
+ ## User journey
6
9
 
7
- 直接告诉 Agent 来源和后续任务:
10
+ Tell the agent the source and the follow-up task:
8
11
 
9
12
  ```text
10
- Omni 解析 ./report.pdf
11
- Omni 解析 https://example.com/report.pdf
12
- Omni 解析 ./report.pdf 并总结营收变化
13
+ Parse ./report.pdf with Omni
14
+ Parse https://example.com/report.pdf with Omni
15
+ Parse ./report.pdf with Omni and summarize the revenue changes
13
16
  ```
14
17
 
15
- URL 不要求安装 Bridge。本地文件首次使用时,Agent 应先说明最小目录授权、数据处理方式并取得确认,再安装固定版本 Bridge。解析完成后,Agent 应继续摘要、问答或字段抽取等原始任务,而不是止于“解析完成”。
18
+ URLs never require installing Bridge. For local files, the agent should first explain the
19
+ minimal directory authorization and data handling and obtain confirmation, then install
20
+ a pinned Bridge version. After parsing completes, the agent continues the original task —
21
+ summarization, Q&A, field extraction — rather than stopping at "parse done".
16
22
 
17
- ## 要求
23
+ ## Requirements
18
24
 
19
- - Node.js 20.12 或更新版本。
20
- - Cue API Key:<https://cuecue.cn/api-key>。
21
- - 新账号有免费积分可体验;当前赠送和每日额度以服务端 onboarding policy `doctor` 输出为准。
22
- - 请在 Agent 的安全密钥或本机环境设置中配置 `CUE_API_KEY`。**请勿把 API Key 粘贴到对话中。**
25
+ - Node.js 20.12 or newer.
26
+ - Cue API Key: <https://cuecue.cn/api-key>.
27
+ - New accounts receive free credits to try; the current grant and daily allowance follow
28
+ the server-side onboarding policy and the `doctor` output.
29
+ - Configure `CUE_API_KEY` in the agent's secret store or local environment.
30
+ **Never paste the API Key into a conversation.**
23
31
 
24
- Bridge 运行时只使用以下产品配置:
32
+ Bridge reads only these product configuration variables at runtime:
25
33
 
26
34
  - `CUE_API_KEY`
27
35
  - `OMNI_ALLOWED_ROOTS`
28
36
 
29
- `OMNI_ALLOWED_ROOTS` 只用于用户明确授权的额外绝对目录;macOS/Linux 使用冒号分隔,Windows 使用分号分隔。当前 Agent workspace 仍是默认允许范围。
37
+ `OMNI_ALLOWED_ROOTS` is only for additional absolute directories the user explicitly
38
+ authorizes; colon-separated on macOS/Linux, semicolon-separated on Windows. The current
39
+ agent workspace remains the default allowed scope.
30
40
 
31
- ## 安装与配置
41
+ ## Installation and configuration
32
42
 
33
- 始终使用已审核的精确版本,不使用隐式 `latest`:
43
+ Always use an audited exact version, never an implicit `latest`:
34
44
 
35
45
  ```sh
36
- npx -y @cueai/omni-reader-mcp@1.1.2 setup
46
+ npx -y @cueai/omni-reader-mcp@1.2.0 setup
37
47
  ```
38
48
 
39
- 交互 setup 支持 HermesCursorClaude Desktop 和通用 stdio 配置。非交互安装使用同一参数解析和写入逻辑:
49
+ The interactive setup supports Hermes, Cursor, Claude Desktop, and generic stdio
50
+ configuration. Non-interactive installation uses the same argument parsing and write
51
+ logic:
40
52
 
41
53
  ```sh
42
- npx -y @cueai/omni-reader-mcp@1.1.2 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
43
- npx -y @cueai/omni-reader-mcp@1.1.2 setup --client cursor --add-root /absolute/minimum/root --yes --json
44
- npx -y @cueai/omni-reader-mcp@1.1.2 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
54
+ npx -y @cueai/omni-reader-mcp@1.2.0 setup --client hermes --allowed-root /absolute/minimum/root --yes --json
55
+ npx -y @cueai/omni-reader-mcp@1.2.0 setup --client cursor --add-root /absolute/minimum/root --yes --json
56
+ npx -y @cueai/omni-reader-mcp@1.2.0 setup --client claude-desktop --allowed-root /absolute/minimum/root --yes --json
45
57
  ```
46
58
 
47
- Agent/脚本在 pty 下运行(stdin 仍是 TTY)时,用 `--headless`(别名 `--non-interactive`)显式声明非交互,无需 `--yes` 且绝不读 stdin:
59
+ When an agent or script runs under a pty (stdin is still a TTY), declare non-interactive
60
+ mode explicitly with `--headless` (alias `--non-interactive`): no `--yes` is required and
61
+ stdin is never read:
48
62
 
49
63
  ```sh
50
- npx -y @cueai/omni-reader-mcp@1.1.2 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
64
+ npx -y @cueai/omni-reader-mcp@1.2.0 setup --client cursor --allowed-root /absolute/minimum/root --headless --json
51
65
  ```
52
66
 
53
- ## 缓存与 journal 隔离
67
+ ## Cache and journal isolation
54
68
 
55
- 本地解析缓存与操作 journal 默认位于用户级缓存目录(macOS `~/Library/Caches/cue/omni-reader-mcp`、Windows `%LOCALAPPDATA%\Cue\omni-reader-mcp\Cache`、Linux `~/.cache/cue/omni-reader-mcp`)。若 Agent 的文件监视器(如 WorkBuddy)锁定该目录下的文件导致写入失败,设置 `OMNI_CACHE_DIR` 将缓存与 journal 一起隔离到不被监视的目录:
69
+ The local parse cache and operation journal default to the user-level cache directory
70
+ (macOS `~/Library/Caches/cue/omni-reader-mcp`, Windows
71
+ `%LOCALAPPDATA%\Cue\omni-reader-mcp\Cache`, Linux `~/.cache/cue/omni-reader-mcp`). If the
72
+ agent's file watcher (e.g. WorkBuddy) locks files under that directory and writes fail,
73
+ set `OMNI_CACHE_DIR` to isolate cache and journal together into a directory that is not
74
+ watched:
56
75
 
57
76
  ```sh
58
77
  export OMNI_CACHE_DIR=/var/cache/omni-reader
59
78
  ```
60
79
 
61
- 显式 `OMNI_CACHE_DIR` 不会被项目重叠检查改写到临时目录;仍禁止与项目目录互相包含。
80
+ An explicit `OMNI_CACHE_DIR` is never rewritten to a temporary directory by the
81
+ project-overlap check; mutual containment with a project directory remains forbidden.
62
82
 
63
- setup 会:
83
+ `setup` will:
64
84
 
65
- 1. 展示 user-scope 配置目标和变更;
66
- 2. 写入单一、精确版本的 `omni-reader` facade
67
- 3. 使用私有 lock、可信备份和原子替换;
68
- 4. 验证 Omni 安全解析环境;
69
- 5. 验证失败时恢复原配置;
70
- 6. 提示对应 Agent reload restart
85
+ 1. show the user-scope configuration target and changes;
86
+ 2. write a single, exact-version `omni-reader` facade;
87
+ 3. use a private lock, trusted backup, and atomic replacement;
88
+ 4. verify the Omni secure parse environment;
89
+ 5. restore the previous configuration when verification fails;
90
+ 6. prompt the corresponding agent to reload or restart.
71
91
 
72
- 配置不会写入 API Key 明文。Hermes 使用原生的独立 `command`、`args` 和安全环境变量引用。
92
+ Configuration never writes the API Key in plaintext. Hermes uses native separate
93
+ `command`, `args`, and safe environment variable references.
73
94
 
74
- ## Agent 调用规则
95
+ ## Agent calling rules
75
96
 
76
- Agent 将用户提供的来源字符串直接传给 `parse(source)`:
97
+ Agents pass the user-provided source string directly to `parse(source)`:
77
98
 
78
- - 只有 HTTP(S) 被视为 URL;普通字符串按本地路径处理。
79
- - Do not read, attach, base64-encode, or insert the file content into the conversation before calling Omni.
80
- - 不使用 `file://`、localhost 或公共临时上传站点作为回退。
81
- - 安装 Bridge 或扩大 allowed root 前必须确认。
82
- - 状态恢复优先使用已有 `operation_id`;不得为超时重复上传或重复创建解析。
99
+ - Only HTTP(S) is treated as a URL; a plain string is treated as a local path.
100
+ - Do not read, attach, base64-encode, or insert the file content into the conversation
101
+ before calling Omni.
102
+ - Do not use `file://`, localhost, or public temporary upload sites as a fallback.
103
+ - Confirm before installing Bridge or widening the allowed roots.
104
+ - Prefer the existing `operation_id` for status recovery; never re-upload or duplicate a
105
+ parse for a timeout.
83
106
 
84
- 公开工具固定为:
107
+ The public tools are fixed:
85
108
 
86
109
  - `parse`
87
110
  - `get_parse_status`
@@ -89,66 +112,102 @@ Agent 将用户提供的来源字符串直接传给 `parse(source)`:
89
112
  - `read_result`
90
113
  - `discard_result`
91
114
 
92
- 每个工具都返回 `structuredContent` 和严格 `outputSchema`。
115
+ Every tool returns `structuredContent` with a strict `outputSchema`, plus an equivalent
116
+ fallback for clients that only read legacy MCP `content[].text`:
93
117
 
94
- ## 前台、后台和进度
118
+ - when `parse` completes and the result is inlineable, text returns the full Markdown
119
+ directly;
120
+ - for processing, artifact, cleanup, cancel, expired, and failure states, text returns
121
+ compact JSON equivalent to the `structuredContent` fields;
122
+ - the `read_result` text JSON contains the current `result.text` and an optional
123
+ `next_cursor`; clients must exhaust all cursors before concatenating the body;
124
+ - the `discard_result` text JSON explicitly returns `discarded`; never claim deletion on
125
+ call success alone.
95
126
 
96
- 每次解析的前台预算固定为 **15 秒**:
127
+ This gives clients that do not render `structuredContent` the operation/result handles
128
+ and the full body without changing the contract for structured-capable clients.
97
129
 
98
- - 15 秒内完成:直接返回完整结果。
99
- - 超过 15 秒:返回可恢复的 processing operation。
100
- - 客户端明确请求且支持 MCP Tasks 时,Bridge 使用 task。
101
- - 其他客户端使用 `get_parse_status` 的有界轮询;不承诺客户端不支持的主动通知。
130
+ ## Foreground, background, and progress
102
131
 
103
- processing/task 状态只包含 operation、stage、百分比和可选权威单位进度。可用单位仅为 `page`、`sheet`、`slide`、`frame`、`segment`。状态中不包含结果正文、预览、Markdown、页面图片、裁剪图片或累计部分输出。
132
+ The foreground budget of every parse is fixed at **15 seconds**:
104
133
 
105
- ## 数据处理与保留
134
+ - completes within 15 seconds: the full result is returned directly;
135
+ - exceeds 15 seconds: a recoverable processing operation is returned;
136
+ - when the client explicitly requests it and supports MCP Tasks, Bridge uses a task;
137
+ - other clients use bounded polling of `get_parse_status`; proactive notifications that
138
+ the client does not support are not promised.
106
139
 
107
- URL 和本地文件都使用强制 no-store 语义并进入 **Omni 安全解析环境**:
140
+ processing/task status contains only the operation, stage, percentage, and an optional
141
+ authoritative unit progress. Available units are only `page`, `sheet`, `slide`, `frame`,
142
+ `segment`. Status never contains the result body, previews, Markdown, page images, crop
143
+ images, or accumulated partial output.
108
144
 
109
- - 用户电脑上的原始本地文件保持 unchanged;URL 来源也不会被修改或删除。
110
- - Omni 创建的处理副本和临时数据在完成后主动清理。
111
- - 加密交付数据在 ACK 后删除;未确认 ACK 时最迟在 **10 分钟**交付窗口到期。
112
- - 只有远端 ACK 和清理已确认后才返回 `completed`。
113
- - 本地结果已保留但远端清理仍不确定时返回 `cleanup_pending`,不会提前声称已删除。
114
- - 超过 64 KiB 的结果可以保存在用户私有 Bridge cache,最长 **24 小时**;这与远端 10 分钟交付窗口是两类不同数据。
115
- - `read_result` 分块读取本地结果;`discard_result` 可立即删除指定结果;`clean` 清理 Bridge 创建的本地 artifact 和到期记录。
145
+ ## Data handling and retention
116
146
 
117
- 状态查询、结果读取和丢弃不会创建新的解析或 usage event。`cancel_parse` 只报告服务端确认的真实结算状态,不会自行造成第二次计费。
147
+ Both URL and local files use mandatory no-store semantics and enter the
148
+ **Omni secure parse environment**:
118
149
 
119
- ## 约束错误
150
+ - the original local file on the user's machine stays unchanged; URL sources are never
151
+ modified or deleted;
152
+ - processing copies and temporary data created by Omni are actively cleaned after
153
+ completion;
154
+ - encrypted delivery data is deleted after ACK; without a confirmed ACK, at the latest
155
+ when the **10-minute** delivery window expires;
156
+ - `completed` is returned only after the remote ACK and cleanup are confirmed;
157
+ - `cleanup_pending` is returned when the local result is retained but remote cleanup is
158
+ still uncertain — never claim deletion prematurely;
159
+ - results over 64 KiB may be kept in the user's private Bridge cache for up to
160
+ **24 hours**; this is a different class of data from the remote 10-minute delivery
161
+ window;
162
+ - `read_result` reads local results in chunks; `discard_result` deletes a specific result
163
+ immediately; `clean` removes Bridge-created local artifacts and expired records.
120
164
 
121
- Bridge grant、上传和计费前验证本地来源:
165
+ Status queries, result reads, and discards never create a new parse or usage event.
166
+ `cancel_parse` reports only the real settlement state confirmed by the server and never
167
+ causes a second billing by itself.
122
168
 
123
- - `SOURCE_TOO_LARGE`:超过当前 256 MiB 上限,并返回机器可读 `constraints.max_bytes`。
124
- - `UNSUPPORTED_MEDIA_TYPE`:媒体类型不受支持,并返回当前权威 `supported_extensions`。
169
+ ## Constraint errors
125
170
 
126
- Agent 不应自动拆分、转码或上传公共站点;应请用户提供符合约束的新来源。
171
+ Bridge validates the local source before grant, upload, and billing:
127
172
 
128
- ## 命令
173
+ - `SOURCE_TOO_LARGE`: exceeds the current 256 MiB cap, with machine-readable
174
+ `constraints.max_bytes`.
175
+ - `UNSUPPORTED_MEDIA_TYPE`: unsupported media type, with the current authoritative
176
+ `supported_extensions`.
177
+
178
+ Agents should not auto-split, transcode, or upload to public sites; ask the user for a
179
+ new source that satisfies the constraints.
180
+
181
+ ## Commands
129
182
 
130
183
  ```sh
131
- npx -y @cueai/omni-reader-mcp@1.1.2 doctor
132
- npx -y @cueai/omni-reader-mcp@1.1.2 doctor --json
133
- npx -y @cueai/omni-reader-mcp@1.1.2 clean
134
- npx -y @cueai/omni-reader-mcp@1.1.2 uninstall --yes --json
184
+ npx -y @cueai/omni-reader-mcp@1.2.0 doctor
185
+ npx -y @cueai/omni-reader-mcp@1.2.0 doctor --json
186
+ npx -y @cueai/omni-reader-mcp@1.2.0 clean
187
+ npx -y @cueai/omni-reader-mcp@1.2.0 uninstall --yes --json
135
188
  ```
136
189
 
137
- 不带命令运行固定版本会启动 stdio MCP server
190
+ Running the pinned version without a command starts the stdio MCP server:
138
191
 
139
192
  ```sh
140
- npx -y @cueai/omni-reader-mcp@1.1.2
193
+ npx -y @cueai/omni-reader-mcp@1.2.0
141
194
  ```
142
195
 
143
- `doctor --json` 返回 package/npm/client adapterKey present/absentallowed-root 安全状态、endpoint compatibility、artifact、cache mode、onboarding 和 reload 状态;不会输出 Key、私有来源路径或内容。
196
+ `doctor --json` returns package/npm/client adapter, Key present/absent, allowed-root
197
+ safety status, endpoint compatibility, artifacts, cache mode, onboarding, and reload
198
+ status; it never prints the Key, private source paths, or content.
144
199
 
145
- ## 卸载与回滚
200
+ ## Uninstall and rollback
146
201
 
147
- `uninstall --yes --json` 只删除当前受信的 1.1.2 Bridge entry;存在匹配的可信备份时恢复原 URL-only `omni-reader` entry。卸载不会删除用户源文件,也不会静默删除未过期的本地结果。
202
+ `uninstall --yes --json` removes only the currently trusted 1.2.0 Bridge entry; when a
203
+ matching trusted backup exists, it restores the original URL-only `omni-reader` entry.
204
+ Uninstall never deletes user source files and never silently removes unexpired local
205
+ results.
148
206
 
149
- 需要回滚 1.1.1 时:
207
+ To roll back from 1.1.1:
150
208
 
151
- 1. 停止推荐或安装该版本;
152
- 2. 运行 `uninstall --yes --json` 恢复可信 URL-only entry
153
- 3. 对已经上传的 operation 继续使用状态恢复,让结算和清理完成;
154
- 4. 保留本地结果,或由用户显式运行 `discard_result` / `clean`。
209
+ 1. stop recommending or installing that version;
210
+ 2. run `uninstall --yes --json` to restore the trusted URL-only entry;
211
+ 3. for already-uploaded operations, continue using status recovery so settlement and
212
+ cleanup complete;
213
+ 4. keep local results, or have the user explicitly run `discard_result` / `clean`.
@@ -1,5 +1,7 @@
1
1
  import type { FileHandle } from "node:fs/promises";
2
2
  import type { ReleasedMetadata, ResultRetentionSink, ResultRetentionStart } from "./iiis-client.js";
3
+ import { GROUNDING_SCHEMA_VERSION, RESULT_BUNDLE_PROTOCOL_VERSION } from "./protocol.js";
4
+ import { type VerifiedBundle } from "./result-bundle.js";
3
5
  export interface ArtifactStoreOptions {
4
6
  readonly rootDirectory?: string;
5
7
  readonly projectDirectory?: string;
@@ -41,6 +43,59 @@ export interface ArtifactReadResult {
41
43
  readonly text: string;
42
44
  readonly nextCursor?: string;
43
45
  }
46
+ export type BundlePartName = "content" | "grounding";
47
+ export type BundleContentStorage = {
48
+ readonly kind: "inline";
49
+ readonly text: string;
50
+ } | {
51
+ readonly kind: "artifact";
52
+ readonly nextCursor: string;
53
+ };
54
+ export type BundleGroundingStorage = {
55
+ readonly kind: "inline";
56
+ readonly value: unknown;
57
+ } | {
58
+ readonly kind: "artifact";
59
+ readonly nextCursor: string;
60
+ };
61
+ export interface BundleLocalResult {
62
+ readonly kind: "bundle";
63
+ readonly operationId: string;
64
+ readonly resultId: string;
65
+ readonly detail: "grounded" | "layout";
66
+ readonly bundleBytes: number;
67
+ readonly bundleDigest: string;
68
+ readonly expiresAt: string;
69
+ readonly bundleProtocolVersion: typeof RESULT_BUNDLE_PROTOCOL_VERSION;
70
+ readonly groundingSchemaVersion: typeof GROUNDING_SCHEMA_VERSION;
71
+ readonly parts: {
72
+ readonly content: {
73
+ readonly part: "content";
74
+ readonly mediaType: "text/markdown; charset=utf-8";
75
+ readonly resultBytes: number;
76
+ readonly digest: string;
77
+ readonly storage: BundleContentStorage;
78
+ };
79
+ readonly grounding: {
80
+ readonly part: "grounding";
81
+ readonly mediaType: "application/vnd.cue.omni-grounding+json; version=1";
82
+ readonly resultBytes: number;
83
+ readonly digest: string;
84
+ readonly storage: BundleGroundingStorage;
85
+ };
86
+ };
87
+ }
88
+ export interface BundlePartReadChunk {
89
+ readonly resultId: string;
90
+ readonly part: BundlePartName;
91
+ readonly mediaType: "text/markdown; charset=utf-8" | "application/vnd.cue.omni-grounding+json; version=1";
92
+ readonly resultBytes: number;
93
+ readonly offset: number;
94
+ readonly decodedBytes: number;
95
+ readonly text: string;
96
+ readonly nextCursor?: string;
97
+ readonly expiresAt: string;
98
+ }
44
99
  interface ArtifactFinalizeInput extends ReleasedMetadata {
45
100
  readonly resultId: string;
46
101
  }
@@ -54,10 +109,12 @@ export declare class ArtifactStore {
54
109
  get rootDirectory(): string;
55
110
  createRetention(): LocalResultRetention;
56
111
  read(resultId: string, cursor?: string, maxBytes?: number): Promise<ArtifactReadResult>;
112
+ readBundlePart(resultId: string, cursor: string, maxBytes?: number): Promise<BundlePartReadChunk>;
57
113
  discard(resultId: string): Promise<boolean>;
58
114
  cleanupExpired(): Promise<number>;
59
115
  close(): Promise<void>;
60
116
  _finalizeArtifact(temporaryPath: string, metadata: ArtifactFinalizeInput): Promise<ArtifactResult>;
117
+ _finalizeBundle(resultId: string, verified: VerifiedBundle, metadata: ReleasedMetadata): Promise<BundleLocalResult>;
61
118
  _newTemporaryArtifact(): Promise<{
62
119
  resultId: string;
63
120
  temporaryPath: string;
@@ -72,6 +129,7 @@ export declare class LocalResultRetention implements ResultRetentionSink {
72
129
  write(chunk: Uint8Array): Promise<void>;
73
130
  complete(metadata: ReleasedMetadata): Promise<void>;
74
131
  result(): LocalResult;
132
+ bundleResult(): BundleLocalResult;
75
133
  abort(): Promise<void>;
76
134
  }
77
135
  export {};