n8n-mcp 实战指南:深入理解 n8n `$binary` 插槽——从槽位结构到文件大小限制
n8n-mcp 实战指南深入理解 n8n$binary插槽——从槽位结构到文件大小限制【免费下载链接】n8n-mcpA MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you项目地址: https://gitcode.com/GitHub_Trending/n8/n8n-mcp导读在 n8n 中文件PDF、图片、压缩包从不直接存放在$json里而是由每个 item 上的$binary插槽承载——数据走$json文件走$binary二者并行且互不干扰。本文以 n8n-mcp 仓库的 BINARY_BASICS.md 为核心系统讲解$binary插槽的完整形态、哪些节点产出/消费二进制、在 Code 节点中如何读写字节、mime 类型契约、文件大小上限与执行过程排查方法。读完你将掌握文件在 n8n 里到底存在哪、如何确保它活着到达消费节点的完整技术链路。一、插槽形态$json与$binary是互不相通的双轨n8n 中每一个 item 都有两个顶层键json存放结构化数据binary存放文件字节。两者相互独立——一个只改写json的转换节点不会自动携带binary反之亦然。这是 n8n 二进制处理的第一性原理也是 90% 二进制 bug 的根源该原则在 SKILL.md 中被总结为三条铁律之一文件内容在$binary不在$json。一个典型 item 的完整形状如下来自原文档{ json: { customerId: 42, status: sent }, binary: { invoice: { data: base64-encoded bytes, mimeType: application/pdf, fileName: invoice-42.pdf, fileExtension: pdf, fileSize: 12 kB } } }1.1 二进制属性名binary property namebinary内部的键——这里的invoice——就是二进制属性名binary property name。它可以是任意字符串data是大多数节点的默认名。文件处理类节点会暴露一个binaryPropertyName参数来指向这个键生产者命名插槽消费者按这个名字引用它。如果消费者端的名字写错它就会去找一个不存在的插槽——文件悄悄消失的经典原因。1.2 四个关键字段字段含义data字节内容Base64 编码mimeType消费者应如何解释这些字节application/pdf、image/png……fileName用于邮件附件、上传、下载到磁盘等场景fileExtension通常由fileName推导部分节点直接使用它表达式视角$json和$binary是两个独立的命名空间{{ $binary.invoice.fileName }}读文件元数据{{ $json.customerId }}读数据二者永不混用详见 SKILL.md。二、哪些节点产出二进制Producer几乎不需要手工拼装插槽——节点会帮你填充它节点要设置什么结果HTTP RequestresponseFormat: file响应体进入$binary.data或options中指定的名字Read/Write Files from Disk读取文件路径文件内容进入$binaryS3 / Google Drive / Dropbox下载文件引用下载的文件进入$binary.key邮件触发器IMAP、Gmail trigger开启附件处理每个附件进入$binaryProvider AI 媒体节点图像/音频生成options.binaryPropertyOutput生成字节落入指定名字的插槽2.1 最常见的下载 bugHTTP Request 忘了responseFormat: file如果 HTTP Request 保持默认的响应格式n8n 会尝试把响应体当作 JSON 或文本解析——最终你得到的是$json里一段损坏的乱码字符串而不是$binary里干净的字节。仓库中 enhanced-config-validator.ts 也印证了这一点校验器会主动建议 API 端点显式设置options.response.response.responseFormat并给出示例补丁{ options: { response: { response: { responseFormat: json } } } }不同 n8n 版本的响应处理选项位于不同的结构之下务必用get_node查询nodes-base.httpRequest确认当前版本的真实字段名这条建议同样适用于下文所有字段名随版本漂移的参数。2.2 Provider AI 节点的隐藏开关图像生成、文本转语音等 Provider AI 节点是另一个反复出现的坑很多节点不显式设置options.binaryPropertyOutput就不会产出二进制。不设这个开关下一个节点就没有任何东西可以上传。补充说明仓库的 example-generator.ts 在生成 FTP 上传示例时也使用了同族参数binaryData: truebinaryPropertyName: data——启用二进制 指定属性名这一组合是 n8n 各节点上传文件的通用约定。三、哪些节点消费二进制Consumer消费者通过属性名引用插槽节点如何引用二进制EmailSend附件字段指向binaryPropertyNameSlack发送文件引用二进制属性HTTP Requestmultipart/form-data在 body 参数中引用二进制存储上传S3、R2、Drive把二进制作为请求体引用Write Files to Disk把命名的二进制属性写入某个路径模式永远一致生产者命名属性消费者指向这个名字。绝大多数文件没附上的 bug 都是两端属性名不匹配——请同时用get_node核对两端字段并检查执行记录验证。四、在 Code 节点中读取二进制大多数工作流根本不需要读字节——直接把二进制透传给消费者即可。当确实需要字节哈希、解析、文本提取时在 Code 节点中使用getBinaryDataBuffer不要自己取$binary.key.data再做 base64 解码——这个辅助方法会替你处理 n8n 的存储模式内存 vs 文件系统// Code 节点执行模式 Run Once for Each Item const buffer await this.helpers.getBinaryDataBuffer(0, data); // (itemIndex, propertyName) const text buffer.toString(utf-8); // 仅适用于文本类文件 const length buffer.length; return [{ json: { ...$json, length }, binary: $input.item.binary, // ← 透传文件否则经过此节点后文件就丢了 }];getBinaryDataBuffer(itemIndex, propertyName)返回一个 NodeBuffer可以像普通 Buffer 一样切片、哈希、解码。语言层面的细节可用辅助方法、执行模式、$input与$json的区别属于n8n-code-javascript技能二进制相关的唯一铁律就是上面注释里的那句如果返回对象里不带binary文件就会在这个节点被丢弃。仓库测试 node-specific-validators.test.ts 中也出现了this.helpers.getBinaryDataBuffer(0, data)的用法可作为该 API 在真实代码中签名itemIndex, propertyName的佐证。PDF 文本提取警告buffer.toString(utf-8)对 PDF 无效——PDF 是二进制容器而非 UTF-8 文本。你需要在有解析库的环境里做真正的解析OCR/提取节点或专用库。Buffer 给你的是字节把字节变成可读文本是另一个独立问题。五、在 Code 节点中写入二进制自己构建插槽把字节做 base64再补上 mime 类型和文件名消费者才知道自己拿到的是什么const text Hello, world!; return [{ json: { ok: true }, binary: { report: { data: Buffer.from(text).toString(base64), mimeType: text/plain, fileName: report.txt, fileExtension: txt, }, }, }];不要省略mimeType——否则下游消费者可能拒绝文件或渲染错误邮件附件不干净Slack 显示通用文件图标而不是内联图片。务必总是设置它。六、Mime 类型生产者与消费者之间的契约mimeType是生产者与消费者之间的契约。一个错误的值不会报错——它只会让消费者行为异常拒绝附件、把内联渲染变成下载、或显示损坏的缩略图。文件类型Mime 类型PDFapplication/pdfPNGimage/pngJPEGimage/jpeg纯文本text/plainJSONapplication/jsonCSVtext/csvXLSXapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheetZIPapplication/zip当来源不告知类型时可以从文件头字节嗅探PDF 以%PDF-开头、PNG 以\x89PNG开头、JPEG 以\xFF\xD8\xFF开头。在 Code 节点里写几行魔数magic bytes检查是无法信任上游元数据时的可靠兜底方案。七、文件大小上限与外部存储卸载策略执行数据存储在 n8n 的数据库中巨大的 base64 块会撑大数据库并拖慢实例。粗略指导每个插槽的大小结论几 MB没问题几十 MB可用但更慢留意实例内存100 MB卸载到外部存储只传递 URL/ID对大文件的推荐模式是字节一产生就上传到对象存储把 URL 或 key 作为纯 JSON 在工作流中传递只在真正需要字节的那个节点重新拉取。这样每个 item 的负载都很小执行也快。如果自托管实例使用文件系统二进制数据模式而非内存模式数据库压力会小一些但对真正的大文件同样的卸载建议依然成立。这与 SKILL.md 中避免在 Code 节点硬编码 base64的反模式一脉相承硬编码会造成巨大的工作流 JSON、运行缓慢且易泄露。八、在执行记录中检查二进制是否存活validate_workflow不会告诉你二进制是否在某个节点幸存——插槽被丢弃是一种静默失败。唯一可靠的检查方法是看执行记录本身运行工作流n8n_test_workflow或真实触发。用n8n_executions拉取执行记录查看每个节点输出中的binary插槽。即使 base64 太大无法完整渲染插槽也会显示存在性与元数据名称、mime 类型、大小。你要检查的就是它在每个节点上的存在与否。binary最后一次出现、紧接着在下一节点消失的位置正是需要加透传或 Merge 的地方具体模式见 MERGE_FOR_CONTEXT.md。九、当二进制是触发器输入时对于接收文件的工作流——multipart webhook 上传、邮件附件、被监听的文件夹——二进制在触发器输出处到达从触发器开始就按它的二进制属性名引用。在每个需要它的下游节点透传每个节点都可能成为剥落点。如果二进制没有出现在触发器输出处检查两点Content-type 处理接收multipart/form-data的 Webhook 会把文件放进$binary、把表单字段放进$json.body接收 JSON 的 Webhook 则完全没有二进制。$json.body的表达式细节属于n8n-expression-syntax。触发器的二进制设置有些触发器除非显式告知否则会跳过附件下载。十、把二进制带过 JSON 转换Merge 兜底与透传二进制最容易丢失的地方是JSON-only 节点Edit Fields、Code、IF——它们可能从输出中丢弃$binary插槽而工作流校验照常通过、运行无报错只是下游邮件节点要附件时文件已经不在了。两种保留方式详见 MERGE_FOR_CONTEXT.md转换节点的透传选项Edit Fields 开启includeOtherFieldsCode 节点显式返回binary: $input.item.binary。有现成选项时这是最便宜的修复。扇出 按位置合并把源同时路由进转换分支和旁路分支再用combineByPosition模式的 Merge 重新组合。JSON 来自转换侧二进制在旁路侧原样幸存[Source with binary] ─┬─→ [Edit Fields: change JSON] ─┐ │ (binary stripped here) │ │ ├─→ [Merge: combineByPosition] ─→ [Email: attach] │ │ └──────────────────────────────────┘ (bypass — binary passes through untouched)用 n8n-mcp 的n8n_update_partial_workflow接线时combineByPosition会按位置把输入 1 的第 N 个 item 与输入 2 的第 N 个 item 配对因此两条分支的 item 顺序与数量必须对齐。注意两个容易踩的细节Merge 默认只有2 个输入接 3 分支必须调高输入数否则多余分支被静默丢弃连接输入索引是0 基的旁路分支落在targetInput: 1。Merge 的字段名mode、combineBy、numberOfInputs在不同版本间有变动提交结构前用get_node核对nodes-base.merge。如果剥落点太多逐个 Merge 的成本会超过收益此时更优解是尽早上传字节一出现就上传对象存储URL/key 作为纯 JSON 穿越所有转换只在需要的节点重新拉取或把二进制工作推入子工作流注意 Execute Workflow Trigger 默认的 typed-input 模式只携带命名 JSON 字段、会丢弃$binary子工作流需要直接收字节时要用 passthrough 输入模式。结语从插槽形态到消费节点、从 Code 节点读写到 mime 契约、从大小限制到执行排查$binary的完整链路其实只有一条主线生产者命名、消费者引用、转换节点透传、执行记录验证。记住两句话即可覆盖绝大多数场景——文件内容永远在$binary而不在$json任何只返回json的节点都在默默丢弃文件。更进一步的边界场景Agent 工具只能走 JSON、聊天界面必须用 URL 渲染图片可继续阅读同技能目录下的 AGENT_TOOL_BINARY.md 与 CDN_REQUIREMENT.md。【免费下载链接】n8n-mcpA MCP for Claude Desktop / Claude Code / Windsurf / Cursor to build n8n workflows for you项目地址: https://gitcode.com/GitHub_Trending/n8/n8n-mcp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考