DifyとAzure上の自作MCP Serverとで、SSE+HTTPがうまくいかなった話し
tl:dr
- DifyとAzure上の自作MCP Serverとで、SSE+HTTPの接続を試みたがうまくいかなかった
- 具体的な検証内容と、構築した構成を説明しているので参考に
- この知見を持ちつつ、今後のMCP界隈の動向を追っていきたい
はじめに
実現したかったアーキテクチャ図
この検証は、下記記事の続編となります。
Local上で動かせるようになったMCPドリブンのChat UIについて、Dify上でリモートで動かせるようにする検証となります。デスクトップ上のMCP ServerはStdioという方式が推奨されているのですが、Difyから使用する場合は、SSEという方式が推奨されています。
このため、元々Stdioを前提に作ったPythonmcp_server.py
をSSEで通信できるようにhttp_sse_server.py
でラッピングするやり方をとりました。
検証結果
DifyからMCP Serverへ接続する場合、Difyのマーケットプレイスからプラグインを探してインストールする必要があります。
マーケットプレイスの画面 MCPと検索すると9件プラグインが存在した
今回は、下記プラグインをそれぞれ検証しました。
- Agent Strategies (Support MCP Tools)
- MCP SSE / StreamableHTTP
- MCP Agent Strategy
Agent Strategies (Support MCP Tools)
Azure上のMCP Server
へHTTP+SSE通信をする設定をしてチャットで質問したのですが、止まってしまい回答を得ることができませんでした。
この状態で止まって動かなかった
MCP Serverのログを確認したところ、下記の通りMCP Serverに届いているようでした。
INFO: 10.92.0.9:49367 - "GET /sse HTTP/1.1" 200 OK
2025-06-01 07:10:11,175 - http_sse_mcp_server - INFO - SSE session 123d3a82-42e1-48f8-adf3-53f01382a26a disconnected
2025-06-01 07:10:11,345 - http_sse_mcp_server - INFO - Received message for session 123d3a82-42e1-48f8-adf3-53f01382a26a
2025-06-01 07:10:11,345 - http_sse_mcp_server - INFO - Active sessions: ['027f2f1c-b609-4675-9bc7-b34a2b2b4274', 'ad4c724d-e897-4e40-8196-95e386fe2c65', '507cda22-2f9c-4eea-a710-47eecee1b208', 'db6e2905-7580-491f-a27a-25acbac7eee9', 'c799ad5f-d59a-4181-a524-3aedd51d4997', '62ef5788-4d48-45d4-b4f5-08d753b8f2f8', '047edaf5-f43d-4ddf-8662-3fdb4a11ffde']
2025-06-01 07:10:11,345 - http_sse_mcp_server - WARNING - Session 123d3a82-42e1-48f8-adf3-53f01382a26a not found, creating new session
2025-06-01 07:10:11,345 - http_sse_mcp_server - INFO - Processing message: initialize with id: d87771846084445fbe6cdb0b20d74ac7
2025-06-01 07:10:11,346 - http_sse_mcp_server - INFO - Initializing MCP connection - Protocol: 2024-11-05, Client: {'name': 'MCP HTTP with SSE Client', 'version': '1.0.0'}
INFO: 10.92.0.9:49374 - "POST /sse/messages?session_id=123d3a82-42e1-48f8-adf3-53f01382a26a HTTP/1.1" 200 OK
MCP SSE / StreamableHTTP
MCP SSE / StreamableHTTP
の場合、プラグインを使う前に認証が必要なのですが、この認証で途中で止まってしまいました。Agent Strategies (Support MCP Tools)
と同じくMCP Serverへリクエストは届いているように見えました。
この状態のままとなり認証が通らない
INFO: 10.92.0.11:62597 - "GET /sse HTTP/1.1" 200 OK
2025-06-01 07:54:12,671 - http_sse_mcp_server - INFO - SSE session d780dd3b-6a90-4997-af79-071a97d8483f disconnected
2025-06-01 07:54:12,839 - http_sse_mcp_server - INFO - Received message for session d780dd3b-6a90-4997-af79-071a97d8483f
2025-06-01 07:54:12,839 - http_sse_mcp_server - INFO - Active sessions: ['027f2f1c-b609-4675-9bc7-b34a2b2b4274', 'ad4c724d-e897-4e40-8196-95e386fe2c65', '507cda22-2f9c-4eea-a710-47eecee1b208', 'db6e2905-7580-491f-a27a-25acbac7eee9', 'c799ad5f-d59a-4181-a524-3aedd51d4997', '62ef5788-4d48-45d4-b4f5-08d753b8f2f8', '047edaf5-f43d-4ddf-8662-3fdb4a11ffde', '123d3a82-42e1-48f8-adf3-53f01382a26a']
2025-06-01 07:54:12,839 - http_sse_mcp_server - WARNING - Session d780dd3b-6a90-4997-af79-071a97d8483f not found, creating new session
2025-06-01 07:54:12,839 - http_sse_mcp_server - INFO - Processing message: initialize with id: 7eed8a4fe18b4db2bd15b75ae996ee3f
2025-06-01 07:54:12,840 - http_sse_mcp_server - INFO - Initializing MCP connection - Protocol: 2024-11-05, Client: {'name': 'MCP HTTP with SSE Client', 'version': '1.0.0'}
INFO: 10.92.0.11:62601 - "POST /sse/messages?session_id=d780dd3b-6a90-4997-af79-071a97d8483f HTTP/1.1" 200 OK
MCP Agent Strategy
MCP Agent Strategy
のケースだとうまく動きました。Difyのノードの構成はこのようになっています。検証として最小構成にしています。ただ、動くときと動かない時があり不安定です。
Difyのノードの構成
動いている様子
INFO: 10.92.0.11:49693 - "GET /sse HTTP/1.1" 200 OK
2025-06-01 08:07:00,457 - http_sse_mcp_server - INFO - Received message for session 6aa1a518-9d4e-4e33-9eac-50c603400aff
2025-06-01 08:07:00,457 - http_sse_mcp_server - INFO - Active sessions: ['027f2f1c-b609-4675-9bc7-b34a2b2b4274', 'ad4c724d-e897-4e40-8196-95e386fe2c65', '507cda22-2f9c-4eea-a710-47eecee1b208', 'db6e2905-7580-491f-a27a-25acbac7eee9', 'c799ad5f-d59a-4181-a524-3aedd51d4997', '62ef5788-4d48-45d4-b4f5-08d753b8f2f8', '047edaf5-f43d-4ddf-8662-3fdb4a11ffde', '123d3a82-42e1-48f8-adf3-53f01382a26a', 'd780dd3b-6a90-4997-af79-071a97d8483f', '5902c8f8-0df3-4572-bb48-9a93f9ddccd4', 'bd694165-6d5b-4394-9dcd-838be87838aa', 'e59a5818-4e61-4712-8ee8-1e61d525d734', '5de6d864-1396-4a1d-a03d-3868673efedb', '7ab5467d-8390-41af-96f1-c4f2da4b3f33', '6aa1a518-9d4e-4e33-9eac-50c603400aff']
2025-06-01 08:07:00,457 - http_sse_mcp_server - INFO - Processing message: initialize with id: 0
2025-06-01 08:07:00,457 - http_sse_mcp_server - INFO - Initializing MCP connection - Protocol: 2024-11-05, Client: {'name': 'mcp', 'version': '0.1.0'}
INFO: 10.92.0.11:49697 - "POST /sse/messages?session_id=6aa1a518-9d4e-4e33-9eac-50c603400aff HTTP/1.1" 200 OK
2025-06-01 08:07:00,625 - http_sse_mcp_server - INFO - Received message for session 6aa1a518-9d4e-4e33-9eac-50c603400aff
2025-06-01 08:07:00,625 - http_sse_mcp_server - INFO - Active sessions: ['027f2f1c-b609-4675-9bc7-b34a2b2b4274', 'ad4c724d-e897-4e40-8196-95e386fe2c65', '507cda22-2f9c-4eea-a710-47eecee1b208', 'db6e2905-7580-491f-a27a-25acbac7eee9', 'c799ad5f-d59a-4181-a524-3aedd51d4997', '62ef5788-4d48-45d4-b4f5-08d753b8f2f8', '047edaf5-f43d-4ddf-8662-3fdb4a11ffde', '123d3a82-42e1-48f8-adf3-53f01382a26a', 'd780dd3b-6a90-4997-af79-071a97d8483f', '5902c8f8-0df3-4572-bb48-9a93f9ddccd4', 'bd694165-6d5b-4394-9dcd-838be87838aa', 'e59a5818-4e61-4712-8ee8-1e61d525d734', '5de6d864-1396-4a1d-a03d-3868673efedb', '7ab5467d-8390-41af-96f1-c4f2da4b3f33', '6aa1a518-9d4e-4e33-9eac-50c603400aff']
2025-06-01 08:07:00,626 - http_sse_mcp_server - INFO - Processing message: notifications/initialized with id: None
INFO: 10.92.0.11:49697 - "POST /sse/messages?session_id=6aa1a518-9d4e-4e33-9eac-50c603400aff HTTP/1.1" 204 No Content
2025-06-01 08:07:00,626 - http_sse_mcp_server - INFO - Received initialized notification: notifications/initialized
2025-06-01 08:07:00,794 - http_sse_mcp_server - INFO - Received message for session 6aa1a518-9d4e-4e33-9eac-50c603400aff
2025-06-01 08:07:00,794 - http_sse_mcp_server - INFO - Active sessions: ['027f2f1c-b609-4675-9bc7-b34a2b2b4274', 'ad4c724d-e897-4e40-8196-95e386fe2c65', '507cda22-2f9c-4eea-a710-47eecee1b208', 'db6e2905-7580-491f-a27a-25acbac7eee9', 'c799ad5f-d59a-4181-a524-3aedd51d4997', '62ef5788-4d48-45d4-b4f5-08d753b8f2f8', '047edaf5-f43d-4ddf-8662-3fdb4a11ffde', '123d3a82-42e1-48f8-adf3-53f01382a26a', 'd780dd3b-6a90-4997-af79-071a97d8483f', '5902c8f8-0df3-4572-bb48-9a93f9ddccd4', 'bd694165-6d5b-4394-9dcd-838be87838aa', 'e59a5818-4e61-4712-8ee8-1e61d525d734', '5de6d864-1396-4a1d-a03d-3868673efedb', '7ab5467d-8390-41af-96f1-c4f2da4b3f33', '6aa1a518-9d4e-4e33-9eac-50c603400aff']
2025-06-01 08:07:00,794 - http_sse_mcp_server - INFO - Processing message: tools/list with id: 1
INFO: 10.92.0.11:49697 - "POST /sse/messages?session_id=6aa1a518-9d4e-4e33-9eac-50c603400aff HTTP/1.1" 200 OK
2025-06-01 08:07:03,202 - http_sse_mcp_server - INFO - Received message for session 6aa1a518-9d4e-4e33-9eac-50c603400aff
2025-06-01 08:07:03,202 - http_sse_mcp_server - INFO - Active sessions: ['027f2f1c-b609-4675-9bc7-b34a2b2b4274', 'ad4c724d-e897-4e40-8196-95e386fe2c65', '507cda22-2f9c-4eea-a710-47eecee1b208', 'db6e2905-7580-491f-a27a-25acbac7eee9', 'c799ad5f-d59a-4181-a524-3aedd51d4997', '62ef5788-4d48-45d4-b4f5-08d753b8f2f8', '047edaf5-f43d-4ddf-8662-3fdb4a11ffde', '123d3a82-42e1-48f8-adf3-53f01382a26a', 'd780dd3b-6a90-4997-af79-071a97d8483f', '5902c8f8-0df3-4572-bb48-9a93f9ddccd4', 'bd694165-6d5b-4394-9dcd-838be87838aa', 'e59a5818-4e61-4712-8ee8-1e61d525d734', '5de6d864-1396-4a1d-a03d-3868673efedb', '7ab5467d-8390-41af-96f1-c4f2da4b3f33', '6aa1a518-9d4e-4e33-9eac-50c603400aff']
2025-06-01 08:07:03,202 - http_sse_mcp_server - INFO - Processing message: tools/call with id: 2
INFO: 10.92.0.11:49697 - "POST /sse/messages?session_id=6aa1a518-9d4e-4e33-9eac-50c603400aff HTTP/1.1" 200 OK
2025-06-01 08:07:10,314 - http_sse_mcp_server - INFO - SSE session 6aa1a518-9d4e-4e33-9eac-50c603400aff disconnected
APIキーで認証すると繋がらなくなった
セキュアにするために、APIキーを発行してAPIキー認証にしました。
すると、Timeoutを起こして一切MCP Serverに繋がらなくなりました。Timeout設定等を見直して原因分析したのですが、結局よくわからず。
なお、コマンドcurl
だとうまく動きました。下記例はHTTPSで接続していますが、DifyではHTTPSでもタイムアウトになりました。
curl -k -X POST https://xxx.japaneast.azurecontainer.io/message `
>> -H "Content-Type: application/json" `
>> -H "x-api-key: mcp_api_xxx" `
>> -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"get_ticket_list","arguments":{}},"id":3}'
{"result":{"content":[{"type":"text","text":"# Ticket List\n\n| ID | Reception Date | Account/Requestor | Category/Detail | Summary | Person in Charge | Status | Scheduled Date/Remaining
|\n|---|---|---|---|---|---|---|---|\n| TCK-0046 | 2025-05-29 10:48 | イノベーションラボ株式会社/渡辺 さくら | 障害報告/システム障害 | CSVインポートエラー | 山田 太郎 | 対応中 | 2025-06-01 0 days left
|\n| TCK-0003 | 2025-05-29 10:48 | 株式会社ABC/佐藤 次郎 | 障害報告/システム障害 | ダッシュボードが表示されない | 山田 太郎 | 受付済 | 2025-05-31 -1 days left |\n| TCK-0043 | 2025-05-28 10:48 |
株式会社ABC/佐藤 次郎 | UX改修依頼/検索機能改善提案 | 検索結果のハイライト表示 | 山田 太郎 | 受付済 | 2025-06-11 10 days left |\n| TCK-0004 | 2025-05-28 10:48 | グローバルテック株式会社/伊藤 健一 |
問合せ/ポータル・記事・検索機能に関する問合せ | 全文検索が一部ヒットしない | 田中 美咲 | 対応中 | 2025-06-04 3 days left |\n| TCK-0022 | 2025-05-27 10:48 | イノベーションラボ株式会社/渡辺 さくら |
障害報告/システム障害 | ファイルアップロード機能の不具合 | 山田 太郎 | 対応中 | 2025-06-03 2 days left |\n| TCK-0006 | 2025-05-27 10:48 | 株式会社ABC/佐藤 次郎 | 障害報告/システム障害 |
検索機能のパフォーマンスが低下 | 鈴木 花子 | 対応中 | 2025-05-31 -1 days left |\n| TCK-0037 | 2025-05-26 10:48 | XYZ株式会社/高橋 三郎 | 障害報告/システム障害 | 印刷機能の不具合 | 山田 太郎 | 対応中 |
2025-06-02 1 days left |\n| TCK-0017 | 2025-05-26 10:48 | XYZ株式会社/高橋 三郎 | 障害報告/システム障害 | セキュリティ設定のエラー | 田中 美咲 | 対応中 | 2025-06-01 0 days left |\n| TCK-0008 |
2025-05-26 10:48 | グローバルテック株式会社/伊藤 健一 | 機能追加依頼/連携機能追加 | 通知用のSlack API連携 | 田中 美咲 | 受付済 | 2025-06-20 19 days left |\n| TCK-0029 | 2025-05-25 10:48 |
XYZ株式会社/高橋 三郎 | 問合せ/サポート管理に関する問合せ | 自動バックアップ設定について | 田中 美咲 | 受付済 | 2025-06-07 6 days left |\n| TCK-0015 | 2025-05-25 10:48 | 株式会社ABC/佐藤 次郎 |
問合せ/サポート管理に関する問合せ | アクセス権限の設定方法 | 鈴木 花子 | 受付済 | 2025-06-09 8 days left |\n| TCK-0001 | 2025-05-25 10:48 | 株式会社ABC/佐藤 次郎 |
問合せ/ポータル・記事・検索機能に関する問合せ | 検索機能が正常に動作しない | 山田 太郎 | 対応中 | 2025-06-01 0 days left |\n| TCK-0025 | 2025-05-24 10:48 | XYZ株式会社/高橋 三郎 |
機能追加依頼/連携機能追加 | Microsoft Teams連携 | 山田 太郎 | 確認中 | 2025-06-19 18 days left |\n| TCK-0009 | 2025-05-24 10:48 | 123株式会社/高橋 三郎 | 問合せ/サポート管理に関する問合せ |
ログイン機能に関する問題 | 鈴木 花子 | 確認中 | 2025-06-03 2 days left |\n| TCK-0035 | 2025-05-23 10:48 | 株式会社ABC/佐藤 次郎 | 機能追加依頼/連携機能追加 | Webhookによるイベント通知 | 田中 美咲 |
対応中 | 2025-06-13 12 days left |\n| TCK-0019 | 2025-05-23 10:48 | 株式会社ABC/佐藤 次郎 | 問合せ/ポータル・記事・検索機能に関する問合せ | 検索結果のフィルタリング | 山田 太郎 | 対応中 | 2025-06-05 4
days left |\n| TCK-0005 | 2025-05-23 10:48 | イノベーションラボ株式会社/渡辺 さくら | UX改修依頼/検索機能改善提案 | 検索結果の並び順をカスタマイズしたい | 山田 太郎 | 確認中 | 2025-06-13 12 days left
|\n| TCK-0027 | 2025-05-22 10:48 | 株式会社ABC/佐藤 次郎 | 障害報告/システム障害 | ログイン後の画面遷移エラー | 鈴木 花子 | 対応中 | 2025-06-02 1 days left |\n| TCK-0010 | 2025-05-22 10:48 |
イノベーションラボ株式会社/渡辺 さくら | UX改修依頼/UI/UX改善提案 | ダッシュボードのグラフ表示期間設定 | 山田 太郎 | 対応中 | 2025-06-06 5 days left |\n| TCK-0031 | 2025-05-21 10:48 | 株式会社ABC/佐藤
次郎 | 問合せ/ポータル・記事・検索機能に関する問合せ | 検索APIの利用方法 | 山田 太郎 | 対応中 | 2025-06-04 3 days left |\n"}]},"jsonrpc":"2.0","id":3}
現状の不安定さを考えると、、、
DifyなどのAI AgentからリモートMCPができるのは夢が広がる話しですが、現状の各プラグインの不安定さやAPIキーがうまく機能しないところを見るとまだまだ発展途上でEnterprise利用は時期尚早かなと思いました。私のアーキテクチャや実装に不備がある可能性も高いですが、もう少し事例やノウハウがたまって安定してからかなと。
この検証のサーバ構成
参考までに解説します。
このシステムは、Azureクラウド上に構築された3層アーキテクチャを採用しています:
[AIクライアント(Dify)] → [MCP Server] → [API Server] → [PostgreSQL Database]
各層は明確に役割が分離されており、スケーラビリティとセキュリティを考慮した設計としています。
主要コンポーネントの詳細
1. Azure Container Instances - アプリケーション実行環境
リソース名: ticket-system-containers
Container Instancesは、サーバーレスでコンテナを実行できるAzureのサービスです。以下の2つのコンテナを1つのコンテナグループとして実行しています:
- MCP Server コンテナ(Python)
- API Server コンテナ(Node.js)
これらのコンテナは同一のネットワーク内で動作し、localhost経由で相互に通信できます。外部からは専用のFQDN(xxx.japaneast.azurecontainer.io
)でアクセス可能です。
2. MCP Server - AIとシステムの橋渡し
技術スタック: Python FastAPI + HTTP/SSE
MCP Serverは、AIクライアントからのリクエストを受け取り、適切なシステム操作に変換する重要な役割を担います:
# MCPツールの例
- get_ticket_list # チケット一覧取得
- create_ticket # チケット作成
- update_ticket # チケット更新
- add_ticket_history # 履歴追加
特徴的な実装:
- Server-Sent Events(SSE):リアルタイムな双方向通信を実現
- レート制限:10リクエスト/分の制限でシステムを保護
-
APIキー認証:
x-api-key
ヘッダーによるアクセス制御
3. API Server - ビジネスロジック層
技術スタック: Node.js Express + TypeScript
API Serverは、RESTful APIとして実装されており、実際のビジネスロジックを処理します:
// 主要エンドポイント
GET /tickets // チケット一覧
GET /tickets/:id // チケット詳細
POST /tickets // チケット作成
PUT /tickets/:id // チケット更新
POST /tickets/:id/history // 履歴追加
TypeScriptとPgTypedを使用することで、型安全性を確保し、SQLインジェクションを防いでいます。
4. PostgreSQL Flexible Server - データ永続化層
リソース名: ticket-system-db
Azure Database for PostgreSQL Flexible Serverを使用し、以下のデータを管理:
- チケット情報(
tickets
テーブル) - チケット履歴(
ticket_history
テーブル) - ユーザー、アカウント、カテゴリなどのマスターデータ
バージョン16.8を使用し、7日間の自動バックアップが設定されています。
5. Container Registry - コンテナイメージ管理
リソース名: ticketsystemacr
Azure Container Registry(ACR)は、プライベートなDockerレジストリとして機能します:
-
api-server:prod-ssl
:本番用APIサーバーイメージ -
mcp-server-http:latest
:MCPサーバーイメージ
CI/CDパイプラインと連携して、安全なイメージ管理を実現していく想定でした。
6. Key Vault - シークレット管理
リソース名: ticket-system-keyvault
Azure Key Vaultで以下の機密情報を一元管理:
- データベースパスワード
- Container Registryの認証情報
- MCP APIキー
アプリケーションはManaged Identityを使用してKey Vaultにアクセスするため、ハードコードされた認証情報は一切ありません。
7. Managed Identity - 認証の自動化
リソース名: ticket-system-identity
User-assigned Managed Identityにより、以下を実現:
- Container InstancesからKey Vaultへの安全なアクセス
- Container RegistryからのイメージPull認証
- パスワードレスな認証フロー
データフローの詳細
-
AIクライアント → MCP Server
- HTTP + SSE プロトコルで通信
- MCPツール呼び出し(例:「チケット一覧を取得」)
-
MCP Server → API Server
- 内部ネットワーク経由のREST API呼び出し
- localhost:8080でアクセス
-
API Server → PostgreSQL
- コネクションプールを使用した効率的なDB接続
- PgTypedによる型安全なSQL実行
セキュリティの実装
このシステムでは、多層防御のアプローチを採用:
-
認証・認可
- APIキー認証(MCP層)
- Managed Identity(インフラ層)
-
ネットワークセキュリティ
- コンテナグループ内の内部通信
- 外部公開は必要最小限のポートのみ
-
シークレット管理
- Key Vaultによる一元管理
- 環境変数経由での安全な注入
-
レート制限
- API濫用防止
- システムリソースの保護
まとめ
このアーキテクチャは、AIツールとエンタープライズシステムを安全に統合するためのリファレンス実装として機能します。MCPプロトコルを中心に、Azureのマネージドサービスを活用することで、運用負荷を最小限に抑えながら、拡張性とセキュリティを両立させています。
各層が疎結合に設計されています。これにより、将来的にMCP Serverを別のAIシステムに対応させたり、API Serverを異なるビジネスロジックに置き換えたりすることが容易になるのではと考えています。
おわりに
いかがでしたか。この記事を書くのか悩みましたが、うまくいかなった事例も誰かの役に立つのではと考えて記事にしました。MCPのSSEやStreamable HTTPは、今後発展していく分野と考えています。この経験を知見として持っておき、日々のMCP界隈の動向を追っていけたらと考えています。
Discussion