mcpField
N
n8n-binary-and-data

n8n-binary-and-data

github.com/czlonkowskiデータ・データベース6.5k1.9k 回インストール4 日前に更新
リポジトリ

n8n-binary-and-data について

n8n のワークフロー構築者向けに、`$json` と `$binary` の役割の違いや、AI エージェントのツール境界をバイナリが通過できない理由を説明するスキルです。ファイルの保持、ストレージキーや URL による受け渡し、チャットでの画像表示の方法を扱います。

主な機能

  1. 01`$json` と `$binary` の区別
  2. 02バイナリデータの読み書き
  3. 03変換時のファイル消失防止
  4. 04ストレージ経由のエージェント連携
  5. 05URL によるチャット画像表示

活用シーン

  1. 01ダウンロード先フィールドの調査
  2. 02データ変換後の添付ファイル保持
  3. 03アップロードファイルのツール処理
  4. 04生成画像のチャット表示

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/czlonkowski/n8n-skills --skill n8n-binary-and-data

インストール後、Claude Code で/n8n-binary-and-dataを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

AGENT_TOOL_BINARY.md
BINARY_BASICS.md
CDN_REQUIREMENT.md
MERGE_FOR_CONTEXT.md
README.md

詳細

n8n のバイナリデータとデータ

n8n の各アイテムには、構造化データ用の $json とファイルのバイトデータ用の $binary という、独立した2つの領域があります。この2つはワークフロー内を並行して流れます。ファイルの内容、つまり実際の PDF、画像、zip は $binary に格納され、$json には格納されません。この区別を誤ると、空のフィールドを読み込んだり、フローの途中でファイルを失ったり、AI エージェントに使用できないツール入力を渡したりすることになります。

このスキルでは、バイナリデータの格納場所、読み書きの方法、気付かないうちに削除されないようにする方法、バイナリデータと AI エージェントのツール境界の厳格な分離、そしてチャット画面で生のバイトデータではなく URL が必要な理由を説明します。


バイナリデータのバグの90%を防ぐ3つのルール

  1. ファイルの内容は $json ではなく $binary にあります。 HTTP ダウンロード、「Read Files」、またはメール添付ファイルのトリガーの後、バイトデータは $binary.<key> に格納されます。$json に格納されるのは、あってもメタデータだけです。ファイルの内容を取得するために $json.data を読み込んでも、何も得られません。

  2. バイナリデータは、どちらの方向にも AI エージェントのツール境界を越えられません。 ツールの引数と戻り値は JSON のみです。アップロードされた画像をファイルとしてツールに渡すことはできず、ツールから生のバイトデータを返すこともできません。ストレージに事前に保存し、代わりにキーまたは URL を JSON 経由で渡してください。AGENT_TOOL_BINARY.md を参照してください。

  3. チャット画面では、画像は $binary ではなく URL で表示されます。 Slack、Discord、Teams、Telegram、埋め込み型の Webhook チャットはいずれも、バイナリ領域を読み取りません。画像は URL から取得できる場所に保存する必要があります。CDN_REQUIREMENT.md を参照してください。


2つの領域

各アイテムは次のような構造です。

{
  "json": { "customerId": 42, "status": "sent" },
  "binary": {
    "invoice": {
      "data": "<base64-encoded bytes>",
      "mimeType": "application/pdf",
      "fileName": "invoice-42.pdf",
      "fileExtension": "pdf"
    }
  }
}

binary 内のキー(ここでは invoice)がバイナリプロパティ名です。ほとんどのファイル処理ノードには、その名前を指定する binaryPropertyName パラメーターがあります。生成側が領域に名前を付け、処理側がその名前で参照します。ほとんどのノードでは既定のキーが data なので、別の指定がなければ $binary.data と考えてください。

$json と $binary は別々の名前空間です。{{ $binary.invoice.fileName }} のような式はファイルのメタデータを読み込み、{{ $json.customerId }} はデータを読み込みます。この2つが混ざることはありません。

この区別は、Webhook に関する注意点も説明しています。multipart/form-data を受信した Webhook トリガーでは、アップロードされたファイルは $binary に、付随するフォームフィールドは $json.body に格納されます。つまり、アップロードされたファイルは $json の下にはありません。(Webhook の $json.body というネスト構造は n8n-expression-syntax の領域です。)

領域の構造、MIME タイプ、サイズ制限の詳細については BINARY_BASICS.md を参照してください。


バイナリデータの生成

$binary の領域を手動で作成することはほとんどありません。ノードが自動で設定します。

