让 AI 写文档。
在 OmniDoc 里
接着编辑。
把 Codex、Claude 或你的本机 AI 助手连接到 OmniDoc,直接生成 .udoc 文件。标题、正文、表格与公式,都能在文档里继续修改。
Windows 1.02 · 原生文档接口项目周报
本周进展
原生文档接口接入完成。
接下来,整理测试与发布计划。
| 任务 | 状态 |
|---|---|
| 接口接入 | 已完成 |
| 文档验收 | 进行中 |
下周计划
完善示例,收集使用反馈。
通过 MCP、命令行或本机 HTTP。
用原生文档块组织内容与格式。
指定输出位置,已有文件保留。
准备好这三件事
安装当前 Windows 1.02 客户端,保持软件运行。
它在安装目录中,与 OmniDoc 主程序一起提供。
支持 STDIO MCP,或能执行本机命令的 AI 客户端。
假设安装位置是 D:\OmniDoc,接口程序就是 D:\OmniDoc\OmniDocAI.exe。如果你选择了其他安装目录,下方填写真实路径即可。
普通云端聊天无法仅凭 Windows 路径访问你的电脑。本篇操作针对 Windows 本机环境;Linux 接入说明将在对应版本验收后补充。
先确认安装包包含接口程序
在 PowerShell 执行以下命令。第一条返回 True,随后输出带有 schema、workflow、version 的 JSON,即表示程序可启动。读取 schema 不需要打开文档服务。
$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.02"。配置中无需填写 API token。生成第一份文档
方式 A · 直接把任务交给 AI
接入成功后,将这段提示词发给助手,再指定输出文件的完整路径,例如 D:/Reports/weekly-001.udoc。
请使用 OmniDoc 的原生文档工具,写一份《项目周报》。
包含:标题、本周进展、两列任务表(任务 / 状态)、下周计划。
1. 先调用 omnidoc_get_udoc_schema,按实际 schema 编写 document。
2. 使用可编辑的 blocks:标题、正文和表格分别放在块中。
3. 先确认我指定的输出目录存在;若没有,请用你的文件工具创建。
4. 调用 omnidoc_create_udoc,保存到我指定的绝对路径。
5. 已有文件请保留,另存为新的 .udoc 文件名。
6. 成功后告诉我实际文件路径、字节数和 SHA-256。
开始前,请让我指定输出文件的绝对路径。生成成功后,助手会返回实际文件路径。用 OmniDoc 打开该 .udoc,即可编辑、保存或导出。
方式 B · 不依赖 AI,先跑通一个示例
保持 OmniDoc 打开,在 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 '生成失败,请按下方排错说明检查。' }
Write-Host "打开这个文件:$output"
Get-FileHash -LiteralPath $output -Algorithm SHA256path、bytes、sha256 与 native: true。读取、修改,再另存为新文档
在上方示例成功后的同一个 PowerShell 窗口执行。read 会导出可修改的 JSON;编辑其中的正文,再用 create 生成新版本。
# 在上方生成示例的同一个 PowerShell 窗口继续执行
$jsonOutput = [IO.Path]::ChangeExtension($output, '.json')
& $ai read $output $jsonOutput
if ($LASTEXITCODE -ne 0) { throw '读取失败。' }
# 修改 JSON 后,以新的文件名生成修改版
& $ai create $jsonOutput ([IO.Path]::ChangeExtension($output, '.edited.udoc'))原有文档会保留。再次运行时,请选一个新的输出文件名;CLI 和 MCP 都会拒绝覆盖已存在的文件。
原生文档怎么写
AI 提交一个 JSON 对象,由 OmniDoc 原生引擎校验并编码成 .udoc。标题、正文和表格按块组织;每个块使用唯一的正整数 para_id 标识。
以下是可直接提交的完整示例,和安装包中的示例 JSON 相同:
{
"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 读取完整 document,保留页面设置、资源及未修改的块,再创建一个新的输出文件。普通文档使用 blocks;需要完整网页交互的嵌入内容可按软件支持的 htmledit 结构处理。
四个工具,完成创建与修改
以下是助手在 MCP 中看到的实际工具名称和参数。document 传 JSON 对象;路径传完整的本机绝对路径。
| 工具 | 参数 | 结果 |
|---|---|---|
omnidoc_get_udoc_schema | {} | 返回 schema、workflow、version。 |
omnidoc_create_udoc | document 对象outputPath 新 .udoc 文件 | 原生校验后生成文件,返回路径、字节数、SHA-256。 |
omnidoc_validate_document | document 对象 | 调用原生校验器,返回校验摘要。创建时也会校验。 |
omnidoc_read_udoc | path 现有 .udoc 文件outputPath 可选,新 .json 文件 | 省略 outputPath 时直接返回 document;填写时写入 JSON 文件。 |
生成与读取文件的成功结果包含 native: true。MCP 将结果同时放在 structuredContent 和文本内容中;失败时返回 isError: true 与具体原因。
开发者:一次完整的 MCP tools/call 请求
STDIO 使用逐行 UTF-8 JSON-RPC。客户端完成 initialize 与 notifications/initialized 握手后,发送以下请求。请先创建 D:/Reports,并确认输出文件尚不存在。
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "omnidoc_create_udoc",
"arguments": {
"document": {
"format": "udoc",
"version": 3,
"unidoc_type": "docs",
"title": "项目周报",
"blocks": [
{
"para_id": 1,
"type": "paragraph",
"html": "<h1>项目周报</h1>",
"pages": [
1
]
},
{
"para_id": 2,
"type": "paragraph",
"html": "<p>本周完成原生文档接入。</p>",
"pages": [
1
]
}
]
},
"outputPath": "D:/Reports/weekly-001.udoc"
}
}
}成功时 result.structuredContent 的结构如下。路径、字节数与摘要以实际生成结果为准。
不要把 OmniDocAI.exe --mcp 当作普通命令运行后等待它显示界面;它会等待客户端通过标准输入发送协议消息。
脚本与应用也能调用
命令行接口
适合能够执行本机程序的助手和自动化脚本。create、validate、read 均连接已运行的 OmniDoc。
$ai = 'D:/OmniDoc/OmniDocAI.exe'
& $ai schema
& $ai create 'input.json' 'new-document.udoc'
& $ai validate 'input.json'
& $ai read 'existing-document.udoc' 'new-document.json'
# MCP 客户端使用的启动命令:
& $ai --mcpCLI 支持相对路径,并将其解析为绝对路径;MCP 要求绝对路径。输出目录必须存在,输出文件不能已存在。JSON 输入上限 64 MiB,UDOC 输入上限 128 MiB;内嵌资源另受原生 schema 的限制。
本机 HTTP 接口
需要直接集成时,从默认用户目录 %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 |
展开可运行的 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 命令确认程序能启动。 |
Open OmniDoc with profile…Desktop API unavailable… | 打开 OmniDoc,等待本机服务就绪。自定义用户目录时,在上方 profile 字段填入相同目录。 |
outputPath must be an absolute path | MCP 传入完整路径,如 D:/Reports/weekly-001.udoc。输出扩展名使用小写 .udoc;读取输出使用 .json。 |
Output directory does not exist | 先用文件工具或 PowerShell 创建目录。OmniDoc 的文档工具不会自动创建输出目录。 |
Output already exists… | 选择新文件名,例如 weekly-002.udoc。原文件保留;接口不会覆盖它。 |
| 原生校验失败 / 重复的 para_id | 重新读取 schema。保证标识为唯一正整数,必填字段齐全,再调用 create。检查完整错误中的字段位置。 |
429 / 每分钟调用额度已用完 | 按错误返回的秒数等待。避免反复单独校验;create 已包含原生校验。 |
直接 HTTP 调用返回 401 | 重新读取当前 local-api.json,使用最新 token。软件重启后不要继续复用旧凭据。 |
直接 HTTP 调用返回 403 | 检查使用的 Host 是否为发现文件中的地址,并移除 Origin 头。通过本机脚本调用。 |
自定义用户目录如何设置?
默认目录是 %LOCALAPPDATA%\OmniDoc\Online。只有桌面软件实际使用另一个 profile 时,才在配置中追加 --profile 与该目录的绝对路径。上方配置生成器会为三个客户端一起添加参数。
CLI 示例可使用 & $ai --profile 'D:/MyOmniDocProfile' create $sample $output。MCP 参数数组形如 ["--mcp", "--profile", "D:/MyOmniDocProfile"]。
原生接口是什么?需要 Python 或浏览器自动化吗?
接口随 Windows 客户端提供。OmniDocAI 通过本机 API 调用软件自带的 Rust 文档引擎,完成校验、打包和解包。运行时不依赖 Python,也不需要操纵编辑器界面。
本篇的 JSON 示例和 MCP/CLI 原生生成已在 Windows 安装包中验证;生成文档已检查编辑、保存和重开。Codex 与 Claude 的配置格式依据各自官方接入文档;具体客户端中的连接状态请按第 02 节检查。