Movatterモバイル変換


[0]ホーム

URL:


Zenn
UPGRADE tech blogUPGRADE tech blog
UPGRADE tech blogPublicationへの投稿
💭

Dify×MCPを試してみた① Zapier編

に公開
2025/07/14

こんにちは、田中です。

今日のビジネス環境において、外部データソースをAPI経由で連携させる必要性はますます高まっています。しかし、これらのAPI連携を個別に実装し、連携ロジックをコードで管理するのは、開発工数、エラーハンドリング、メンテナンス性の観点から大きな負担となり得ます。

ここで注目されるのが、Managed Content/Capability Platform (MCP) という概念です。本記事では、このMCPがなぜ重要なのか、そしてLLMアプリケーション開発プラットフォームDifyとMCPを組み合わせることで、特に複数のAPI連携を伴う複雑なワークフローをいかに効率的に構築・管理できるようになるかを解説していきます。

MCPとは

MCPは、単なるコンテンツ管理システム(CMS)やナレッジベースを超えた概念です。LLMやエージェントが必要とする以下の二つの要素を一元的に管理し、制御された形で提供するためのプラットフォーム基盤と捉えることができます。

  1. コンテンツ (Content): 社内ドキュメント、データベース、Webサイトなど、LLMが参照・学習するための情報源。
  2. 機能・能力 (Capability): 外部APIの呼び出し、特定機能の実行、SaaSツールの操作など、LLMが現実世界に働きかけるための「ツール」。

MCPは、これらのコンテンツやツールへのアクセスを集約・抽象化し、LLMアプリケーション(例えばDifyで構築されたもの)に対して、管理・統制されたインターフェースを提供します。これにより、セキュリティの確保、アクセス制御、利用状況の監視、ツールの追加・更新の容易化といったメリットが生まれます。「MCPサーバー」として機能し、様々なツールやプラットフォーム間の連携を仲介するハブとなるイメージです。

Dify × MCP連携の真価:API連携における違い

Difyは単体でも、カスタムツールとしてAPIを登録し、ワークフロー内で利用する機能を持ちます。しかし、扱うAPIの種類や数が増え、連携ロジックが複雑化するにつれて、以下のような課題が生じやすいです。

  • ツール管理の煩雑化: 個々のAPIの仕様変更への追従、認証情報の管理、利用権限の設定などが個別に発生し、管理コストが増大する。
  • 再利用性の低下: 特定のワークフローのためだけにAPIツールを定義すると、他のワークフローでの再利用が難しい場合がある。
  • ガバナンスの欠如: 誰がどのAPIをどの程度の頻度で利用しているか、といった全体的な利用状況の把握や統制が難しい。

ここでMCPが真価を発揮します。Dify公式ブログでも紹介されているように、例えばZapierのようなAPI連携プラットフォームをMCPプラグイン経由でDifyに統合できます。これによりZapierに登録した多くのAPIからAIが自律的に用途に合ったAPIを選別して、指示を実行してくれます。

これは何を意味するのでしょうか? DifyはZapierと連携することで、個別のAPI設定をすることなく、Zapier経由で多様な外部サービスを操作できるようになります。

デモ

Dify×MCPの例で特に威力を発揮するケースが複数のAPI連携を行う際です。

ここではGoogle calendarで得た予定をGmailを使って送信するアプリをDifyとZapierというMCPサーバーを用いて作っていきます。