入力元バイナリデータの格納方法
responseFormat: "file" を指定した HTTP Requestレスポンス本文が $binary.data(または指定した名前)に格納されます
Read/Write Files from Disk読み込んだファイルの内容が $binary に格納されます
ストレージからのダウンロード(S3、Google Drive、Dropbox など)ダウンロードしたファイルが $binary.<key> に格納されます
添付ファイル付きのメールトリガー各添付ファイルが $binary に格納されます
プロバイダーの AI メディアノード(画像/音声の生成)options.binaryPropertyOutput を設定して、後続ノードが参照する場所にバイトデータを格納します

HTTP でダウンロードする場合、重要なのは responseFormat の1つのフィールドです。nodes-base.httpRequest に対して get_node を実行して確認してください。既定の JSON/文字列形式のままにしておくと、ダウンロードしたファイルが $binary にきれいなバイトデータとしてではなく、$json に文字化けしたテキストとして格納されるのが典型的な原因です。


Code ノードでのバイナリの読み書き

ほとんどのワークフローでは、バイト列を直接扱う必要はありません。メールの添付ファイル、ファイルのアップロード、Slack のファイルなど、通常はそのまま利用先に渡します。多くのバイト処理には、ネイティブノードがあります。Extract From File(CSV、XLSX、PDF のテキスト、JSON、プレーンテキスト → アイテムまたはフィールド)、Convert To File(アイテム → CSV/XLSX/JSON/テキストファイル)、Crypto(binaryData: true でファイルをハッシュ化)、Compression(zip/gzip)です。対応するノードがない形式の場合に限り、Code ノードで生のバイト列を読み書きし、「Why Code:」の注記を付けてください。

読み取りには getBinaryDataBuffer を使います。$binary.<key>.data を手作業で base64 デコードしないでください。

// Code node, "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,   // pass the binary through, or it's gone
}];

書き込みはスロットを自分で作成します。バイト列を 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',
    },
  },
}];

Code ノードのサンドボックス、ヘルパー、実行モードについては、n8n-code-javascript(および n8n-code-python)が扱います。言語レベルの詳細には、そちらを参照してください。ここで覚えておくべきバイナリ固有の点は、[{ json: {...} }] を返す Code ノードは、binary を再度付与しないと ファイルを通知なく破棄することです。BINARY_BASICS.md を参照してください。


変換処理の途中でバイナリを維持する

Edit Fields(Set)、Code、IF など、JSON のみを扱うノードは、出力から $binary スロットを削除することがあります。ワークフローは正常と検証され、エラーなく実行されますが、メールノードが添付しようとした時点で、後続の処理にファイルが存在しません。

維持する方法は 2 つあります。

  • 変換ノードのパススルーオプションを使う。 Edit Fields には includeOtherFields があり、Code ノードは binary: $input.item.binary を明示的に返せます。利用できる場合は、これが最も手軽な修正方法です。
  • 分岐させて、位置で Merge する。 ソースを変換側とバイパス側の両方にルーティングし、combineByPosition モードの Merge で再結合します。JSON は変換側から取得し、バイナリはバイパス側で維持します。
[Source with binary] ─┬─→ [Edit Fields: change JSON] ─┐
                      │      (binary stripped here)     ├─→ [Merge: combineByPosition] ─→ [Email: attach]
                      └──────────────────────────────────┘
                          (bypass — binary passes through untouched)

combineByPosition は各入力の N 番目のアイテム同士を組み合わせるため、フィールド数を揃える必要があります。接続の配線方法と、多数の処理を経由するチェーンでの代替案(早めのアップロード、サブワークフロー)については、MERGE_FOR_CONTEXT.md を参照してください。


エージェントツールにおけるバイナリの境界

ここが最も注意すべき点です。AI Agent は JSON を介してツール(Custom Code Tool、Call n8n Workflow Tool、HTTP Request Tool、MCP tools)とやり取りします。この経路では、どちらの方向でもバイナリを渡せません。どちらの場合も解決方法は同じです。バイト列をストレージに一時保存し、JSON 経由でキーまたは URL を渡して、受け取り側で取得します。

受信 — エージェントのツールで処理するファイルをユーザーがアップロードする場合:

  1. チャットトリガーから files[] 配列を受け取ります。ファイルを分割し、それぞれをハッシュ化したキーでプライベートストレージにアップロードします。
  2. エージェントの実行前に、その分岐を再結合します(これは同期バリアであり、飾りではありません)。N 個のファイルによってエージェントが N 回実行されないよう、エージェントに executeOnce: true を設定します。
  3. エージェントのシステムプロンプトにキーを挿入し、元の名前(人間が文脈を把握するため)とストレージキー(ツールが必要とするもの)の両方を記載したうえで、「このキーを正確に使用する」と明示します。
  4. ツールはキーを文字列引数として受け取り、ストレージからファイルをダウンロードします。

