让 AI 写文档。
在 OmniDoc 里
接着编辑。
把 Codex、Claude 或你的本机 AI 助手连接到 OmniDoc,直接生成 .udoc 文件。助手还能看到排版结果、逐块修改,标题、公式、图表与可交互图都能在文档里继续编辑。
Windows 1.05 · 原生文档接口项目周报
本周进展
原生文档接口接入完成。
接下来,整理测试与发布计划。
| 任务 | 状态 |
|---|---|
| 接口接入 | 已完成 |
| 文档验收 | 进行中 |
下周计划
完善示例,收集使用反馈。
返回页数、排版问题与页面图片。
用原生文档块组织内容与格式。
指定输出位置,已有文件保留。
准备好这三件事
接口直接使用安装目录中的文档引擎,桌面软件不必保持打开。
它在安装目录中,与 OmniDoc 主程序一起提供。
支持 STDIO MCP,或能执行本机命令的 AI 客户端。
假设安装位置是 D:\OmniDoc,接口程序就是 D:\OmniDoc\OmniDocAI.exe。如果你选择了其他安装目录,下方填写真实路径即可。
普通云端聊天无法仅凭 Windows 路径访问你的电脑。本篇操作针对 Windows 本机环境;Linux 接入说明将在对应版本验收后补充。
先确认安装包包含接口程序
在 PowerShell 执行以下命令。第一条返回 True,随后输出带有 guide、schema、version 的 JSON,即表示程序可启动。
$ai = 'D:/OmniDoc/OmniDocAI.exe'
Test-Path -LiteralPath $ai
& $ai schema把 OmniDoc 接入你的助手
填写安装路径,再选择客户端。下面的配置会随路径自动更新。MCP 客户端负责启动接口程序,你只需让 OmniDoc 保持打开。
将配置合并到 %USERPROFILE%\.codex\config.toml,保留现有配置,然后重启 Codex 或开始新的会话。若设置了 CODEX_HOME,使用该目录中的配置文件。
[mcp_servers.omnidoc_native]
command = "D:/OmniDoc/OmniDocAI.exe"
args = ["--mcp"]
tool_timeout_sec = 180也可以用 Codex CLI 添加
如果已安装 codex 命令,在 PowerShell 执行;不要同时重复添加相同服务。
codex mcp add omnidoc_native -- 'D:/OmniDoc/OmniDocAI.exe' '--mcp'运行 codex mcp list 检查条目。若大文档调用超时,在对应配置项中设置 tool_timeout_sec = 180。
在 PowerShell 执行下面的命令。--scope user 让当前用户的各个项目都能使用这项服务。
claude mcp add --transport stdio --scope user omnidoc-native -- 'D:/OmniDoc/OmniDocAI.exe' '--mcp'重新开始 Claude Code 会话,输入 /mcp,确认 omnidoc-native 已连接。已有同名条目时,先运行 claude mcp get omnidoc-native 检查路径。
在 Claude Desktop 的 Settings → Developer → Edit Config 打开本地配置,将下方条目合并到已有的 mcpServers 中。Windows 默认文件位置为 %APPDATA%\Claude\claude_desktop_config.json。
{
"mcpServers": {
"omnidoc-native": {
"command": "D:/OmniDoc/OmniDocAI.exe",
"args": [
"--mcp"
]
}
}
}保存后完全退出并重新打开 Claude Desktop,在本地 MCP 服务列表中确认 omnidoc-native 可用。
omnidoc_get_udoc_schema。它应返回原生 JSON schema 和 version: "1.01"。配置中无需填写 API token。生成第一份文档
方式 A · 直接把任务交给 AI
接入成功后,将这段提示词发给助手,再指定输出文件,例如 D:/Reports/weekly-001.udoc。
请使用 OmniDoc 的原生文档工具,写一份《项目周报》。
包含:标题、本周进展、两列任务表(任务 / 状态)、下周计划。
1. 先调用 omnidoc_get_udoc_schema,阅读 guide 中的语义块写法。
2. 用 heading、paragraph、table 等语义块编写 document;表格加 caption 和 label。
3. 调用 omnidoc_create_udoc 保存到我指定的路径;它会返回页数和排版问题。
4. 调用 omnidoc_render_udoc 查看第 1 页的图片,确认版面没有问题。
5. 需要修改时用 omnidoc_edit_udoc 在原文件上修改,不要另起新文件。
开始前,请让我指定输出文件路径。助手会返回文件路径、版本号 revision 和排版检查结果。用 OmniDoc 打开该 .udoc,即可继续编辑、保存或导出;也可以让助手调用 omnidoc_open_in_editor 直接打开。
方式 B · 不依赖 AI,先跑通一个示例
在 PowerShell 执行下面的完整示例。它读取安装包自带的 JSON,创建“文档\OmniDoc-AI”目录,以新文件名保存结果,再把每一页渲染成图片。
$ai = 'D:/OmniDoc/OmniDocAI.exe'
$sample = Join-Path (Split-Path $ai) 'ai-interface/native-document.example.json'
$folder = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'OmniDoc-AI'
New-Item -ItemType Directory -Force -Path $folder | Out-Null
$output = Join-Path $folder ('AI示例-' + [guid]::NewGuid().ToString('N') + '.udoc')
& $ai create $sample $output
if ($LASTEXITCODE -ne 0) { throw '生成失败,请按下方排错说明检查。' }
& $ai render $output (Join-Path $folder '页面预览')
Write-Host "打开这个文件:$output"path、bytes、revision 和 layout(页数、每页填充率与排版问题);“页面预览”目录中是与编辑器显示一致的页面图片。首次排版检查需要几秒启动编辑器。查看结构,并在原文件上修改
在上方示例成功后的同一个 PowerShell 窗口执行。outline 列出块编号与类型;edit 按编号插入、替换、删除或移动块,并自动重新编号图、表、公式与引用。
# 在上方生成示例的同一个 PowerShell 窗口继续执行
& $ai outline $output
$ops = Join-Path $folder 'ops.json'
'[{"op":"insert","after":"end","blocks":[{"type":"paragraph","text":"由命令行追加的段落,含公式 $E=mc^2$。"}]}]' |
Set-Content -LiteralPath $ops -Encoding UTF8
& $ai edit $output $ops
if ($LASTEXITCODE -ne 0) { throw '修改失败。' }
# 导出完整 JSON(可选)
& $ai read $output ([IO.Path]::ChangeExtension($output, '.json'))修改前的版本保存在用户目录的 mcp-history 中,可以找回。create 默认不覆盖已有文件。
原生文档怎么写
AI 提交一个 JSON 对象。推荐用语义块描述内容:标题、段落、公式、图、表、列表、代码与可交互图。OmniDoc 会把它们转成原生块,自动给图、表、公式编号并解析引用,再校验、编码成 .udoc。
{
"authoring": {"style": "paper"},
"blocks": [
{"type": "heading", "level": 1, "text": "一维热传导"},
{"type": "paragraph", "text": "由式(\\ref{eq:heat})与表 \\ref{tab:p} 可知,行内公式 $r=\\alpha\\Delta t/\\Delta x^2$。"},
{"type": "equation", "tex": "u_t=\\alpha u_{xx}", "label": "eq:heat"},
{"type": "table", "label": "tab:p", "caption": "参数", "rows": [["符号", "取值"], ["$\\alpha$", "1.0"]]},
{"type": "figure", "label": "fig:wave", "caption": "可交互的温度曲线",
"embed": {"code": "<!doctype html>…完整网页…", "height": 300}}
]
}| 语义块 | 写法 |
|---|---|
heading | level 1–6 与 text;标题与下一块保持在同一页。 |
paragraph | text 支持 $行内公式$、**加粗**、\ref{标签},\$ 表示美元符号;也可用 html。 |
equation | tex 与可选 label;有标签时自动编号。不要手写 \tag{}。 |
figure | caption、label,以及 embed(完整网页与高度)、image(data URL、网址或本机图片路径)或 html 之一。图与图题不会被分到两页。 |
table | rows 二维数组、caption、label;首行默认为表头,表题在表格上方。 |
| 其他 | list、code、quote、pagebreak,或直接写原生块 {"html": "…"}。 |
authoring | 可选:style 为 "paper" 时使用论文版式(衬线字体、两端对齐、三线表);language 为 "en" 时图表前缀改为 Figure / Table。 |
可交互图运行在沙箱中:无法读取文档、Cookie 或宿主页面,宽度等于页面内容宽度(A4 常规页边距约 642 CSS 像素),高度固定为 height。插入前可用 omnidoc_test_embed 单独运行,查看截图、脚本错误与实际内容高度。
原生块也可以直接提交。以下是安装包中的原生示例:
{
"format": "udoc", "version": 3, "unidoc_type": "docs",
"title": "AI 原生文档示例",
"page": {"size":"A4","orientation":"portrait","marginPreset":"normal"},
"blocks": [
{"para_id":1,"type":"paragraph","html":"<h1>AI 生成的原生文档</h1>","pages":[1]},
{"para_id":2,"type":"paragraph","html":"<p>这段文字可在 UniDoc 中直接编辑,包含 <strong>加粗</strong> 和 <em>斜体</em>。</p>","pages":[1]},
{"para_id":3,"type":"paragraph","html":"<table><tbody><tr><th>项目</th><th>数值</th></tr><tr><td>原生表格</td><td>42</td></tr></tbody></table>","pages":[1]},
{"para_id":4,"type":"paragraph","html":"<p>公式:<latex>\\frac{1}{2}</latex></p>","pages":[1]}
]
}| 字段 / 内容 | 写法 |
|---|---|
format / version / unidoc_type | 固定为 "udoc" / 3 / "docs"。 |
blocks | 文档块数组。每块至少包含 para_id 和 html。 |
para_id | 正整数,整份文档内唯一。修改已有文档时保留未变更块的标识。 |
html | 块内的内容与格式。标题可写 <h1>,正文可写 <p>。 |
| 表格与公式 | 本示例均使用 type: "paragraph" 的块,内容分别含 <table> 与 <latex>。 |
| 页面与分页 | page 是页面设置;示例的 pages: [1] 将块放在第 1 页。篇幅较大时需安排块所在页面,并在编辑器中检查排版。 |
原生块、图片附件与修改已有文档
图片和附件按 schema 的 resources 规则打包:资源键是内容寻址的包内路径,值是自包含 data URL。需要引用资源时,先读取 schema 与已有文档的真实结构,保留资源引用。
修改已有 .udoc 时,用 omnidoc_read_udoc 查看结构(默认只返回大纲,嵌入代码与图片数据会缩略),再用 omnidoc_edit_udoc 按块编号修改。未修改的块、页面设置与资源保持不变。原生块中图题与公式带有 data-udoc-kind、data-udoc-label、data-udoc-number 属性,引用写作 <span data-udoc-ref="标签">;手工编辑 HTML 时保留这些属性,编号才能继续自动更新。
写、看、改:十个工具
以下是助手在 MCP 中看到的实际工具名称和参数。路径可以是绝对路径,也可以相对于助手的工作目录。
| 工具 | 参数 | 结果 |
|---|---|---|
omnidoc_get_udoc_schema | {} | 撰写指南 guide(语义块、沙箱规则、修改操作、排版问题代码)与原生 schema。先调用它。 |
omnidoc_create_udoc | document、outputPathifExists:fail / version / replacecheck、images | 编号、校验并保存,返回 revision、标签编号、警告,以及排版检查(页数、填充率、问题);images: true 时附带前几页图片。 |
omnidoc_read_udoc | path、view:outline / blocks / fullids、from、to、includeEmbeds | 默认返回大纲(块编号、类型、标签、摘要);blocks 返回指定块的 HTML;full 返回完整 JSON。 |
omnidoc_edit_udoc | path、operations、baseRevision | 插入、替换、删除、移动、替换文字、设置页面;全部成功才保存,旧版本进入历史。返回新的 revision 与排版检查。 |
omnidoc_check_udoc | path 或 document、detail | 在真实编辑器中排版,返回问题清单:页尾大片留白、图与图题分页、标题落在页尾、超出页面、公式错误、沙箱脚本错误等,并给出块编号与建议。 |
omnidoc_render_udoc | path 或 document、pages、scale、format、outputDir | 返回与编辑器显示一致的页面图片(含可交互图的当前画面),默认前 4 页。 |
omnidoc_test_embed | code、height、waitMs | 在同样宽度的沙箱中运行一段网页,返回截图、脚本错误和内容实际尺寸。 |
omnidoc_export_udoc | path 或 document、outputPath | 导出编辑器的无损 HTML(分页与流式两种视图,内嵌原生文档,可再导入)。 |
omnidoc_validate_document | document | 只做编号与原生校验,不保存、不排版;会提示未知引用。 |
omnidoc_open_in_editor | path | 在 OmniDoc 桌面软件中打开文件给用户查看。 |
MCP 将结果同时放在 structuredContent 和文本内容中;页面图片以 MCP 图片内容返回。失败时返回 isError: true 与具体原因。
开发者:一次完整的 MCP tools/call 请求
STDIO 使用逐行 UTF-8 JSON-RPC。客户端完成 initialize 与 notifications/initialized 握手后,发送以下请求。输出目录需已存在。
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "omnidoc_create_udoc",
"arguments": {
"document": {
"title": "项目周报",
"blocks": [
{"type": "heading", "level": 1, "text": "项目周报"},
{"type": "paragraph", "text": "本周完成原生文档接入,见表 \\ref{tab:tasks}。"},
{"type": "table", "label": "tab:tasks", "caption": "任务状态",
"rows": [["任务", "状态"], ["接口接入", "已完成"]]}
]
},
"outputPath": "D:/Reports/weekly-001.udoc"
}
}
}成功时 result.structuredContent 的结构如下,数值以实际结果为准。
不要把 OmniDocAI.exe --mcp 当作普通命令运行后等待它显示界面;它会等待客户端通过标准输入发送协议消息。
脚本与应用也能调用
命令行接口
适合能够执行本机程序的助手和自动化脚本。所有命令直接使用安装目录中的引擎,不需要打开 OmniDoc。
$ai = 'D:/OmniDoc/OmniDocAI.exe'
& $ai schema
& $ai create 'input.json' 'new-document.udoc' # 可追加 version 或 replace
& $ai validate 'input.json'
& $ai outline 'document.udoc'
& $ai edit 'document.udoc' 'operations.json'
& $ai check 'document.udoc'
& $ai render 'document.udoc' 'page-images'
& $ai export-html 'document.udoc' 'document.html'
& $ai test-embed 'figure.html' 'embed-preview'
& $ai read 'document.udoc' 'document.json'
# MCP 客户端使用的启动命令:
& $ai --mcpCLI 与 MCP 都接受相对路径,并按当前工作目录解析。输出目录必须存在;输出文件已存在时默认拒绝。JSON 输入上限 64 MiB,UDOC 输入上限 128 MiB;内嵌资源另受原生 schema 的限制。
本机 HTTP 接口
需要直接集成、且 OmniDoc 正在运行时,从默认用户目录 %LOCALAPPDATA%\OmniDoc\Online\local-api.json 读取 baseUrl 和临时 token。端口随启动变化,使用 Authorization: Bearer <token> 认证,没有调用次数限制。
| 请求 | 请求体 | 成功响应 |
|---|---|---|
POST /v1/documents/pack | UTF-8 JSONapplication/json | UDOC 文件(二进制) |
POST /v1/documents/validate | UTF-8 JSONapplication/json | JSON 校验摘要 |
POST /v1/documents/unpack | UDOC 文件(二进制) | 自包含的 document JSON |
HTTP 接口只做原生打包、校验与解包;语义块、修改操作和排版检查由 OmniDocAI 提供。
展开可运行的 PowerShell HTTP 生成示例
此示例使用默认 profile。自定义用户目录时,修改 $profile。响应按二进制写入新文件,并检查原生容器标识。
# OmniDoc 需要正在运行。先把 ai 路径改为实际安装位置。
$ai = 'D:/OmniDoc/OmniDocAI.exe'
$profile = Join-Path $env:LOCALAPPDATA 'OmniDoc/Online'
$connection = Get-Content -LiteralPath (Join-Path $profile 'local-api.json') -Raw | ConvertFrom-Json
$address = [uri]$connection.baseUrl
if ($address.Scheme -ne 'http' -or $address.Host -ne '127.0.0.1' -or
$address.IsDefaultPort -or $address.AbsolutePath -ne '/' -or
$address.UserInfo -or $address.Query -or $address.Fragment -or
$connection.token -notmatch '^[a-fA-F0-9]{64}$') {
throw '本机 API 配置无效,请重新打开 OmniDoc。'
}
$sample = Join-Path (Split-Path $ai) 'ai-interface/native-document.example.json'
$body = [Text.Encoding]::UTF8.GetBytes((Get-Content -LiteralPath $sample -Raw -Encoding UTF8))
$output = Join-Path ([Environment]::GetFolderPath('MyDocuments')) ('HTTP示例-' + [guid]::NewGuid().ToString('N') + '.udoc')
Add-Type -AssemblyName System.Net.Http
$handler = [Net.Http.HttpClientHandler]::new()
$handler.UseProxy = $false
$handler.AllowAutoRedirect = $false
$client = [Net.Http.HttpClient]::new($handler)
$client.Timeout = [TimeSpan]::FromSeconds(180)
$client.DefaultRequestHeaders.Authorization = [Net.Http.Headers.AuthenticationHeaderValue]::new('Bearer', $connection.token)
$content = [Net.Http.ByteArrayContent]::new($body)
$content.Headers.ContentType = [Net.Http.Headers.MediaTypeHeaderValue]::new('application/json')
try {
$response = $client.PostAsync($address.GetLeftPart([UriPartial]::Authority) + '/v1/documents/pack', $content).GetAwaiter().GetResult()
if (-not $response.IsSuccessStatusCode) {
throw ('HTTP ' + [int]$response.StatusCode + ': ' + $response.Content.ReadAsStringAsync().GetAwaiter().GetResult())
}
$bytes = $response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult()
$stream = [IO.File]::Open($output, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write)
try { $stream.Write($bytes, 0, $bytes.Length) } finally { $stream.Dispose() }
Get-FileHash -LiteralPath $output -Algorithm SHA256
} finally {
if ($response) { $response.Dispose() }
$content.Dispose()
$client.Dispose()
}API 只监听 127.0.0.1,面向本机程序。请求不要带浏览器 Origin 头;不要把临时 token 写入共享配置。OmniDocAI 会自动完成发现与认证,通常优先使用 MCP 或 CLI。
遇到问题,按提示排查
| 现象 / 错误 | 处理方法 |
|---|---|
| 助手中没有 OmniDoc 工具 | 检查程序路径和配置语法;重启助手或开新会话。用 schema 命令确认程序能启动。 |
Layout rendering needs Microsoft Edge… | 排版检查与页面图片需要 Microsoft Edge、Google Chrome 或 Chromium。Windows 通常自带 Edge;其他位置可设置环境变量 OMNIDOC_RENDER_BROWSER 指向浏览器程序。创建、读取与修改不受影响。 |
OmniDoc engine manifest…Engine file changed… | 安装目录中的引擎文件与接口程序不匹配。重新运行 OmniDoc 安装程序修复。 |
Output directory does not exist | 先用文件工具或 PowerShell 创建目录。 |
… already exists | 换一个文件名;或传 ifExists: "version" 自动另存为 name-2.udoc,传 "replace" 覆盖(旧文件进入历史)。 |
The file changed since revision… | 文件在你读取之后被修改过。重新调用 omnidoc_read_udoc,基于新的 revision 再修改。 |
Unknown reference(warnings) | 引用的标签不存在,文中会显示 ??。检查 label 与 \ref{} 的拼写。 |
| 原生校验失败 | 重新读取 guide 与 schema,检查完整错误中的块位置(如 blocks[3])。 |
| 直接 HTTP 调用无法连接 | 本机 HTTP 接口需要 OmniDoc 正在运行;MCP 与 CLI 不需要。 |
直接 HTTP 调用返回 401 | 重新读取当前 local-api.json,使用最新 token。软件重启后不要继续复用旧凭据。 |
直接 HTTP 调用返回 403 | 检查使用的 Host 是否为发现文件中的地址,并移除 Origin 头。通过本机脚本调用。 |
自定义用户目录如何设置?
默认目录是 %LOCALAPPDATA%\OmniDoc\Online,接口在其中保存修改历史与排版检查的临时数据。需要使用其他目录时,在配置中追加 --profile 与该目录的绝对路径。上方配置生成器会为三个客户端一起添加参数。
CLI 示例可使用 & $ai --profile 'D:/MyOmniDocProfile' create $sample $output。MCP 参数数组形如 ["--mcp", "--profile", "D:/MyOmniDocProfile"]。
原生接口是什么?需要 Python 或浏览器自动化吗?
接口随 Windows 客户端提供。OmniDocAI 直接调用安装目录中自带的 Rust 文档引擎,完成校验、打包、解包与修改;运行时不依赖 Python。
排版检查、页面图片与 HTML 导出会在后台启动一个独立的文档引擎,并以无头模式运行系统 Edge/Chrome 中的同一个 UniDoc 编辑器。它不操作你正在使用的窗口,也不连接云端服务;退出接口时一并结束。