npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

libreoffice-mcp

v0.1.0

Published

MCP server that drives a local LibreOffice instance over UNO: convert, export, read and edit Writer/Calc/Impress documents.

Readme

LibreOffice MCP

WorkBuddy 连接器:让 AI 直接驱动本机安装的 LibreOffice,完成文档转换、导出、读取与编辑。

  • 接入方式:MCP + Skill(本地 stdio 进程,无需 OAuth、无需上传文件)
  • 支持平台:Windows 完整支持;Linux 实验性支持(需系统装有 python3-uno);macOS 暂不支持,会返回显式错误
  • 工具数量:22
  • 依赖:本机已安装 LibreOffice(Windows 无需另装 Python;Linux 需 python3-uno)

版本与环境

开发与全部实测结论对应的环境:

| 项目 | 版本 | |---|---| | 操作系统 | Windows 11 Pro(10.0.26300,x64) | | LibreOffice | 26.2.6.3 | | Python | 3.12.14(CPython,LibreOffice 自带) | | Node.js | 22.22.2(要求 ≥ 18) | | npm | 10.9.7 |

运行期依赖只有 Node.js ≥ 18 与本机 LibreOffice。不需要 uv,也不需要 pip install 任何包——UNO 绑定随 LibreOffice 一起安装。

  • PDF 专用参数(page_range / pdfa / password / quality)需要 LibreOffice 7.4 及以上,更低版本会退回默认导出并在结果里给 warning。
  • 用户机器上的实际版本由 lo_status 返回:os、node、python_version、version(LibreOffice)。排查环境问题时以这几个字段为准,不要用上表的开发版本代替。

它是怎么工作的

WorkBuddy ──stdio/JSON-RPC──▶ Node MCP Server ──UNO socket──▶ headless soffice
                                    │
                                    └──JSON-Lines──▶ UNO Worker(带 uno 绑定的 Python)
  • Node 侧负责 MCP 协议、参数校验、路径守卫、作业队列。
  • UNO Worker 由一个能 import uno 的 Python 启动(Windows 用 LibreOffice 自带的 python.exe;Linux 用系统的 python3,需装 python3-uno),直接调用 UNO API 完成文档操作。
  • 每个 MCP 会话使用独立的临时 UserInstallation 配置,不会与用户正在使用的 LibreOffice 互踢。

工具一览

| 分组 | 工具 | |---|---| | 环境 | lo_status、lo_restart_runtime | | 转换导出 | lo_convert、lo_convert_batch、lo_job_status、lo_export_pdf、lo_export_images | | 读取 | lo_read_text、lo_inspect、lo_calc_read、lo_calc_formulas、lo_calc_sheets、lo_writer_paragraphs、lo_impress_read | | 写入 | lo_create、lo_writer_write、lo_writer_replace、lo_calc_write、lo_calc_recalc、lo_impress_set_text、lo_metadata、lo_merge |

支持的目标格式(lo_convert):pdf docx doc odt rtf txt html xlsx xls ods csv pptx ppt odp fodt fods fodp odg

目标格式必须与源文档同族(文字→文字、表格→表格、演示→演示、绘图→odg)。跨族转换 LibreOffice 不会报错,而是把源格式写进目标文件;连接器会校验产物容器,不一致就返回 FORMAT_MISMATCH。

图片(png / jpg)不是转换目标格式,逐页导出请用 lo_export_images。

本地开发

npm install
npm run build        # 编译 TS 并复制 worker.py 到 dist/py
npm run smoke        # 端到端冒烟:22 个工具跑真实文档
npm run audit        # 发布前审计:97 项,覆盖元数据/协议/功能/异常/安全/文档一致性
npm run scenarios    # 场景验证:靠环境模拟验证「未安装/被占用/macOS/超时/超大文件」等
npm run guard        # 预算与预检回归:30 秒口径、PDF 拦截、产物与预算的实测耗时
npm run real         # 真实文件验证:跑 samples/ 下的业务文件(旧格式升级 + PDF + 预览图)
npm run pkg          # 打包产物验证:把待发布的 tarball 装进干净目录再启动

npm run audit 通过真实 stdio JSON-RPC 驱动服务,逐条打印 PASS/FAIL,结果写入 docs/audit-report.json。 npm run scenarios 用真实环境模拟覆盖那些"人眼才能判断"的条目:起一个占用默认 profile 的 LibreOffice 验证共存、用 --import 钩子伪造"未安装"与 macOS、把超时压到 400ms 验证报错可读、把大小上限压到 1MB 验证拦截,结果写入 docs/scenario-report.json。 npm run real 需要你把待测文件放进 samples/(不入 npm 包),覆盖旧格式保真升级、8MB 级大文件、真实母版渲染与文本替换。

三套脚本都返回非零退出码,可直接当 CI 门禁。检查项定义见 docs/release-checklist.md,提审前必须全绿。

在 WorkBuddy 里本地挂载(开发调试用)

项目级 mcp.json 用本地路径,替代 npx 方式(<项目根> 换成你本机的实际路径):

{
  "mcpServers": {
    "libreoffice": {
      "type": "stdio",
      "command": "node",
      "args": ["<项目根>/dist/index.js"],
      "timeout": 60000
    }
  }
}

timeout 不要低于 30000:连接器内部单次调用预算上限是 28 秒(含冷启动),声明值更小的话,长任务会被传输层先掐断,看到的就不是可读的 TIMEOUT 了。改完需在 WorkBuddy 界面点一次「信任」才会激活。

环境变量