送信 — ツールがエージェントから返すファイルを生成する場合:

  1. ツールのサブワークフローでバイナリを生成し、ストレージにアップロードして、{ "ok": true, "key": "...", "url": "https://...", "mimeType": "image/png" } のような JSON を返します。
  2. エージェントは返信に URL を埋め込むか、別のツールにキーを渡します。

エージェントの passthroughBinaryImages: true は、ビジョン機能で LLM が見る内容を変えるだけです。ツールがファイルを受け取れるようにはなりません。また、対象は画像のみで、PDF、音声、動画には対応しません。どのツールにも、引き続きアップロードしてキーを渡すパターンが必要です。パターンの全容、ハッシュ戦略、ストレージの選択肢、長時間実行ツール向けの方法については、AGENT_TOOL_BINARY.md を参照してください。

ツール自体を構築していますか?Custom Code Tool の契約については n8n-code-tool を、AI Agent とツールを組み合わせる構成については n8n-workflow-patterns を参照してください。

チャット画面でのCDN要件

ワークフローで画像を生成し、ユーザーがチャットメッセージ内に表示したい場合:

  • アイテムにバイナリがあるだけでは不十分です。 チャットクライアントは、URLで画像を参照するメッセージをレンダリングするか、プラットフォーム独自のファイルアップロードAPIを通じてバイト列を送信します。$binary を読み取ることはありません。
  • バイト列は、HTTPS経由でURLから取得できる場所に保存する必要があります。 まずオブジェクトストアまたはドライブにアップロードし、返されたURLを埋め込みます。
  • n8nには組み込みのCDNがありません。 ストレージはユーザーが用意します。

S3を前提にせず、すでに利用しているストレージを尋ねてください。オブジェクトストレージ(S3、R2、GCS、Azure Blob、Backblaze B2、Supabase Storage)とドライブ型サービス(Dropbox、Google Drive、OneDrive、Box)はどれも利用できますが、URLの形式はサービスによって異なります。まだストレージがない場合は、Cloudflare R2が最も手軽な出発点です。機密性の高いコンテンツには、恒久的に公開するURLではなく、有効期限付きの署名付きURLを使用してください。CDN_REQUIREMENT.md を参照してください。


利用できない機能

  • $fromAI() ではバイナリを渡せません。 ツールのパラメーターに設定できるのは、文字列、数値、ブール値、オブジェクトです。ファイルのバイト列は渡せません。代わりにストレージキーを渡してください。
  • ツールの引数と戻り値はJSONのみです。 エージェントツールには、入力にも出力にも「バイナリパラメーター」はありません。
  • n8nにはCDNも、公開ファイルホストもありません。 URL経由でのファイル配信は常にユーザーのストレージが担い、n8nは担いません。
  • getBinaryDataBuffer はCodeノード用のヘルパーです。 Custom Code Toolのサンドボックスでは利用できません(n8n-code-tool を参照)。

Data Tablesの保存場所

ステージングしたファイルの参照カウント、使用中のキーの追跡、重複排除など、永続的な表形式ストレージには、n8n-mcp-tools-expert が管理する n8n_manage_datatable サーフェスを使用します。このスキルではData Tablesを扱いません。


アンチパターン

アンチパターン問題点修正方法
$json からファイルの内容を読み取るバイト列は $binary に保存されます。$json は空か、メタデータのみです$binary.<key> から読み取るか、Codeノードで getBinaryDataBuffer を使用します
responseFormat: "file" を指定せずにHTTPでダウンロードするバイト列がクリーンなバイナリではなく、加工されたテキストとして $json に届きますHTTP Requestノードで responseFormat: "file" を設定します
Codeノードが [{json:{...}}] を返し、binary を含めないファイルが後続の処理で気付かれないまま失われます戻り値で binary: $input.item.binary を再度付与します
JSON変換(Edit Fields/IF)でバイナリが失われるEmail/Uploadノードで添付するものが見つかりませんパススルーオプションを使うか、分岐させてMerge by positionでマージします
アップロードしたファイルを $fromAI でツールに渡す$fromAI ではバイナリを渡せないため、ツールには何も届きません事前にストレージへ配置し、システムプロンプトにキーを挿入して、ツールがキーで取得するようにします
passthroughBinaryImages を使えばツールがファイルを参照できると思い込むこれはLLMに見える内容にのみ影響し、しかも画像だけが対象ですツールには引き続き、アップロードしてキーを渡すパターンが必要です
ツールが生のバイナリをエージェントに返すツールの出力はJSONです。バイト列は保持されず、コンテキストも膨らみますアップロードし、JSONで { key, url } を返します
$binary をチャット画面に投稿すれば画像が表示されると思い込むチャットクライアントは生のバイト列ではなく、URLを使ってレンダリングしますストレージ/CDNにアップロードし、URLを埋め込むか、プラットフォームのファイルAPIを使用します
Codeノードにbase64をハードコードするワークフローJSONが巨大になり、処理が遅くなり、情報漏えいの危険も生じます$binary で参照するか、アップロードしてURLで参照します

