Cherry Studio 本地文档转 Markdown 完全指南:mcp__cherry-tools__to_markdown 工具的用法、边界与原理
【免费下载链接】cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端项目地址: https://gitcode.com/CherryHQ/cherry-studio
Cherry Studio 通过内置 MCP 服务器向 Agent 注入了一组第一方工具,其中mcp__cherry-tools__to_markdown负责把受支持的本地文档(Word、PPT、Excel、OpenDocument、PDF 等)转换为 Markdown。本文以官方技能参考 documents.md 为骨架,结合仓库源码与测试用例,系统讲解该工具的路由定位、调用契约、路径授权边界、输出管理、恢复策略与底层实现,帮助读者(以及阅读本文的 Agent/LLM)在会话中安全、准确地使用这一能力。
一、工具定位:与知识库、Shell 的边界
to_markdown解决的是**"读取一份本地文档的结构化内容"**问题——当普通文本读取工具无法处理 Office/PDF 等二进制格式时,由它来接管。官方路由表(SKILL.md)明确区分了三条路径:
- 本地文档读取/转换→
mcp__cherry-tools__to_markdown,然后按需读取返回的临时 Markdown 文件; - 知识库问答→
mcp__cherry-tools__kb_list→kb_search→kb_read,这些工具检索的是已被 Cherry 索引过的文档,而非任意本地文件; - Shell 执行→ 项目捆绑的
bun/uv/uvx/rg运行时,用于跑脚本、执行一次性工具、搜索代码。
三者互不替代:to_markdown不检索知识库,也不是通用 Shell 替代品。从源码看,该工具由独立的领域提供器CherryDocumentTools实现,并由CherryBuiltinToolsServer聚合进名为cherry-tools的 MCP server(见 cherryBuiltinTools.ts),与其他领域工具(CherryKnowledgeTools、CherryAutonomyTools、CherryCliTools)并列注册。
二、工作流:一次完整的文档转换
官方参考文档给出了标准调用序列,结合源码 cherryDocumentTools.ts 可以还原完整流程:
- 传入路径:调用工具时传入一个
path参数——可以是相对会话工作区的路径,也可以是绝对路径(须属于本会话授权范围,见下文"路径授权"一节); - 路径解析与鉴权:工具先尝试把路径解析到会话工作区内;失败后再尝试 agent 数据目录与会话附件等可信根。任何越权路径都会在转换开始前被拒绝;
- 格式识别:加载
@firecrawl/anydoc转换库,通过formatFromExtension(path.extname(...))取扩展名对应的格式,再调用toMarkdownBytes完成转换(该库也会从文件内容识别格式,扩展名仅作兜底); - 写入临时文件:转换结果被整体写入 agent 私有的临时 Markdown 文件(位于
<agentDataPath>/tmp/to-markdown/<uuid>.md,以wx标志创建); - 返回结果:工具结果只包含该临时文件的绝对路径和字符数,不会把整篇文档塞进模型上下文;
- 后续读取:Agent 用普通文件工具对返回路径做切片读取、搜索,或按用户要求复制到最终路径。
关键设计:结果不注入上下文。工具故意只回传{ path, chars },避免大文档撑爆上下文窗口。这一点由输出 Schema 强制约束(见 builtinTools.ts),测试 cherryDocumentTools.test.ts 也验证了"转换结果不包含在工具返回值中"这一行为。
三、支持的输入格式
官方参考文档给出的支持矩阵如下:
| 类别 | 扩展名 |
|---|---|
| Word | .doc、.docx、.docm |
| PowerPoint | .ppt、.pps、.pot、.pptx、.pptm、.ppsx、.ppsm |
| Excel | .xls、.xlsx、.xlsm、.xlsb |
| OpenDocument | .odt、.ods、.odp |
| 其他 | .rtf、.epub、.csv、.pdf |
同一份清单在源码中以常量TO_MARKDOWN_SUPPORTED_EXTENSIONS定义,并内嵌进工具描述与参数说明中(见 builtinTools.ts)。
值得注意的格式识别细节:
- 内容优先、扩展名兜底:转换器会从文件内容识别可辨识的格式,识别失败时回退到扩展名判断;
- CSV 无文件签名:CSV 没有内容特征可用于识别,因此必须使用
.csv扩展名才能被正确路由; - 单参数约束:工具目前只接受
path一个必填参数,不接受输出路径、格式覆盖、页码范围、密码或 OCR 选项——格式判断完全交由转换器自主决定。
四、参数与返回契约
path参数的 Schema 约束(见 builtinTools.ts):
- 字符串类型,调用前会
trim(); - 最小长度 1(非空);
- 最大长度 4096 字符;
- 语义:相对路径从会话工作区解析;绝对路径必须是本会话已公布的附件或位于 agent 数据目录之下。
返回值 Schema(toMarkdownOutputSchema):
{ "path": "绝对路径:转换出的临时 Markdown 文件,需要时按切片读取", "chars": "写入 Markdown 文件的字符数(非负整数)" }chars对应源码中markdown.length,即转换结果去除首尾空白后的字符数,可用于让 Agent 判断文件规模、决定切片读取策略。
五、路径授权与安全边界
该工具无需审批(auto-approved),因此越权路径必须在转换发生前被拦截。源码中的授权逻辑(cherryDocumentTools.ts 的resolveDocumentSource)定义了三个可信根:
- 会话工作区:相对路径或落在工作区内的绝对路径,通过 WorkspaceFileGuard.ts 的
resolveWorkspaceFile解析——它先用realpath规范化目标路径,再校验其是否仍位于工作区根之内,从而挫败..相对遍历与符号链接逃逸; - Agent 数据目录:Agent 自己下载或生成的文档所在目录(
agentDataPath),通过isSameOrInside做包含性校验(见 path.ts); - 本会话附件:仅限本会话公布的托管文件——授权采用精确物理路径匹配,而不是父目录匹配。测试用例验证了"与已授权附件共享父目录的兄弟文件不会被授权"这一边界(见 cherryDocumentTools.test.ts)。
除路径外,还有两道硬约束:
- 常规文件:源必须是可读的常规文件(
lstat校验,目录等特殊文件被拒绝); - 大小限制:源文件不得超过工具的字节上限。源码中
MAX_FILE_SIZE_BYTES = 100 * MB(见 downloadAsBase64.ts),且在读取前(stat)与读取后(实际字节数)双重校验,防止"文件在读取间隙被替换/增长"绕过限制(见 localFileResolver.ts)。
六、临时输出管理:agent 私有目录与 24 小时清理
转换结果统一写入<agentDataPath>/tmp/to-markdown/目录,文件名是随机 UUID,避免与其他会话产物冲突;wx创建标志保证不覆盖已存在文件。源码中的cleanupStaleOutputs会在每次转换时清理超过 24 小时(OUTPUT_MAX_AGE_MS = 24 * 60 * 60 * 1000)未修改的.md临时文件,只清理该目录内的 Markdown 文件、不影响近期产物。测试用例("removes stale Markdown outputs while preserving recent files")用 25 小时前的旧文件验证了这一行为。
对 Agent 的实操含义:临时文件是"私有且会过期"的,需要长期保留的内容应复制到用户要求的最终路径;读取时应按切片进行,而不是一次性载入全文。
七、恢复策略与已知限制
官方参考文档给出了明确的故障处理矩阵,每一条都对应可验证的源码行为:
| 情况 | 处理方式 |
|---|---|
| 工具不可用 | 本会话的文档转换能力不可用,不要在用户不知情的情况下安装或调用替代转换器 |
| 不支持或不可读的文件 | 报告转换器错误,不要通过npm、bun x、npx、直接mise、远程安装器或手动下载的二进制重试 |
| 空输出 | 报告"未产生任何文本",绝不能将其包装成一次成功的转换——源码中空结果会抛出Document conversion produced no text,且不会落盘(测试用例已覆盖) |
| 扫描版/纯图片 PDF | 需要 OCR,而本工具不提供OCR;应如实告知用户,另行选择具备 OCR 的路径 |
| Windows ARM64 | 上游(@firecrawl/anydoc)目前未发布该平台的原生绑定,因此转换在该平台不可用(仓库中亦有对应注释佐证,见 fileExtensions.ts) |
此外,工具错误会以Error: <message>文本形式返回并标记isError,Agent 应当读取报错信息修正调用,而不是盲目重试相同参数;转换过程也尊重 AbortSignal,可被会话取消。
八、实战示例:总结一份 PPT
官方参考文档给出了最典型的使用场景——"Summarizereports/q3-review.pptx"。完整执行序列如下:
- 调用
mcp__cherry-tools__to_markdown,参数path: "reports/q3-review.pptx"(相对会话工作区的路径); - 拿到返回的临时 Markdown 绝对路径与字符数;
- 用普通文件工具对返回路径按切片读取或搜索相关章节;
- 基于切片内容完成总结并回复用户。
过程中不要安装独立的文档转换 CLI,也不要把完整 Markdown 一次性加载进模型上下文——前者违反"不绕行安装"原则,后者会无谓消耗上下文窗口。
九、源码级调用链与验证
从工具名到最终落盘,完整调用链为:
mcp__cherry-tools__to_markdown → CherryBuiltinToolsServer(MCP 分发,见 cherryBuiltinTools.ts) → CherryDocumentTools.call(参数校验、路径鉴权,见 cherryDocumentTools.ts) → resolveWorkspaceFile / resolveLocalFile(realpath 防逃逸 + 大小校验) → @firecrawl/anydoc 的 formatFromExtension + toMarkdownBytes(格式识别与转换) → 写入 <agentDataPath>/tmp/to-markdown/<uuid>.md → 返回 { path, chars }针对该工具的单元测试(cherryDocumentTools.test.ts)系统验证了以下行为:结果不含文档内容、工作区外绝对路径被拒、../遍历与符号链接逃逸被拒、本会话附件可转换、非本会话附件被拒、agent 数据目录内文件可转换、超限文件被拒、空输出报错且不落盘、24 小时过期清理。这些测试即是最佳的行为契约文档。
十、与知识库文件处理的区别(避免混淆)
仓库中还存在另一条"文档转 Markdown"路径——知识库的文件处理流程(如 localDocument 处理器),它面向已入库的 PDF 文件,且仅路由 PDF(knowledgeFileProcessingExts = ['.pdf'],见 fileExtensions.ts),包含本地 OCR 回退(PaddleOCR)等更重的处理能力。但这条路径属于知识库索引侧,不暴露为本文所述的 MCP 工具;to_markdown面向的是会话内任意受支持的本地文档,两者是不同入口、不同授权模型,切勿混用。
结语
mcp__cherry-tools__to_markdown是 Cherry Studio Agent 会话中处理本地办公文档的标准入口:单参数、格式自动识别、结果落盘而非注入上下文、三类可信根严格鉴权、24 小时临时文件治理,配合明确的恢复策略,构成一套安全、克制、可预测的文档转换能力。结合本文的源码佐证与测试契约,Agent 与开发者都可以放心地在会话工作流中编排这一工具,而不会触及知识库索引或 Shell 执行等相邻边界。
【免费下载链接】cherry-studio🍒 Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端项目地址: https://gitcode.com/CherryHQ/cherry-studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考