| 变量 | 作用 | 默认 | |---|---|---| | LO_PROGRAM_DIR | 指定 <LibreOffice>/program 目录 | 自动探测(注册表 / 常见路径 / PATH) | | LO_SOFFICE | 直接指定 soffice 可执行文件 | — | | LO_MCP_TIMEOUT_MS | 单次调用预算上限(对所有工具生效,上限 55 秒) | 28000 | | LO_MCP_BOOT_TIMEOUT_MS | 无头进程启动等待上限 | 30000 | | LO_MCP_MAX_FILE_MB | 单文件大小上限 | 200 | | LO_MCP_ALLOW_ROOTS | 允许访问的根目录,系统路径分隔符分隔 | 工作目录 + 主目录 + 临时目录 |

已知限制

  • macOS 未实现:lo_status 会返回 UNSUPPORTED_PLATFORM 并说明原因。
  • Linux 需要 python3-uno(Debian/Ubuntu)或 libreoffice-pyuno(Fedora)。
  • 复杂排版(艺术字、VBA 宏、非常见字体)转换保真度取决于 LibreOffice 过滤器,交付前应抽查。
  • PDF 专用参数(page_range / pdfa / password / quality)通过 FilterOptions JSON 传递,需要 LibreOffice 7.4 及以上;更早版本会退回无参数导出,并在返回值的 warning 字段里说明。注意:这些参数以 FilterData 属性传入时会被 LibreOffice 静默忽略(不报错、不生效),已在代码注释中标注原因,勿改回。
  • 读取 PDF 很慢,且无法优化:LibreOffice 需要先把 PDF 导入成绘图文档再逐形状取文本。实测 7.1MB / 41 页:导入 27.3 秒 + 遍历 21.5 秒 ≈ 48.8 秒,约 6.6 秒/MB;同一份文件在三次实测里出现 48.4s / 48.9s / 55.4s 的波动(取决于机器负载),所以 6MB 以上就已贴近 55 秒上限。因此 lo_read_text / lo_inspect 对 >2MB 的 PDF 会直接拦截(毫秒级返回 PDF_TEXT_SLOW),要读需显式传 allow_slow: true。docx / xlsx / pptx 不走这条路径,7.7MB 演示文稿约 1 秒。
  • 单次调用预算是整次调用的总预算,冷启动时间也算在里面(早期版本把启动与操作分开计时,最坏能叠到 80 秒以上)。统一为 28 秒,与平台「建议 30 秒内响应」的口径一致;与 mcp.json 声明的 60 秒传输超时留有大量余量,保证用户看到的是带 hint 的 TIMEOUT 而不是传输层中断。LO_MCP_TIMEOUT_MS 可整体放宽,但会被截到 55 秒 —— 再长只会让宿主先断开。
  • 唯一会超过 30 秒的路径是大 PDF 的 allow_slow: true(上限 55 秒),已由调用方显式选择。预期耗时较长的任务请直接走 lo_convert_batch + lo_job_status 作业模式。
  • 作业进行中再调用其他 lo_* 工具会排队(LibreOffice 文档对象不是线程安全的),此时只用 lo_job_status 轮询即可。
  • 批量作业的状态只存在内存里:MCP 进程重启后旧 job_id 失效(会返回 JOB_NOT_FOUND)。
  • 默认只允许访问工作目录、用户主目录与临时目录;数据盘上的素材需通过 LO_MCP_ALLOW_ROOTS 显式放行,当前允许范围可用 lo_status 的 allowed_roots 查看。
  • 客户端异常强杀进程时(Windows TerminateProcess),本次会话的临时 profile 无法自清,会由下一次启动扫描回收。

目录结构

├── src/                    Node MCP Server(TypeScript)
│   ├── platform.ts         soffice / python 探测
│   ├── runtime.ts          进程生命周期、RPC、自愈重试
│   ├── jobs.ts             批量作业队列
│   ├── paths.ts            路径守卫
│   ├── tools.ts            22 个工具注册
│   └── py/worker.py        UNO worker
├── connector/              提交到连接器市场的包
│   ├── connector-meta.json
│   ├── mcp.json
│   ├── icon.svg
│   ├── SUBMIT.md           提审说明与自检清单
│   └── skills/libreoffice/SKILL.md
├── scripts/copy-assets.mjs 构建后复制 worker.py
├── test/
│   ├── smoke.mjs          端到端冒烟
│   ├── audit.mjs          发布前审计(含格式清单/PDF 参数一致性)
│   ├── scenarios.mjs      场景验证(环境模拟 + 文档指导性)
│   ├── guard.mjs          预算与预检回归(28 秒口径、PDF 拦截、各操作实测耗时)
│   ├── real-samples.mjs   真实业务文件验证
│   ├── pkg-install.mjs    待发布 tarball 的安装态验证
│   ├── sim/               环境模拟钩子(伪造未安装 / darwin)
│   ├── fixtures/          合成夹具(含组合形状页)
│   ├── make-fixtures.py   生成夹具
│   ├── probe-*.py/.mjs    实测取证脚本(不参与自动回归,结论见 CHANGELOG)
│   └── demo-real.mjs      真实场景演练(模板填充 → PDF → 预览图)
│   (`debug-*.mjs` 为排障脚本,不在发布范围内)
├── docs/
│   ├── connector-design.md    设计与任务分解
│   ├── release-checklist.md   发布前检查清单
│   ├── npm-publish.md         npm 发布操作单
│   ├── audit-report.json      最近一次审计结果
│   ├── scenario-report.json   最近一次场景验证结果
│   └── real-samples-report.json 最近一次真实文件验证结果
├── CHANGELOG.md            版本记录与已知限制

License

MIT