手順:

  1. まずはこちらからZapierのアカウントを作ります。

  2. アクセスしたサイトからGet startedを選択します。

  3. Googleアカウントなどから作成します。

  4. 作成するアカウントを選択したのちに以下のような質問が出てくるので答えていきます。

  5. 質問に答え終わると以下のようなページになるのでNew MCP Serverを選択してください。

  6. 以下のページになったらMCP ClientはOtherをNameには好きなものを入力して、Create MCP Serverを選択してください。

  7. Add toolを選択してください。

  8. 次にGoogle Calendarを選択してください。

  9. アクセスしたページのAdd all Google Calendar toolsを選択してください。

  10. 使用するGoogle calendarのgoogle accountを選択してください。

  11. Add all Google calendar toolsを選択します。

  12. もう一度Add toolsを選択します。

  13. Gmailを選択します。

  14. Add all Gmail toolsを選択します。

  15. 使用するGmail account を選択します。

  16. Add all Gmail toolsを選択します。

  17. 上の部分からConnectを選択します

  18. Server URLをコピーします

  19. 次にDifyにログインします。

    ※アカウントがない方は作ってください。

  20. アプリを作成する→最初から作成するを選択します。

  21. アプリの種類→チャットフローとする。

    アプリのアイコンと名前はなんでもよい。

  22. その後作成するを選択する。

  23. LLMを削除します。

  24. 開始のブロックのプラスボタンを選択してエージェントを選択します。

  25. エージェントノードのプラスボタンからもう一つエージェントノードを追加します。

  26. 二つ目のエージェントノード(エージェント2)の+ボタンから線を引っ張り、回答ブロックと接続します。

  27. 回答ブロックの応答にはLLMブロック/textが指定されているので削除して、エージェント2/textを指定します。

  28. 次にエージェントのエージェンティック戦略をMCP AgentのMCP Function Callingにします。

    ※まだMCP Agentをインストールしていない場合は以下の手順でMCP Agentをインストールしてください。

    1. 「マーケットプレイスでさらに見つけてください」を選択します。

    2. MCP Agent Strategyを選択します。

    3. インストールします。

  29. Modelを選択する。

    ※なんでもよいです。

  30. Tools Listは

    Current Time→Current Time

    Current Time→Weekday Calculator を選択します。

  31. Current Timeにおいては設定からTimezoneをTokyoにしてください。

  32. 次に右上のENVと書かれているボタンを押し、環境変数を設定します。

  33. 環境変数の追加から

    タイプはString

    変数名はなんでもよい

    値にはZapierからコピーしたURLを張り付けます。

  34. エージェントのMCP SERVER URLに先ほど設定した変数を設定します。

  35. Instructionには以下のものコピペします。

    Userの指示に従い適切なツールを使用してください。今日の日付を取得する際には、CurrentTimeを使ってください。昨日や明日や明後日などの日付を取得する際にはCurrentTimeから計算を行い取得してください。曜日について指示があった際にはWeekday Calculatorを用いて計算してください。予定について尋ねられた際にはzapier_mcpから得られるGoogle Calendar情報を用いて予定を取得してください。日付を指定されている場合その日以外の予定は送信しないでください。予定についてはカレンダーに書いている情報以外は書かないでください。送信は行わなくてよいです。出力は質問内容への解答だけでいいです。
  36. QUERYにはsys.queryを選択します。

  37. 今度はエージェント2について設定を行います。

    設定に関しては以下の値をそれぞれ入れます。

    ※instructionについては後述

    ※QUERYのところはエージェント/textが入っていることに注意

  38. エージェント2のinstructionについては以下のように入力してください

    送信してと言われたらエージェント/textをそのままGmailを使って指定された宛先に送信してください。許可を取る必要はないです。
  39. 右上の公開を押す。

  40. アプリを実行を選択する。

  41. チャットに依頼内容を打ち込むと以下のようになります。

  42. 送られたメールは以下のようになります。

