document-mcp
MCP(模型上下文协议)服务器公开
documents.js文档转换,.odb、元数据和字体工具document-compute.js作为MCP工具,所以说MCP的代理可以转换、检查、编辑和计算docx/pptx/odt/odp/ods/odg/odf/pdf/odb/xlsx/markdown文档,而无需直接针对任何一个库编写TypeScript。
document-mcp 不添加任何转换或编辑逻辑-每个工具都是薄的 registerOperation() 包装器(src/register-operation.ts)在…周围 document-operations DocumentOperation该包包含实际的发送 documents.js的转换函数, DocumentConverter 港口, .odb/PDF阅读器,作为一个Zod模式和一个传输不可知的 run() 每个操作,与(最终)REST服务器共享 document-cli第二次解析自己的标志,而不是在这里定义。 document-cli 是基于相同底层操作的兄弟前端——终端CLI/TUI而不是MCP服务器——因此两者是一个共享实现的独立消费者,可以公开它的不同子集。一个 convert_document 这就是所谓的忠诚 (source, targetFormat) 对往返无损,这是一个尽最大努力重建,为什么-是到底是什么 documents.js自己的Fidelity部分 文件,表格包含;这里就不重述了。
graph TD
schema("document-schema.js")
ooxml("ooxml.js")
odf("odf.js")
pdfcodec("pdf-codec")
mdcodec("markdown-codec")
bytecodec("byte-codec")
documents("documents.js")
outline("document-outline.js")
compute("document-compute.js")
operations("document-operations")
mcp("document-mcp")
cli("document-cli")
schema --> outline
schema --> compute
schema --> mcp
schema --> ooxml
schema --> odf
schema --> pdfcodec
schema --> mdcodec
schema --> documents
ooxml --> documents
odf --> documents
pdfcodec --> documents
mdcodec --> documents
bytecodec --> pdfcodec
bytecodec --> documents
documents --> operations
outline --> operations
compute --> operations
operations --> mcp
documents --> cli
odf --> cli
pdfcodec --> cli
click schema "https://github.com/ExaDev/documents.js/tree/main/packages/document-schema.js" "document-schema.js"
click ooxml "https://github.com/ExaDev/documents.js/tree/main/packages/ooxml.js" "ooxml.js"
click odf "https://github.com/ExaDev/documents.js/tree/main/packages/odf.js" "odf.js"
click pdfcodec "https://github.com/ExaDev/documents.js/tree/main/packages/pdf-codec" "pdf-codec"
click mdcodec "https://github.com/ExaDev/documents.js/tree/main/packages/markdown-codec" "markdown-codec"
click bytecodec "https://github.com/ExaDev/documents.js/tree/main/packages/byte-codec" "byte-codec"
click documents "https://github.com/ExaDev/documents.js" "documents.js"
click outline "https://github.com/ExaDev/documents.js/tree/main/packages/document-outline.js" "document-outline.js"
click compute "https://github.com/ExaDev/documents.js/tree/main/packages/document-compute.js" "document-compute.js"
click operations "https://github.com/ExaDev/documents.js/tree/main/packages/document-operations" "document-operations"
click mcp "https://github.com/ExaDev/documents.js/tree/main/packages/document-mcp" "document-mcp"
click cli "https://github.com/ExaDev/documents.js/tree/main/packages/document-cli" "document-cli"
style mcp fill:#f9a825,stroke:#333,stroke-width:3px
开始
直接运行服务器-不需要安装步骤:
npx document-mcp
服务器使用 它的交通 (作为本地进程运行)。这由Claude Code, Claude Desktop, Codex CLI, Codex Desktop和OpenCode直接支持。克劳德·韦伯(克劳德。ai)、Claude Mobile和ChatGPT都需要一个 远程HTTP MCP服务器-参见 远程传输 下面。
兼容性
| 客户端 | 运输 | 直接支持 |
|---|---|---|
| 克劳德代码(CLI) | 的头 | ✅ |
| Claude Code(插件) | 的头 | ✅ |
| 克劳德桌面 | 的头 | ✅ |
| 食典委CLI | 的头 | ✅ |
| 食典委的桌面 | 的头 | ✅ |
| OpenCode | 的头 | ✅ |
| Claude Team/Enterprise (org) | 头(每台机器) | ✅通过托管设置 |
| Claude Web (Claude .ai) | HTTP / SSE只 | ❌需要远程传输 |
| Claude Mobile (iOS/Android) | HTTP / SSE只 | ❌需要远程传输 |
| ChatGPT (web /桌面) | HTTP只 | ❌需要远程传输 |
从Claude Code连接
一行(直接添加MCP服务器):
claude mcp add --transport stdio document-mcp — npx -y document-mcp
或者作为Claude Code插件安装(这个repo是一个插件市场-包括新版本的自动更新):
从终端:
claude plugin marketplace add ExaDev/document-mcp
claude plugin install document-mcp@exadev
或者从正在运行的Claude Code会话中:
/plugin marketplace add ExaDev/document-mcp
/plugin install document-mcp@exadev
运行 /reload-plugins 在已经运行的会话中激活。在Claude Desktop或Claude .ai上: 自定义→插件→浏览插件,搜索 document-mcp,并安装。
从Codex CLI连接
codex mcp add document-mcp — npx -y document-mcp
或者通过Codex桌面应用程序: 设置→MCP服务器→+添加。
或者加上 ~/.codex/config.toml 手动:
[mcp_servers.document-mcp]
command = "npx"
args = ["-y", "document-mcp"]
从OpenCode连接
将......添加到...... opencode.json:
{
"mcp": {
"document-mcp": {
"type": "local",
"command": ["npx", "-y", "document-mcp"]
}
}
}
从Claude Desktop连接
添加到 mcpServers 在Claude Desktop的配置文件(~/Library/Application Support/Claude/claude_desktop_config.json 在macOS):
{
"mcpServers": {
"document-mcp": {
"command": "npx",
"args": ["-y", "document-mcp"]
}
}
}
或者,对于针对此存储库而不是发布包的签出的本地开发,点 command 直接在构建的二进制文件中:
{
"mcpServers": {
"document-mcp": {
"command": "node",
"args": ["/absolute/path/to/document-mcp/dist/bin.js"]
}
}
}
从Claude团队/企业(组织)连接
组织管理员可以通过以下方式集中部署MCP服务器配置 服务器托管的设置 管理设置→克劳德代码→克劳德中的管理设置。人工智能控制台)。一个 managed-settings.json document-mcp条目强制组织中所有Claude Code用户之间的连接-不需要每个用户设置。管理员还可以允许/阻止特定的MCP服务器通过 allowedMcpServers/blockedMcpServers 在同一个文件中。
远程传输(HTTP)
Claude Web, Claude Mobile和ChatGPT只接受 远程 (HTTP/SSE) MCP服务器-本地工作室进程无法从浏览器或电话访问。要在这些平台上使用document-mcp,请在HTTP传输后运行它:
npx document-mcp --transport http --port 3000
这就开始了真正的 Streamable HTTP 监听器绑定到 127.0.0.1 (仅环回) --port (默认 3000),服务于相同的工具集演播室传输寄存器-每个请求一个MCP服务器实例,从相同的构建 createServer() 工厂。 --port 0 向操作系统请求一个空闲端口;在服务请求之前,服务器报告它在stderr上实际绑定的端口。答案是 /mcp 其他地方都是404;来自旧的HTTP+ sse时代的客户机的请求与同一端点上的当前客户机一起透明地提供服务,因此没有分离 --transport sse 选择。
然后添加服务器URL(例如: https://your-host:3000/mcp)作为Claude Web (claude.ai /定制/连接器)或ChatGPT (设置→连接器→高级→启用开发人员模式→创建). 使用隧道(Cloudflare隧道,ngrok)或使用TLS部署到服务器-这两个平台都需要HTTPS;仅限环回绑定意味着隧道或反向代理必须运行在相同的主机上 document-mcp 本身。
安全注意事项: 这个HTTP监听器没有身份验证,也没有自己的Host/Origin允许列表——任何可以访问它的人都可以调用任何工具,包括读写任意文件系统路径的工具。默认情况下,它是安全的,因为它绑定了环回;无论它为远程访问(隧道、反向代理)做什么,都负责在流量到达此进程之前对调用者进行身份验证。
独立的二进制
每个版本还附加一个Node 单一可执行文件的应用程序 构建Linux (x64和arm64), Windows (x64和arm64)和macOS (Apple Silicon和Intel)到该版本自己的GitHub发布资产-整个服务器及其依赖项嵌入在一个文件中,不需要Node.js安装或 npx 在所有。两者都支持 stdio 和 --transport http 如上所述;点MCP客户的 command 直接下载二进制文件,而不是 npx/node. 从包的标签中下载与您的平台匹配的资源 发布页面 并直接运行它(chmod +x 首先在Linux/macOS上)。
集装箱图片
每个版本还发布了一个多arch (linux/amd64 + linux/arm64)容器映像到GitHub容器注册表,包装相同的独立 --transport http 在最小值上的二进制 distroless base而不是Node安装:
docker run -p 3000:3000 ghcr.io/exadev/document-mcp:VERSION --port 3000
图像总是出现 --transport http 模式- stdio mode是由MCP客户端作为子进程直接执行的,容器在子进程中没有任何作用,并且绑定到子进程 0.0.0.0 在容器内不管 --port,所以 -p <host>:<container> 到达 /mcp 直接。取代 VERSION 使用软件包自己的确切发布版本; latest 还跟踪最新的版本,匹配 document-rest相同的图像。看到 远程传输 此侦听器本身缺乏身份验证。
发展
需要node . js >=20 和规划 11.6.0 (固定通过 packageManager 在 package.json).
pnpm install
pnpm build # turbo -> tsdown -> dist/ (ESM + CJS + .d.ts)
pnpm typecheck # turbo -> tsc --noEmit
pnpm lint # turbo -> eslint . --fix --cache --max-warnings 0
pnpm test # turbo -> vitest run --project unit
pnpm test:workers # turbo -> vitest under the real Cloudflare Workers runtime (workerd) via @cloudflare/vitest-pool-workers, driving createServer() through an in-memory JSON-RPC pair
pnpm test:smoke # turbo -> tsdown then vitest --project smoke — spawns dist/bin.js as a real subprocess driven over genuine MCP stdio
I / O文档
每个获取或产生文档字节的工具都会经过相同的两个混合形状,这里记录一次,而不是下面每个工具重复记录一次。
输入 (DocumentInput)是一个union:一个文件系统 path (格式是从文件扩展名-推断出来的 docx, pptx, xlsx, odt, odp, ods, odg, odf, md/markdown, pdf),或内联 bytesBase64 加上一个显式 format (必需的,因为内联字节不携带文件名来进行推断)。每个ODF/OOXML模板和支持宏的变体也读取为其基本格式: .ott/.ots/.otp/.otg/.otf 作为 odt/ods/odp/odg/odf, .dotx/.potx/.xltx (模板)或 .docm/.xlsm/.pptm (宏启用)作为它们的OOXML基——模板与 -template 而启用宏的文件携带 vbaProject 部分此库读取过去而不执行或重新发出。 .odb 工具是唯一的例外 .odb 没有单一的 DocumentFormat 它自己(它是一个数据库前端,而不是文档——表、保存的查询和报告是三个不相关的输出形状),所以它们的 source.path/source.bytesBase64 直接读取字节而不进行格式推断。
输出 (DocumentOutput),在生成文档的每个工具上都是单个可选项 outputPath:提供它以使工具将结果写入该文件系统路径(然后报告响应) { path, byteLength }); 省略它以接收内联字节({ bytesBase64, byteLength },标记 large: true 大于5mb(仅供参考,字节永远不会被截断或拒绝)。
工具
| 工具 | 描述 |
|---|---|
convert_document | 将文档从支持的一种格式转换为另一种格式 documents.js的 DocumentConverter 端口- docx、pptx、xlsx、odt、odp、ods、odg、odf、markdown、rtf、wpd、doc、xls、ppt、epub、csv、svg、pdf。并不是每一个 (source, targetFormat) Pair是直接的;呼叫 list_document_conversions 第一。 |
list_document_conversions | 列出了每一个 (source, target) 格式对 convert_document 实际支持。 |
metadata_read | 读取文档的标题/作者/主题/关键字/创建者/生产者/创建和修改的时间戳。适用于所有支持的格式,包括xlsx和odf。 |
metadata_write | 适当地修补文档的标题/作者/主题/关键词。不转换格式-源格式和目标格式必须匹配(或两者都是? pdf); Odf(一个独立的公式文档)被拒绝,因为它根本没有写路径返回。 |
document_create | 通过创建一个新的空白文档 documents.js自己的实时编辑器(createDocx/createOdt/createMarkdownEditor/……)- docx、pptx、odt、odp、ods、odg、pdf或markdown。 |
document_append_paragraphs | 通过相同的实时视图编辑器,将一个或多个段落附加到docx、odt或markdown文档的末尾——每个段落都可以由几个独立格式的运行构建而成 document_create 和document-cli自己的TUI使用。不转换format - source和targetFormat必须匹配。docx和odt共享相同的字段集(underline, fontFamily, sizePt, color, headingLevel, alignment);Markdown支持一个更小的、不同的集合(超链接、内联代码),它会直接拒绝docx/odt-only字段,而不是默默地删除它。 仅涵盖文字处理段落/运行编辑-幻灯片,表格,绘图,表格,列表和图像是一个单独的编辑界面,这里尚未公开。 |
fonts | 列出docx/pptx/odt/odp/ods/odg文档携带的每个嵌入源代码的字体(字体族、粗细/样式、字节长度)。 |
describe_font_file | 独立阅读 .ttf/.otf 字体文件,并报告它声明的关于自身的族/粗体/斜体三体。 |
docx_extras | 读取docx自己的注释、脚注、页眉/页脚部分和编号定义-数据 ContentDocument 枢轴不能携带,所以其他工具看不到它。 |
pdf_inspect | 解析PDF并报告摘要(页数、每页大小和项目类型直方图、元数据、嵌入的图像格式)或 full: true 整个解析过程 LayoutDocument 作为纯JSON -不 $schema 斯坦普,自从那家人搬到 pdf-codec 在 document-schema.js 4.0.0失去了它的模式盖章的信封。 |
odm_to_pdf | 转换 .odm (ODF主文件)转换为PDF格式。一个 .odm 从不将其章节的内容内联,因此每个章节通过调用者提供的方式进行解析 chapters Href-to-document地图和/或 chaptersDir 按basename搜索。 |
from_package | 以目标格式重建实际文档字节 DocumentTree 先前序列化为JSON(例如,通过转换工具自己的) onDocument/ package-dump步骤)。只有真正由当前转储编写的包才会往返: $schema 它携带的URI将 document-schema.js 编写它的发行版,以及4.0.0之前的转储(flat { formatVersion, content, pages } 信封)被拒绝,并给出一个错误,命名固定的发布、从平面到树的更改,以及补救措施—布局文档转储获得自己的指针,命名移动到 pdf-codec。 |
outline_document | 将文档自己的目录投影为结构化JSON: groups ({ text, level, children })用于标题、列表项、幻灯片、表格和绘制页面、页({ kind, text })浏览它们之间的内容。大纲是在源自己的原生内容-直接通过阅读 documents.js的 readNativeDocumentTree (没有桥接转换,没有丢弃的输出字节)和由 document-outline.js的 buildOutline。 |
compute_formula | 读取文档嵌入的每个公式(docx/odt/markdown段落和pptx/odp幻灯片形状);也读取表格单元格自己的块——docx自己的阅读器恢复嵌套在表格单元格中的真实方程;从结构上讲,遍历还涵盖了绘图页面自己的形状流,尽管目前该系列中还没有编写器在那里填充公式;电子表格自己的单元格锚定公式对象;一个独立的 .odf 公式的文档;以及一个嵌套在任何深度的另一个嵌入对象中的公式(例如,嵌入在电子表格中嵌入的绘图中的公式),并逐一求值 document-compute.js的units-typed evaluate() -代理检查文档所声明的算术是否正确的方法。引用符号的公式需要通过提供该符号的值 bindings,由文档自己的符号表id进行键控;每个公式独立报告自己的结果(evaluated, no-content,或 error),因此需要更多绑定的公式不会阻塞其他公式。 |
odb_tables | 列出嵌入的每个表 .odb 数据库跨每个存储层声明—列名、类型和行数据 documents.js 支持(HSQLDB文本/缓存/二进制,火鸟备份)。 |
odb_forms | 列出每个表单 .odb 数据库声明,使用每个表单自己的数据源和字段绑定控件。 |
odb_reports | 列出每个报告 .odb 数据库声明,使用每个报表自己的数据源命令、频带/组结构和 rpt: 公式表达式。 |
odb_query | 运行一个边界 SELECT (使用任何类型的可选join、表别名、派生表) FROM, IN/EXISTS 子查询) .odb 数据库提取的表-直接作为SQL或通过命名保存的查询给出。不涉及数据库引擎;没有列别名;不支持的构造被报告为工具错误命名,永远不会被静默忽略。 |
odb_to_csv | 对象中提取一个指定的表 .odb 数据库为CSV字节。每当数据库声明多个表时,都需要表名。 |
odb_to_xlsx | 提取嵌入的每个表 .odb 数据库声明为一个XLSX工作簿,每个表一个工作表。 |
odb_render_report | 解决一个 .odb 数据库自己的报告-它的数据绑定命令通过有界SQL引擎运行,它的 rpt: 计算公式,布局其条带,并将结果呈现为docx、odt或pdf。 |
参考文献
- documents.js -该服务器公开的库。
- document-outline.js -在document-schema.js的树状结构上使用artifacts -utilities包
DocumentTree谁的buildOutline权力outline_document。 - document-compute.js -单位类型
MathExpression评估者的evaluate()权力compute_formula。 - document-cli -同一库上的兄弟CLI/TUI,其工具链被此存储库的scaffold镜像。
- 模型上下文协议 -该服务器实现的协议,通过
@modelcontextprotocol/server。
陷阱
- 运行时依赖项包括
document-operations+documents.js+@modelcontextprotocol/server+@modelcontextprotocol/node+zod只有;pdf-codec,odf.js,document-schema.js是devDependencies(仅支持测试)。@modelcontextprotocol/node是Node适配器(toNodeHandler)--transport http监听器用于架桥@modelcontextprotocol/serverweb标准的createMcpHandler在平原上node:http服务器-参见 远程传输 以上。每个工具的实际实现——转换/编辑/检查/.odb中直接定义的逻辑src/tools/*.ts,包括自己的范围document-outline.js的buildOutline/outlineLeafText和document-compute.js的evaluate()-现在住在document-operations作为一个DocumentOperation;这个包自己的src/tools/*.ts是薄的registerOperation()包装器(src/register-operation.ts),将每个操作注册为MCP工具,对于其自身错误需要MCP特定浓缩的两个操作(odb_render_report的OdbReportNotSpecifiedError,odm_to_pdf的OdmUnresolvedSectionError),一个mapError钩。每次运行时到达pdf-codec/odf.js- - - - - -ProvidedFont/FontSubstitution/describeFontFace/WinAnsi取代形状-通过documents.js中国自己的再出口(通过document-operations),因此发布的安装不会直接拉入pdf-codec/odf.js依赖。odf.js和document-schema.js生存在devDependencies仅适用于本包自己的测试装置和compute_formula自己的测试断言(document-schema.js的assembleTree/ContentDocument);src/test-support/被排除在tsdown仅构建src/index.ts和src/bin.ts有没有入口点,所以这些东西都不会运进来dist/。
贡献
发布、CI和提交消息约定都是工作空间范围的,而不是包本地的——请参阅 monorepo root README 对于释放机制和 CONTRIBUTING.md 对于共享的git钩子和历史约定。工作内 packages/document-mcp/。
许可证
麻省理工学院