参考ファイル

ファイル読むタイミング
BINARY_BASICS.mdバイナリを初めて扱う場合、または $binary スロット、MIMEタイプ、サイズ制限を読み書きする場合
AGENT_TOOL_BINARY.mdエージェントツールでアップロードしたファイルを使う場合、またはファイルを生成する場合。いずれの方向にも適用される境界について
MERGE_FOR_CONTEXT.mdJSON変換後にバイナリが失われ、再度付与する必要がある場合
CDN_REQUIREMENT.mdチャット画面や、URLで画像を参照する必要のある場所に画像を表示する場合

他のスキルとの連携

n8n-code-javascript / n8n-code-python: Code ノードは、生のバイトデータを読み書きする場所です(getBinaryDataBuffer、Buffer.from(...).toString('base64'))。これらのスキルでは、サンドボックス、ヘルパー、実行モードの詳細を扱います。このスキルでは、返すときにバイナリを再度アタッチする必要があるというルールを扱います。

n8n-code-tool: Custom Code Tool のサンドボックスは、さらに制限されています。$binary、getBinaryDataBuffer、$fromAI は使えません。ツールでファイルが必要な場合は、このスキルのストレージキーのパターンを使って取得します。

n8n-workflow-patterns: エージェントツールのバイナリ境界は、AI-Agent-with-tools パターンの中にあります。CDN フローは、生成 → アップロード → 返信の連鎖です。

n8n-node-configuration: responseFormat、binaryPropertyName、includeOtherFields、binaryPropertyOutput はすべて条件付きフィールドです。get_node を使って、ユーザーのバージョンでの正確な名前を確認してください。

n8n-expression-syntax: $binary.<key>.fileName と $json.body のどちらで参照するか(特に Webhook のアップロード)は、式に関する領域です。

n8n-validation-expert: バイナリスロットが破棄されても、エラーは表面化しません。validate_workflow では検出されないため、実行を調べて存在を確認してください。

n8n-mcp-tools-expert: n8n_manage_datatable(Data Tables)と n8n_executions を扱います。後者を使って、特定のノードを通過した後も binary スロットが残っていることを確認してください。

n8n-error-handling: ストレージへのアップロードとダウンロードは失敗することがあります。キーが見つからない場合に気付かないまま 404 にならないよう、受信側と送信側のステージング手順にエラーブランチが必要です。

using-n8n-mcp-skills: 各スキルの連携方法をまとめたインデックスです。


バイナリが残っていることの確認

検証では、バイナリスロットが削除されても検出されません。エラーが表面化しないため、正しく実行されたことを確認してください。

  1. n8n_test_workflow(または実際の実行をトリガー)で、実行データを生成します。
  2. n8n_executions でその実行データを取得し、ノードごとの出力を調べて binary スロットを確認します。base64 が大きすぎて表示できない場合でも、存在とメタデータは確認できます。
  3. binary が最後に現れるノードが、削除される直前のノードです。パススルーまたは Merge を追加するのはその場所です。

クイックリファレンスチェックリスト

  • ファイルの内容は $binary.<key> から読み取ること。$json は使わない
  • HTTP ダウンロードでは responseFormat: "file" を使う
  • ファイルを引き続き渡す必要がある場合、Code ノードは返すときに binary を再度アタッチする
  • JSON の変換では、バイナリをそのまま渡すか、Merge で再度結合する(combineByPosition)
  • バイナリをエージェントツールに渡したり、エージェントツールから受け取ったりしない。代わりに JSON 経由でキーや URL を渡す
  • passthroughBinaryImages は LLM のビジョン機能にのみ使用し、ツールとの受け渡しには使わない
  • チャット画面に表示する画像はストレージにアップロードし、バイトデータではなく URL を埋め込む
  • ストレージバックエンドはユーザーと相談して選ぶ(S3 をデフォルトにしない)。機密コンテンツには署名付き URL を使う
  • バイナリの有無は検証ではなく、実行データを調べて確認する

覚えておいてください: スロットは2つあり、並んでいます。データは $json に、ファイルは $binary に格納されます。ファイルをエージェントツールに渡す、またはチャット画面に表示する必要が生じた時点で、バイトデータではなく URL として渡します。

コメント