実際のDSLファイルはこのようになります
app: description: '' icon: 🤖 icon_background: '#FFEAD5' mode: advanced-chat name: mcp_demo use_icon_as_answer_icon: falsedependencies: []kind: appversion: 0.2.0workflow: conversation_variables: [] environment_variables: - description: ''   id: 7ac3986c-cb91-4fe5-a807-884755e0b871   name: MCP_Zapier   selector:   - env   - MCP_Zapier   value: https://actions.zapier.com/mcp/sk-ak-BwksCWdZ9W0ng10pHIkNJBRzOx/sse   value_type: string features:   file_upload:     allowed_file_extensions:     - .JPG     - .JPEG     - .PNG     - .GIF     - .WEBP     - .SVG     allowed_file_types:     - image     allowed_file_upload_methods:     - local_file     - remote_url     enabled: false     fileUploadConfig:       audio_file_size_limit: 50       batch_count_limit: 5       file_size_limit: 15       image_file_size_limit: 10       video_file_size_limit: 100       workflow_file_upload_limit: 10     image:       enabled: false       number_limits: 3       transfer_methods:       - local_file       - remote_url     number_limits: 3   opening_statement: ''   retriever_resource:     enabled: true   sensitive_word_avoidance:     enabled: false   speech_to_text:     enabled: false   suggested_questions: []   suggested_questions_after_answer:     enabled: false   text_to_speech:     enabled: false     language: ''     voice: '' graph:   edges:   - data:       isInIteration: false       isInLoop: false       sourceType: start       targetType: agent     id: 1745052852509-source-1745053053196-target     source: '1745052852509'     sourceHandle: source     target: '1745053053196'     targetHandle: target     type: custom     zIndex: 0   - data:       isInIteration: false       isInLoop: false       sourceType: agent       targetType: agent     id: 1745053053196-source-1745058131075-target     source: '1745053053196'     sourceHandle: source     target: '1745058131075'     targetHandle: target     type: custom     zIndex: 0   - data:       isInLoop: false       sourceType: agent       targetType: answer     id: 1745058131075-source-answer-target     source: '1745058131075'     sourceHandle: source     target: answer     targetHandle: target     type: custom     zIndex: 0   nodes:   - data:       desc: ''       selected: false       title: 開始       type: start       variables: []     height: 54     id: '1745052852509'     position:       x: 80       y: 282     positionAbsolute:       x: 80       y: 282     sourcePosition: right     targetPosition: left     type: custom     width: 244   - data:       answer: '{{#1745058131075.text#}}'       desc: ''       selected: false       title: 回答       type: answer       variables: []     height: 104     id: answer     position:       x: 1038.3030083212543       y: 288.00507835175284     positionAbsolute:       x: 1038.3030083212543       y: 288.00507835175284     selected: false     sourcePosition: right     targetPosition: left     type: custom     width: 244   - data:       agent_parameters:         instruction:           type: constant           value: 'Userの指示に従い適切なツールを使用してください             今日の日付を取得する際には、CurrentTimeを使ってください。             昨日や明日や明後日などの日付を取得する際にはCurrentTimeから計算を行い取得してください.             曜日について指示があった際にはWeekday Calculatorを用いて計算してください             予定について尋ねられた際にはzapier_mcpから得られるGoogle Calender情報を用いて予定を取得してください。             日付を指定されている場合その日以外の予定は送信しないでください             予定についてはカレンダーに書いている情報以外は書かないでください             送信は行わなくてよいです             出力は質問内容への解答だけでいいです'         mcp_server:           type: constant           value: '{{#env.MCP_Zapier#}}'         model:           type: constant           value:             completion_params: {}             mode: chat             model: gemini-2.0-flash             model_type: llm             provider: langgenius/gemini/google             type: model-selector         query:           type: constant           value: '{{#sys.query#}}'         tools:           type: constant           value:           - enabled: true             extra:               description: ''             parameters: {}             provider_name: time             schemas:             - auto_generate: null               default: '%Y-%m-%d %H:%M:%S'               form: form               human_description:                 en_US: Time format in strftime standard.                 ja_JP: Time format in strftime standard.                 pt_BR: Time format in strftime standard.                 zh_Hans: strftime 标准的时间格式。               label:                 en_US: Format                 ja_JP: Format                 pt_BR: Format                 zh_Hans: 格式               llm_description: null               max: null               min: null               name: format               options: []               placeholder: null               precision: null               required: false               scope: null               template: null               type: string             - auto_generate: null               default: UTC               form: form               human_description:                 en_US: Timezone                 ja_JP: Timezone                 pt_BR: Timezone                 zh_Hans: 时区               label:                 en_US: Timezone                 ja_JP: Timezone                 pt_BR: Timezone                 zh_Hans: 时区               llm_description: null               max: null               min: null               name: timezone               options:               - label:                   en_US: UTC                   ja_JP: UTC                   pt_BR: UTC                   zh_Hans: UTC                 value: UTC               - label:                   en_US: America/New_York                   ja_JP: America/New_York                   pt_BR: America/New_York                   zh_Hans: 美洲/纽约                 value: America/New_York               - label:                   en_US: America/Los_Angeles                   ja_JP: America/Los_Angeles                   pt_BR: America/Los_Angeles                   zh_Hans: 美洲/洛杉矶                 value: America/Los_Angeles               - label:                   en_US: America/Chicago                   ja_JP: America/Chicago                   pt_BR: America/Chicago                   zh_Hans: 美洲/芝加哥                 value: America/Chicago               - label:                   en_US: America/Sao_Paulo                   ja_JP: America/Sao_Paulo                   pt_BR: América/São Paulo                   zh_Hans: 美洲/圣保罗                 value: America/Sao_Paulo               - label:                   en_US: Asia/Shanghai                   ja_JP: Asia/Shanghai                   pt_BR: Asia/Shanghai                   zh_Hans: 亚洲/上海                 value: Asia/Shanghai               - label:                   en_US: Asia/Ho_Chi_Minh                   ja_JP: Asia/Ho_Chi_Minh                   pt_BR: Ásia/Ho Chi Minh                   zh_Hans: 亚洲/胡志明市                 value: Asia/Ho_Chi_Minh               - label:                   en_US: Asia/Tokyo                   ja_JP: Asia/Tokyo                   pt_BR: Asia/Tokyo                   zh_Hans: 亚洲/东京                 value: Asia/Tokyo               - label:                   en_US: Asia/Dubai                   ja_JP: Asia/Dubai                   pt_BR: Asia/Dubai                   zh_Hans: 亚洲/迪拜                 value: Asia/Dubai               - label:                   en_US: Asia/Kolkata                   ja_JP: Asia/Kolkata                   pt_BR: Asia/Kolkata                   zh_Hans: 亚洲/加尔各答                 value: Asia/Kolkata               - label:                   en_US: Asia/Seoul                   ja_JP: Asia/Seoul                   pt_BR: Asia/Seoul                   zh_Hans: 亚洲/首尔                 value: Asia/Seoul               - label:                   en_US: Asia/Singapore                   ja_JP: Asia/Singapore                   pt_BR: Asia/Singapore                   zh_Hans: 亚洲/新加坡                 value: Asia/Singapore               - label:                   en_US: Europe/London                   ja_JP: Europe/London                   pt_BR: Europe/London                   zh_Hans: 欧洲/伦敦                 value: Europe/London               - label:                   en_US: Europe/Berlin                   ja_JP: Europe/Berlin                   pt_BR: Europe/Berlin                   zh_Hans: 欧洲/柏林                 value: Europe/Berlin               - label:                   en_US: Europe/Moscow                   ja_JP: Europe/Moscow                   pt_BR: Europe/Moscow                   zh_Hans: 欧洲/莫斯科                 value: Europe/Moscow               - label:                   en_US: Australia/Sydney                   ja_JP: Australia/Sydney                   pt_BR: Australia/Sydney                   zh_Hans: 澳大利亚/悉尼                 value: Australia/Sydney               - label:                   en_US: Pacific/Auckland                   ja_JP: Pacific/Auckland                   pt_BR: Pacific/Auckland                   zh_Hans: 太平洋/奥克兰                 value: Pacific/Auckland               - label:                   en_US: Africa/Cairo                   ja_JP: Africa/Cairo                   pt_BR: Africa/Cairo                   zh_Hans: 非洲/开罗                 value: Africa/Cairo               placeholder: null               precision: null               required: false               scope: null               template: null               type: select             settings:               format:                 value: '%Y-%m-%d %H:%M:%S'               timezone:                 value: Asia/Tokyo             tool_label: Current Time             tool_name: current_time             type: builtin           - enabled: true             extra:               description: ''             parameters:               day:                 auto: 1                 value: null               month:                 auto: 1                 value: null               year:                 auto: 1                 value: null             provider_name: time             schemas:             - auto_generate: null               default: null               form: llm               human_description:                 en_US: Year                 ja_JP: Year                 pt_BR: Year                 zh_Hans: 年               label:                 en_US: Year                 ja_JP: Year                 pt_BR: Year                 zh_Hans: 年               llm_description: null               max: null               min: null               name: year               options: []               placeholder: null               precision: null               required: true               scope: null               template: null               type: number             - auto_generate: null               default: null               form: llm               human_description:                 en_US: Month                 ja_JP: Month                 pt_BR: Month                 zh_Hans: 月               label:                 en_US: Month                 ja_JP: Month                 pt_BR: Month                 zh_Hans: 月               llm_description: null               max: null               min: null               name: month               options: []               placeholder: null               precision: null               required: true               scope: null               template: null               type: number             - auto_generate: null               default: null               form: llm               human_description:                 en_US: day                 ja_JP: day                 pt_BR: day                 zh_Hans: 日               label:                 en_US: day                 ja_JP: day                 pt_BR: day                 zh_Hans: 日               llm_description: null               max: null               min: null               name: day               options: []               placeholder: null               precision: null               required: true               scope: null               template: null               type: number             settings: {}             tool_label: Weekday Calculator             tool_name: weekday             type: builtin       agent_strategy_label: MCP FunctionCalling       agent_strategy_name: function_calling       agent_strategy_provider_name: hjlarry/agent/mcp_agent       desc: ''       output_schema: null       plugin_unique_identifier: hjlarry/agent:0.0.1@f42a5a80b1c77fd0655c755b70ad08da47ceb1acc3638cf13a0eb9ed42b3a128       selected: false       title: エージェント       type: agent     height: 198     id: '1745053053196'     position:       x: 384       y: 282     positionAbsolute:       x: 384       y: 282     selected: true     sourcePosition: right     targetPosition: left     type: custom     width: 244   - data:       agent_parameters:         instruction:           type: constant           value: '送信してと言われたら{{#1745053053196.text#}}をそのままGmailを使って指定された宛先に送信してください。             許可を取る必要はないです。             出力は日本語にして'         mcp_server:           type: constant           value: '{{#env.MCP_Zapier#}}/'         model:           type: constant           value:             completion_params: {}             mode: chat             model: gemini-2.0-flash             model_type: llm             provider: langgenius/gemini/google             type: model-selector         query:           type: constant           value: '{{#sys.query#}}{{#1745053053196.text#}}'         tools:           type: constant           value:           - enabled: true             extra:               description: ''             parameters: {}             provider_name: time             schemas:             - auto_generate: null               default: '%Y-%m-%d %H:%M:%S'               form: form               human_description:                 en_US: Time format in strftime standard.                 ja_JP: Time format in strftime standard.                 pt_BR: Time format in strftime standard.                 zh_Hans: strftime 标准的时间格式。               label:                 en_US: Format                 ja_JP: Format                 pt_BR: Format                 zh_Hans: 格式               llm_description: null               max: null               min: null               name: format               options: []               placeholder: null               precision: null               required: false               scope: null               template: null               type: string             - auto_generate: null               default: UTC               form: form               human_description:                 en_US: Timezone                 ja_JP: Timezone                 pt_BR: Timezone                 zh_Hans: 时区               label:                 en_US: Timezone                 ja_JP: Timezone                 pt_BR: Timezone                 zh_Hans: 时区               llm_description: null               max: null               min: null               name: timezone               options:               - label:                   en_US: UTC                   ja_JP: UTC                   pt_BR: UTC                   zh_Hans: UTC                 value: UTC               - label:                   en_US: America/New_York                   ja_JP: America/New_York                   pt_BR: America/New_York                   zh_Hans: 美洲/纽约                 value: America/New_York               - label:                   en_US: America/Los_Angeles                   ja_JP: America/Los_Angeles                   pt_BR: America/Los_Angeles                   zh_Hans: 美洲/洛杉矶                 value: America/Los_Angeles               - label:                   en_US: America/Chicago                   ja_JP: America/Chicago                   pt_BR: America/Chicago                   zh_Hans: 美洲/芝加哥                 value: America/Chicago               - label:                   en_US: America/Sao_Paulo                   ja_JP: America/Sao_Paulo                   pt_BR: América/São Paulo                   zh_Hans: 美洲/圣保罗                 value: America/Sao_Paulo               - label:                   en_US: Asia/Shanghai                   ja_JP: Asia/Shanghai                   pt_BR: Asia/Shanghai                   zh_Hans: 亚洲/上海                 value: Asia/Shanghai               - label:                   en_US: Asia/Ho_Chi_Minh                   ja_JP: Asia/Ho_Chi_Minh                   pt_BR: Ásia/Ho Chi Minh                   zh_Hans: 亚洲/胡志明市                 value: Asia/Ho_Chi_Minh               - label:                   en_US: Asia/Tokyo                   ja_JP: Asia/Tokyo                   pt_BR: Asia/Tokyo                   zh_Hans: 亚洲/东京                 value: Asia/Tokyo               - label:                   en_US: Asia/Dubai                   ja_JP: Asia/Dubai                   pt_BR: Asia/Dubai                   zh_Hans: 亚洲/迪拜                 value: Asia/Dubai               - label:                   en_US: Asia/Kolkata                   ja_JP: Asia/Kolkata                   pt_BR: Asia/Kolkata                   zh_Hans: 亚洲/加尔各答                 value: Asia/Kolkata               - label:                   en_US: Asia/Seoul                   ja_JP: Asia/Seoul                   pt_BR: Asia/Seoul                   zh_Hans: 亚洲/首尔                 value: Asia/Seoul               - label:                   en_US: Asia/Singapore                   ja_JP: Asia/Singapore                   pt_BR: Asia/Singapore                   zh_Hans: 亚洲/新加坡                 value: Asia/Singapore               - label:                   en_US: Europe/London                   ja_JP: Europe/London                   pt_BR: Europe/London                   zh_Hans: 欧洲/伦敦                 value: Europe/London               - label:                   en_US: Europe/Berlin                   ja_JP: Europe/Berlin                   pt_BR: Europe/Berlin                   zh_Hans: 欧洲/柏林                 value: Europe/Berlin               - label:                   en_US: Europe/Moscow                   ja_JP: Europe/Moscow                   pt_BR: Europe/Moscow                   zh_Hans: 欧洲/莫斯科                 value: Europe/Moscow               - label:                   en_US: Australia/Sydney                   ja_JP: Australia/Sydney                   pt_BR: Australia/Sydney                   zh_Hans: 澳大利亚/悉尼                 value: Australia/Sydney               - label:                   en_US: Pacific/Auckland                   ja_JP: Pacific/Auckland                   pt_BR: Pacific/Auckland                   zh_Hans: 太平洋/奥克兰                 value: Pacific/Auckland               - label:                   en_US: Africa/Cairo                   ja_JP: Africa/Cairo                   pt_BR: Africa/Cairo                   zh_Hans: 非洲/开罗                 value: Africa/Cairo               placeholder: null               precision: null               required: false               scope: null               template: null               type: select             settings:               format:                 value: '%Y-%m-%d %H:%M:%S'               timezone:                 value: UTC             tool_label: Current Time             tool_name: current_time             type: builtin       agent_strategy_label: MCP FunctionCalling       agent_strategy_name: function_calling       agent_strategy_provider_name: hjlarry/agent/mcp_agent       desc: ''       output_schema: null       plugin_unique_identifier: hjlarry/agent:0.0.1@f42a5a80b1c77fd0655c755b70ad08da47ceb1acc3638cf13a0eb9ed42b3a128       selected: false       title: エージェント 2       type: agent     height: 198     id: '1745058131075'     position:       x: 688       y: 282     positionAbsolute:       x: 688       y: 282     selected: false     sourcePosition: right     targetPosition: left     type: custom     width: 244   viewport:     x: 575.2647921598689     y: 264.84697840196714     zoom: 0.5401478780503224

このようにすることでGmailとGoogleCalendarどちらとも連携することができます。

まとめ:MCPが拓く、自律型エージェントの未来

Dify × MCPの組み合わせは、LLMエージェントに高度な「実行能力」を与え、かつそれを管理・統制するための強力な基盤を提供します。特に、複数のAPI連携を必要とする複雑な業務プロセスを自動化・高度化する上で、その効果は絶大です。

MCPは、LLMアプリケーション開発における、コンテンツと機能の「供給網」を整備する役割を担う。これにより、開発者はより迅速かつ安全に、高機能なエージェントを構築し、ビジネス価値へと繋げることが可能になります。

参考

https://docs.dify.ai/ja-jp/plugins/best-practice/how-to-use-mcp-zapier
https://dify.ai/blog/dify-mcp-plugin-hands-on-guide-integrating-zapier-for-effortless-agent-tool-calls

UPGRADE tech blog

生成AI特化のコンサルティング・開発・内製化支援を行っています。Dify公式パートナー🚩

Discussion


[8]ページ先頭

©2009-2025 Movatter.jp