OpenZiti MCP Gateway について
OpenZiti MCP Gateway は NetFoundry がスポンサーを務める MCP ゲートウェイで、パブリックエンドポイントを公開せずに OpenZiti オーバーレイ経由で AI アシスタントが内部ツールへ安全にアクセスできるようにします。MCP ツールを複数のチームや分散システムで共有したい利用者を想定しており、複数のバックエンドの集約とフィルタリングに対応しています。
主な機能
- 01OpenZiti オーバーレイによるゼロトラストアクセス
- 02パブリック IP やポート転送が不要
- 03複数のバックエンドを単一エンドポイントに集約
- 04バックエンドごとのツールフィルタリング
- 05stdio と HTTP のトランスポートに対応
活用シーン
- 01AI アシスタントによる内部ツールへの安全なアクセス
- 02リモートマシンの MCP サーバーをチームで共有
- 03ファイルシステム、GitHub、データベースのツールを単一接続で利用
MCP 対応
MCP ゲートウェイ群として、mcp-tools はクライアントをリモートの zrok 共有や Agora トンネルに接続し、mcp-gateway は複数の MCP サーバーを単一エンドポイントに集約し、mcp-bridge は単一の MCP サーバーをネットワークに公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
MCP Gateway
OpenZiti 経由で MCP ツールにゼロトラストでアクセス
MCP Gateway を使うと、公開エンドポイントを公開せずに、AI アシスタントから内部ツールへ安全にアクセスできます。OpenZiti、zrok、Agora を基盤としており、攻撃対象領域のない、暗号学的に安全なゼロトラスト接続を提供します。
MCP Gateway は、安全なワークロードとエージェント型コンピューティング向けソリューションのポートフォリオの一環として、NetFoundry の支援を受けています。NetFoundry は、OpenZiti と zrok の開発元です。
三位一体の構成要素
連携して動作する、シンプルな3つのコンポーネントです。
| コンポーネント | 目的 |
|---|---|
| mcp-tools | MCP クライアントをリモートの zrok 共有または Agora トンネル(stdio または HTTP)に接続します |
| mcp-gateway | 複数のバックエンドを zrok および/または Agora 経由で、1つの安全なエンドポイントに集約します |
| mcp-bridge | 単一の MCP サーバーを zrok または Agora 経由でネットワークに公開します |
flowchart LR
A[Agent] -->|stdio| B[mcp-tools]
B -->|zrok or Agora| C[mcp-gateway]
C -->|stdio / zrok / Agora / HTTP| D[MCP Servers]
C -->|https| E[Remote MCP APIs]
その理由
課題: MCP サーバーは通常、stdio 経由でローカルに実行されます。リモートマシン上のツールにアクセスしたり、チームで共有したりするには、エンドポイントを公開する必要があり、セキュリティ上のリスクが生じます。公開した MCP ツールを保護するのは複雑な場合があります。
解決策: MCP Gateway は OpenZiti のオーバーレイネットワークを利用して、「ダークサービス」を作成します。ダークサービスは次の特長を備えています。
- パブリック IP で待ち受けることはありません
- アクセスには暗号学的な ID が必要です
- ポートフォワーディングなしで NAT やファイアウォールを通過できます
- Agora のカタログやレイヤー1トンネルを通じて公開、提供できます
- 安全にデプロイするのが非常に簡単です
クイックスタート
MCP Gateway を初めてお使いですか? 手順を詳しく解説したスタートガイドをご覧ください。
1. インストール
go install github.com/openziti/mcp-gateway/cmd/...@latest
2. zrok を有効にする
注: mcp-gateway には zrok
v2.0.x以降が必要です。現在の推奨リリースは zrok v2.0.0-rc7 です。
zrok2 enable <your-zrok-token> # get token at https://api-v2.zrok.io
3. Gateway を実行する
config.yml を作成します。
aggregator:
name: "my-gateway"
version: "1.0.0"
backends:
- id: filesystem
transport:
type: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
- id: github
transport:
type: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "ghp_xxx"
mcp-gateway run config.yml
# outputs: {"share_token":"abc123..."}
4. エージェントから接続する
エージェントの設定に追加します。
{
"mcpServers": {
"my-tools": {
"command": "mcp-tools",
"args": ["run", "abc123..."]
}
}
}
これで完了です。エージェントは、1つの安全な接続を通じて両方のバックエンドのツールを使用できます。
ユースケース
複数のツールサーバーを集約する
ファイルシステム、GitHub、データベース、カスタムツールを1つの接続にまとめます。
backends:
- id: fs
transport: { type: stdio, command: mcp-server-filesystem, args: ["/data"] }
- id: github
transport: { type: stdio, command: mcp-server-github }
- id: postgres
transport: { type: stdio, command: mcp-server-postgres }
ツールには自動的に名前空間が付与されます。例:fs:read_file、github:create_issue、postgres:query。
リモートのツールサーバーを公開する
リモートマシン上で mcp-bridge を実行し、ローカルの MCP サーバーを公開します。
# on remote server
mcp-bridge mcp-server-custom --config /etc/custom.yml
# outputs share token
# from anywhere
mcp-tools run <share_token>
ブリッジと Gateway を連結する
Gateway は、リモートのブリッジ(または別の Gateway)をバックエンドとして接続できます。
backends:
- id: remote-tools
transport:
type: zrok
share_token: "token-from-bridge"
Agora 経由で提供・検出する
Gateway、bridge、tools は、zrok に加えて Agora レイヤー1トンネルを使用できます。Gateway は zrok と Agora の両方で同時にサービスを提供し、カタログ広告を公開するとともに、mcp-bridge --network=agora で公開されたバックエンドに接続できます。
agora:
enabled: true
serve:
enabled: true
advertisement:
publish: true
backends:
- id: remote-filesystem
transport:
type: agora
agora_tunnel: filesystem-relay
mcp-tools run --agora mcp-gateway-engineering
設定、CLI フラグ、統合ファイル、スモークテストのシナリオについては、Agora 統合をご覧ください。
HTTP および HTTPS の MCP サーバーに接続する
Gateway は、Streamable HTTP(デフォルト)またはレガシーの SSE トランスポートを使用して、HTTP(S) 経由でリモートの MCP サーバーを集約できます。SSE エンドポイントには protocol: sse を明示的に設定します。type: https は厳格で、https:// エンドポイントのみを受け付けます。type: http は http:// と https:// の両方に対応しますが、平文 HTTP を使用するには明示的な許可が必要です。
backends:
- id: remote-api
transport:
type: https
endpoint: "https://mcp.example.com/mcp"
headers:
Authorization: "Bearer sk-abc123"
- id: legacy-api
transport:
type: https
endpoint: "https://mcp.internal.corp/sse"
protocol: "sse"
tls:
ca_cert_file: "/etc/ssl/certs/internal-ca.pem"
stdio および zrok バックエンドと併用でき、必要に応じて自由に組み合わせられます。
ローカル開発環境や信頼できる内部ネットワークでは、平文 HTTP を明示的に許可できます。
backends:
- id: local-dev
transport:
type: http
endpoint: "http://localhost:8080/mcp"
allow_insecure: true
HTTP バックエンドのクライアントは直接接続し、デフォルトではリダイレクトを拒否します。より広範なネットワーク動作を意図的に許可する場合に限り、トランスポートで allow_environment_proxy: true または allow_redirects: true を設定してください。
永続的な共有
デフォルトでは、mcp-gateway と mcp-bridge はプロセスの終了時に消える一時的な共有を作成します。永続的な共有は zrok のサーバー側に保存されるため、共有トークンを変更せずにゲートウェイやブリッジを停止して再起動できます。
一時的な共有は、デフォルトで非公開かつ所有者のみがアクセスできます。ブリッジでは、繰り返し指定できるフラグを使って、他の zrok アカウントにアクセスを許可できます。
mcp-bridge --access-grant [email protected] mcp-filesystem /data
mcp-gateway の場合は、ゲートウェイの設定で同じアカウントのメールアドレスを zrok.share.access_grants に指定します。作成したアカウントはすでにアクセス権を持つため、リストに含める必要はありません。
# create a persistent share with a chosen name
zrok2 create share -s my-gateway
# the chosen name is the share token
# use the token in a gateway config (share_token: my-gateway) or bridge
mcp-gateway run config.yml
mcp-bridge --share-token my-gateway npx -y @modelcontextprotocol/server-filesystem /home/user
# the gateway/bridge can restart and reconnect to the same share
# when done, delete the share
zrok2 delete share my-gateway
名前を省略すると、zrok がランダムなトークンを生成します。
zrok2 create share
# outputs the share token
トークン名は 3~32 文字で、小文字の英数字とハイフン([a-z0-9-])のみ使用できます。
HTTP トランスポート
すべてのコンポーネントは、stdio に加えて HTTP ベースの MCP トランスポートをサポートしています。
mcp-tools を使って HTTP 経由で提供する:
# expose a zrok share as a local HTTP server
mcp-tools http <share_token> --bind 127.0.0.1:8080
# expose an Agora tunnel as a local HTTP server
mcp-tools http --agora <tunnel> --bind 127.0.0.1:8080
オプション:
--stateless- ステートレスモード(セッションを永続化しません)--json-response- ストリーミングレスポンスより JSON レスポンスを優先します--session-idle-timeout <duration>- 非アクティブなローカルセッションを指定時間後に閉じます。デフォルトは30m、0を指定すると無効になります
ゲートウェイとブリッジは、zrok と Agora を介して Streamable HTTP で MCP をネイティブに提供します。mcp-tools が直接提供する stdio トランスポートをサポートしていないクライアント向けに、ローカルの Streamable HTTP エンドポイントが必要な場合は、mcp-tools http を使用してください。
mcp-tools http は任意の数のローカルエージェントを提供し、それぞれにリモートゲートウェイまたはブリッジ上で専用の MCP セッションが割り当てられます。zrok のアクセス接続または Agora のアタッチメントは一度だけ開かれ、プロセスが存続する間維持されます。ローカルエージェントが接続すると新しいファブリックセッションが開かれ、切断時、セッションの期限切れ時、初期化の失敗時、または mcp-tools のシャットダウン時に閉じられます。バックエンドの状態はエージェントごとに分離され、ゲートウェイに直接接続するエージェントの場合とまったく同じです。--stateless モードでは所有するセッションがないため、リクエストごとにファブリックセッションが開閉されます。これは正しい動作ですが、呼び出しのたびにオーバーレイを介して完全な MCP ハンドシェイクを行います。
シャットダウン時、mcp-tools は進行中のハンドシェイクが完了するまで最大 5 秒待機するため、シャットダウン中に完了したセッションは放置されずに解放されます。ファブリックの HTTP クライアントにはタイムアウトが設定されていないため、この待機時間には上限が設けられています。ただし、この上限には許容されたコストが伴います。リモートセッションは、その initialize リクエストがゲートウェイまたはブリッジに到着した時点で作成されます。そのため、待機時間の上限に達したときにハンドシェイクのレスポンスがまだ処理中であれば、実際のバックエンドリソースを保持するリモートセッションが残り、mcp-tools では終了できなくなります。放棄したセッション数はログに記録され、リモート側で独自のアイドルタイムアウトによって解放されます。無期限に待機する方法では、応答しなくなったオーバーレイによってシャットダウンが永久に保留される可能性があります。
クライアントがセッションを終了せずに応答しなくなった場合でも、専用のバックエンド接続やブリッジのサブプロセスが無期限に保持されないよう、非アクティブな Streamable HTTP セッションは 30 分後に期限切れになります。この上限を調整するには、ゲートウェイの YAML で session_idle_timeout を設定するか、mcp-bridge または mcp-tools http に --session-idle-timeout <duration> を渡してください。明示的に 0 を指定するとアイドルタイムアウトが無効になり、クライアントがセッションを終了するかサーバーがシャットダウンするまで、これらのリソースが保持される場合があります。
ツールのフィルタリング
バックエンドごとに公開するツールを制御します。
backends:
- id: filesystem
transport: { type: stdio, command: mcp-server-filesystem }
tools:
mode: allow
list:
- "read_file"
- "list_directory"
# write operations not exposed
- id: github
tools:
mode: deny
list:
- "delete_*"
# everything except delete operations
アーキテクチャ
MCP Gateway は、接続するクライアントごとに分離されたセッションを作成します。
flowchart LR
subgraph Clients
A[Client A]
B[Client B]
end
A --> G[Gateway]
B --> G
subgraph Session A
G --> A1[Backend 1]
G --> A2[Backend 2]
end
subgraph Session B
G --> B1[Backend 1]
G --> B2[Backend 2]
end
各クライアントには専用のバックエンド接続が割り当てられます。状態は共有されず、相互に干渉することもありません。
ソースからのビルド
git clone https://github.com/openziti/mcp-gateway.git
cd mcp-gateway
go build ./cmd/mcp-gateway
go build ./cmd/mcp-bridge
go build ./cmd/mcp-tools
各バイナリには、ビルドメタデータを表示する version サブコマンドがあります。
mcp-gateway version
ローカルビルドでは開発者ビルド(例:v0.1.x [developer build])と表示されます。リリースバイナリには、バージョン、コミット、ビルド日時、ブランチ、ビルダーの情報が付与されます。
ドキュメント
- 設定例 - 詳細な説明が記載された設定ファイル
- Agora との統合 - Agora の提供、バックエンドの接続、mcp-tools のダイヤル、スモークシナリオ
- エンドツーエンドのスモークテストスイート -
make e2e、3 つすべてのコンポーネントを手動で実行して確認します - OpenZiti ドキュメント
- zrok ドキュメント
- MCP 仕様
ライセンス
Apache 2.0 - LICENSE を参照してください
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。