document-rest

中文文档
1.4.204发布于 2026/11/03MITTypeScriptESM + CJS构建来源已验证

A plain REST API server exposing document-operations' conversion, editing, inspection, and .odb operations as JSON-over-HTTP endpoints — one POST route per operation, for a caller with no MCP client and no Node runtime of their own.

原始使用文档
文档目录9 节
  1. Getting started
  2. Standalone binary
  3. Container image
  4. API
  5. Errors
  6. Getting started (development)
  7. Gotchas
  8. Contributing
  9. License

document-rest

GitHub npm npm version CI

A plain REST API server exposing document-operations's document-conversion, .odb, metadata, and font tooling as JSON-over-HTTP POST routes, for a caller with no MCP client and no Node runtime of its own — a Kotlin/JVM app, a Python script, or any other language with an HTTP client.

document-rest adds no conversion or editing logic of its own — like document-mcp, it is a dispatch layer over document-operations, the only difference being the transport: one POST route per operation instead of one MCP tool. document-mcp's existing --transport http mode is not a substitute for this: it speaks MCP's own JSON-RPC protocol over a single /mcp path, which still needs an MCP client library to call — this package is for a caller that wants ordinary request/response JSON with no protocol of its own layered on top.

Getting started

Run the server directly — no install step needed:

npx document-rest --port 3100

This binds a plain node:http listener to 127.0.0.1 (loopback only) on the given --port (default 3100; --port 0 asks the OS for a free port, reported on stderr once bound).

Security note: this listener has no authentication and no Host/Origin allowlisting of its own — anyone who can reach it can call every operation, including ones that read and write arbitrary filesystem paths. It is safe by default only because it binds to loopback; whatever fronts it for remote access (a tunnel, a reverse proxy) is responsible for authenticating callers before traffic ever reaches this process. Matches document-mcp's own --transport http listener, which carries the identical note for the identical reason.

Standalone binary

Every release also attaches a Node single-executable application build for Linux (x64 and arm64), Windows (x64 and arm64), and macOS (Apple Silicon and Intel) to that release's own GitHub Release assets — the entire server and its dependencies embedded in one file, needing no Node.js install or npx at all. For the "a caller with no Node runtime of its own" case this package exists for in the first place, this removes the last Node dependency too: download the asset matching your platform from the package's tag on the Releases page, run it directly (chmod +x on Linux/macOS first), and it takes the identical --port flag.

Container image

Every release also publishes a multi-arch (linux/amd64 + linux/arm64) container image to GitHub Container Registry, wrapping the identical standalone binary above on a minimal distroless base rather than a Node install:

docker run -p 3100:3100 ghcr.io/exadev/documents.js:VERSION --port 3100

Replace VERSION with the package's own exact release version (e.g. 1.2.0) — matching the version-pinned convention every other artifact in this repository uses, this image is never published under a loose major/minor tag such as 1 or 1.2, though latest does track the newest release. The image binds to 0.0.0.0 inside the container regardless of --port, so -p <host>:<container> is all that's needed to reach it; see the security note above about this listener having no authentication of its own — publishing the container's port makes it reachable by anything that can reach the host, so put a reverse proxy or firewall in front of it before exposing it beyond your own machine.

API

GET / lists every available operation:

curl http://127.0.0.1:3100/
{ "operations": [{ "name": "convert_document", "title": "Convert document", "description": "..." }, ...] }

POST /<operationName> runs one operation: the request body is JSON, validated against that operation's own input schema, and the response is { "result": ... } on success. Every operation document-operations defines is reachable this way — see that package's own README for the full list of operation names and what each one does; the request/response shapes are identical to the equivalent MCP tool's own structuredContent, since both dispatch to the exact same run() function.

curl -X POST http://127.0.0.1:3100/convert_document \
  -H 'content-type: application/json' \
  -d '{"source":{"path":"/tmp/report.docx"},"targetFormat":"markdown"}'

Errors

StatusWhen
400The request body is not valid JSON, fails the operation's own input schema ({ error, issues }, from Zod's treeifyError), or the operation itself threw ({ error }, the thrown message verbatim).
404No operation exists with that name.
405A method other than POST was used against a known operation route (GET / is the only exception).

Two operations enrich their 400 body beyond a bare { error }, mirroring document-mcp's own registerOperation mapError hooks for the identical two typed errors: odb_render_report's OdbReportNotSpecifiedError adds availableReports (every report name the .odb actually declares), and odm_to_pdf's OdmUnresolvedSectionError adds hrefs (every chapter reference that failed to resolve).

Getting started (development)

Requires Node.js >=20 and pnpm 11.6.0 (pinned via packageManager in package.json).

pnpm install
pnpm build      # turbo -> tsdown -> dist/ (ESM + CJS + .d.ts)
pnpm typecheck  # turbo -> tsc --noEmit, plus attw --pack
pnpm lint       # turbo -> eslint . --fix --cache --max-warnings 0
pnpm test       # turbo -> vitest run, driving a real ephemeral-port HTTP server through fetch()

Gotchas

  • No streaming, no chunked upload. readJsonBody buffers the entire request body into memory before parsing it as JSON, matching every operation's own hybrid bytesBase64-or-path input convention (a large document is better supplied by filesystem path, read once by the operation itself, than base64-inflated over HTTP).
  • Abort on client disconnect. Each request gets its own AbortSignal, wired to the underlying IncomingMessage's close event (node:http carries no AbortSignal of its own) — a client that disconnects mid-conversion causes the operation's own signal-aware work (e.g. convert_document's page-boundary cancellation) to stop at the next checkpoint rather than running to completion for a caller no longer listening.

Contributing

Release, CI, and commit-message conventions are all workspace-wide, not package-local — see the monorepo root README for the release mechanism and CONTRIBUTING.md for the shared git hooks and history conventions. Work inside packages/document-rest/.

License

MIT

版本与发布记录

document-rest 共发布 208 个版本,首次发布于 2026/09/11;过去 12 个月发布了 208 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.4.204latest2026/11/03今天
1.4.2032026/10/313 天前
1.4.2022026/10/313 天前
1.4.2012026/10/313 天前
1.4.2002026/10/313 天前
1.4.1992026/10/313 天前

关于 document-rest 的常见问题

document-rest 是什么?

一个普通的REST API服务器,公开文档操作的转换、编辑、检查和操作。odb操作作为JSON-over-HTTP端点—对于没有MCP客户端和自己的Node运行时的调用者,每个操作一个POST路由。

如何安装 document-rest?

在项目目录运行 npm install document-rest,或使用 pnpm add / yarn add / bun add。它还提供命令行工具 document-rest,可以用 npx document-rest 直接运行。

document-rest 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

document-rest 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

document-rest 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

document-rest 可以商用吗?

document-rest 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

document-rest 还在维护吗?

最新版本 1.4.204 发布于 2026/11/03(今天);至今共发布 208 个版本,其中过去 12 个月发布了 208 个;首次发布于 2026/09/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。