こんにちは、田中です。
今日のビジネス環境において、外部データソースをAPI経由で連携させる必要性はますます高まっています。しかし、これらのAPI連携を個別に実装し、連携ロジックをコードで管理するのは、開発工数、エラーハンドリング、メンテナンス性の観点から大きな負担となり得ます。
ここで注目されるのが、Managed Content/Capability Platform (MCP) という概念です。本記事では、このMCPがなぜ重要なのか、そしてLLMアプリケーション開発プラットフォームDifyとMCPを組み合わせることで、特に複数のAPI連携を伴う複雑なワークフローをいかに効率的に構築・管理できるようになるかを解説していきます。
MCPは、単なるコンテンツ管理システム(CMS)やナレッジベースを超えた概念です。LLMやエージェントが必要とする以下の二つの要素を一元的に管理し、制御された形で提供するためのプラットフォーム基盤と捉えることができます。
MCPは、これらのコンテンツやツールへのアクセスを集約・抽象化し、LLMアプリケーション(例えばDifyで構築されたもの)に対して、管理・統制されたインターフェースを提供します。これにより、セキュリティの確保、アクセス制御、利用状況の監視、ツールの追加・更新の容易化といったメリットが生まれます。「MCPサーバー」として機能し、様々なツールやプラットフォーム間の連携を仲介するハブとなるイメージです。
Difyは単体でも、カスタムツールとして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サーバーを用いて作っていきます。
手順:
まずはこちらからZapierのアカウントを作ります。
アクセスしたサイトからGet startedを選択します。
Googleアカウントなどから作成します。
作成するアカウントを選択したのちに以下のような質問が出てくるので答えていきます。
質問に答え終わると以下のようなページになるのでNew MCP Serverを選択してください。
以下のページになったらMCP ClientはOtherをNameには好きなものを入力して、Create MCP Serverを選択してください。
Add toolを選択してください。
次にGoogle Calendarを選択してください。
アクセスしたページのAdd all Google Calendar toolsを選択してください。
使用するGoogle calendarのgoogle accountを選択してください。
Add all Google calendar toolsを選択します。
もう一度Add toolsを選択します。
Gmailを選択します。
Add all Gmail toolsを選択します。
使用するGmail account を選択します。
Add all Gmail toolsを選択します。
上の部分からConnectを選択します
Server URLをコピーします
次にDifyにログインします。
※アカウントがない方は作ってください。
アプリを作成する→最初から作成するを選択します。
アプリの種類→チャットフローとする。
アプリのアイコンと名前はなんでもよい。
その後作成するを選択する。
LLMを削除します。
開始のブロックのプラスボタンを選択してエージェントを選択します。
エージェントノードのプラスボタンからもう一つエージェントノードを追加します。
二つ目のエージェントノード(エージェント2)の+ボタンから線を引っ張り、回答ブロックと接続します。
回答ブロックの応答にはLLMブロック/textが指定されているので削除して、エージェント2/textを指定します。
次にエージェントのエージェンティック戦略をMCP AgentのMCP Function Callingにします。
※まだMCP Agentをインストールしていない場合は以下の手順でMCP Agentをインストールしてください。
「マーケットプレイスでさらに見つけてください」を選択します。
MCP Agent Strategyを選択します。
インストールします。
Modelを選択する。
※なんでもよいです。
Tools Listは
Current Time→Current Time
Current Time→Weekday Calculator を選択します。
Current Timeにおいては設定からTimezoneをTokyoにしてください。
次に右上のENVと書かれているボタンを押し、環境変数を設定します。
環境変数の追加から
タイプはString
変数名はなんでもよい
値にはZapierからコピーしたURLを張り付けます。
エージェントのMCP SERVER URLに先ほど設定した変数を設定します。
Instructionには以下のものコピペします。
Userの指示に従い適切なツールを使用してください。今日の日付を取得する際には、CurrentTimeを使ってください。昨日や明日や明後日などの日付を取得する際にはCurrentTimeから計算を行い取得してください。曜日について指示があった際にはWeekday Calculatorを用いて計算してください。予定について尋ねられた際にはzapier_mcpから得られるGoogle Calendar情報を用いて予定を取得してください。日付を指定されている場合その日以外の予定は送信しないでください。予定についてはカレンダーに書いている情報以外は書かないでください。送信は行わなくてよいです。出力は質問内容への解答だけでいいです。
QUERYにはsys.queryを選択します。
今度はエージェント2について設定を行います。
設定に関しては以下の値をそれぞれ入れます。
※instructionについては後述
※QUERYのところはエージェント/textが入っていることに注意
エージェント2のinstructionについては以下のように入力してください
送信してと言われたらエージェント/textをそのままGmailを使って指定された宛先に送信してください。許可を取る必要はないです。
右上の公開を押す。
アプリを実行を選択する。
チャットに依頼内容を打ち込むと以下のようになります。
送られたメールは以下のようになります。
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どちらとも連携することができます。
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