devcontainer内のClaude CodeからホストのUnity MCPへ接続する方法 - socatによるポート中継とセキュリティ考慮事項
Unity MCP(Model Context Protocol)サーバーをホストマシンで起動し、devcontainer内のClaude Codeから接続したい場合、いくつかの課題に直面します。この記事では、実際に遭遇した問題とその解決策を、再現可能な手順とともに解説します。
この記事の対象読者:
- Unity + MCP for Unity を使って Claude Code と連携したい方
- devcontainer環境でホストマシンのサービスに接続したい方
- Dockerネットワークとポート中継について理解を深めたい方
背景と問題
アーキテクチャ
Unity MCP for Unity はホストマシン(macOS)で動作し、HTTP Server として 127.0.0.1:8080 でリッスンします。一方、Claude Code は devcontainer という隔離された Linux 環境で動作しています。
┌─────────────────────────────────────────────────┐
│ ホスト (macOS) │
│ ┌─────────────────┐ │
│ │ Unity Editor │ │
│ │ (MCP Server) │ │
│ │ 127.0.0.1:8080 │ │
│ └─────────────────┘ │
│ ▲ │
│ │ │
│ ┌────────┼──────────────────────────────┐ │
│ │ devcontainer │ │
│ │ │ │ │
│ │ ┌─────┴─────────┐ │ │
│ │ │ Claude Code │ │ │
│ │ │ (MCP Client) │ │ │
│ │ └───────────────┘ │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
直面した課題
devcontainer内から localhost:8080 にアクセスしようとすると、コンテナ自身の 8080 ポートに接続しようとするため、ホストマシンの Unity MCP には到達できません。
Dockerには host.docker.internal という特殊なホスト名があり、これを使えばホストマシンにアクセスできますが、Unity MCP は 127.0.0.1 でのみリッスンしているため、外部から接続できません。
解決策の検討
方式1: Unity MCP を 0.0.0.0 でバインド
Unity MCP の設定を変更して、全インターフェース(0.0.0.0)でリッスンさせる方法です。
メリット:
- 設定が簡単
- 追加ツール不要
デメリット:
- セキュリティリスク(同一ネットワーク全体に公開)
- Unity MCP の設定変更が必要
方式2: socat によるポート中継(推奨)
ホストマシンで socat を使い、別のポート(8081)で受けたリクエストを Unity MCP の 127.0.0.1:8080 に中継する方法です。
メリット:
- Unity MCP の設定変更不要
- バインドアドレスを柔軟に選択可能
- 一時的な接続として管理しやすい
デメリット:
- socat のインストールが必要
- ポート中継の理解が必要
この記事では、より柔軟で安全な方式2(socat) を採用します。
socatによるポート中継の実装
socatのインストール
macOSではHomebrewで簡単にインストールできます。
brew install socat
ポート中継スクリプトの作成
Unity MCP への接続を中継するスクリプトを作成しました。
.devcontainer/scripts/start-socat.sh:
#!/bin/bash
# Unity MCP用socat中継スクリプト(セキュア版)
# macOSのホスト側で実行
set -e
echo "======================================"
echo "Unity MCP socat Bridge (Secure)"
echo "======================================"
# 既存のsocatプロセスを停止
if pgrep -f "socat.*8081.*8080" > /dev/null; then
echo "Stopping existing socat process..."
pkill -f "socat.*8081.*8080" || true
sleep 1
fi
# Unity MCPサーバーが起動しているか確認
if ! lsof -i :8080 -P -n | grep -q "python.*LISTEN"; then
echo "⚠ Warning: Unity MCP server is not running on port 8080"
echo ""
echo "Please start Unity Editor and ensure MCP For Unity is active."
exit 1
fi
# セキュアモード: localhostのみでバインド
BIND_ADDRESS="127.0.0.1"
echo ""
echo "Starting socat bridge..."
echo " Bind address: ${BIND_ADDRESS}:8081"
echo " Target: 127.0.0.1:8080 (Unity MCP)"
echo " Mode: Secure (localhost only, Docker port forwarding)"
echo ""
# socatをバックグラウンドで起動
socat TCP-LISTEN:8081,bind=${BIND_ADDRESS},fork TCP:127.0.0.1:8080 > /tmp/socat-unity-mcp.log 2>&1 &
SOCAT_PID=$!
# 起動確認
sleep 1
if ps -p $SOCAT_PID > /dev/null; then
echo "✓ socat started successfully (PID: $SOCAT_PID)"
echo ""
echo "To stop: pkill -f 'socat.*8081.*8080'"
echo "View logs: tail -f /tmp/socat-unity-mcp.log"
else
echo "✗ Failed to start socat"
exit 1
fi
このスクリプトは以下の機能を持ちます:
- 既存の socat プロセスを自動停止
- Unity MCP の起動確認
127.0.0.1:8081→127.0.0.1:8080のポート中継- エラーハンドリングとログ出力
スクリプトの実行
# ホストマシン(macOS)で実行
chmod +x .devcontainer/scripts/start-socat.sh
./.devcontainer/scripts/start-socat.sh
出力例:
======================================
Unity MCP socat Bridge (Secure)
======================================
Starting socat bridge...
Bind address: 127.0.0.1:8081
Target: 127.0.0.1:8080 (Unity MCP)
Mode: Secure (localhost only, Docker port forwarding)
✓ socat started successfully (PID: 12345)
To stop: pkill -f 'socat.*8081.*8080'
View logs: tail -f /tmp/socat-unity-mcp.log
devcontainer側の設定
devcontainer.json の設定
devcontainerから socat経由でUnity MCPに接続するため、環境変数とポートフォワーディングを設定します。
.devcontainer/devcontainer.json:
{
"name": "Unity MCP Development",
"containerEnv": {
"UNITY_HTTP_URL": "http://host.docker.internal:8081",
"UNITY_MCP_API_KEY": "unity-mcp-dev-key"
},
"forwardPorts": [8081],
"portsAttributes": {
"8081": {
"label": "Unity MCP Server (via socat)",
"onAutoForward": "silent"
}
}
}
設定のポイント:
UNITY_HTTP_URL: ホストの 8081 ポートに接続(socat経由)forwardPorts: Docker のポートフォワーディング機能を使用host.docker.internal: Docker for Mac/Windows で提供される特殊ホスト名
MCP接続の設定
devcontainer内でClaude CodeにUnity MCPサーバーを登録します。
# devcontainer内で実行
claude mcp add --transport http -s local UnityMCP \
"http://host.docker.internal:8081/mcp" \
--header "Authorization: Bearer unity-mcp-dev-key"
接続確認とトラブルシューティング
SSE (Server-Sent Events) エラーについて
接続確認のため、curl で Unity MCP にアクセスしてみましょう。
# devcontainer内で実行
curl http://host.docker.internal:8081/mcp
すると、次のようなエラーが返ってきます:
{
"jsonrpc": "2.0",
"id": "server-error",
"error": {
"code": -32600,
"message": "Not Acceptable: Client must accept text/event-stream"
}
}
これは正常な応答です! ✅
最初は接続エラーかと思いましたが、調査の結果、Unity MCP は SSE (Server-Sent Events) プロトコルを使用していることが判明しました。
SSEプロトコルとは
SSE は HTTP 上でサーバーからクライアントへの一方向ストリーミングを実現するプロトコルです。クライアントは Accept: text/event-stream ヘッダーを送信する必要があります。
通常の curl は Accept: */* を送信するため、Unity MCP が拒否します。これは接続が成功している証拠であり、以下を確認できています:
- ✅
host.docker.internal:8081への到達成功 - ✅ socat によるポート中継が動作
- ✅ Unity MCP サーバーが正常に応答
Claude Code の MCP client は適切なヘッダーを送信するため、実際の使用では問題ありません。
正しいHTTPステータスコードの確認
SSEエラーのHTTPステータスコードを確認してみましょう。
curl -s -o /dev/null -w "%{http_code}" http://host.docker.internal:8081/mcp
期待される結果: 406(Not Acceptable)
これが返れば、接続は成功しています。
接続失敗のパターン
以下のエラーが出た場合は、それぞれ対処が必要です。
Connection refused:
curl: (7) Failed to connect to host.docker.internal port 8081: Connection refused
原因:
- socat が起動していない
- または Unity MCP サーバーが停止している
解決策:
# ホストマシンで socat を起動
./.devcontainer/scripts/start-socat.sh
# Unity Editor で MCP For Unity を起動
401 Unauthorized:
{"error": {"message": "Unauthorized"}}
原因: API Key の不一致
解決策:
- Unity Editor の API Key 設定を確認
- devcontainer 側の設定を再実行
Claude Code での動作確認
Claude Code のセッション内で、Unity MCP のツールが利用可能か確認します。
利用可能なツール一覧を確認してください
以下のような Unity MCP ツールが表示されれば成功です:
mcp__UnityMCP__manage_scenemcp__UnityMCP__manage_gameobjectmcp__UnityMCP__manage_script
セキュリティ考慮事項
socat によるポート中継では、バインドアドレスの選択が重要です。
バインドアドレスの選択肢
1. 127.0.0.1(推奨)
socat TCP-LISTEN:8081,bind=127.0.0.1,fork TCP:127.0.0.1:8080
特徴:
- localhost のみでリッスン
- Docker のポートフォワーディング機能と組み合わせる
- 最もセキュア
推奨理由:
- 外部ネットワークから完全に隔離
- Docker が内部的にポート接続を処理
- 同一マシン内でのみ通信
2. 192.168.x.x(WiFiインターフェース)
socat TCP-LISTEN:8081,bind=192.168.1.100,fork TCP:127.0.0.1:8080
特徴:
- WiFi 経由でのみアクセス可能
- 同一ネットワーク内の他のデバイスからもアクセス可能
注意点:
- DHCP でIPアドレスが変わる可能性がある
- ファイアウォール設定が必要
- 公共WiFiでは使用しない
3. 0.0.0.0(非推奨)
socat TCP-LISTEN:8081,bind=0.0.0.0,fork TCP:127.0.0.1:8080
特徴:
- 全ネットワークインターフェースでリッスン
- 同一ネットワーク全体に公開
リスク:
- 最もセキュリティリスクが高い
- 同一WiFi上の全デバイスからアクセス可能
- API Key認証が必須
推奨事項
devcontainer + Unity MCP の用途では、127.0.0.1 バインド + Docker ポートフォワーディング を推奨します。
追加のセキュリティ対策:
-
API Key設定必須
- 推測困難な値を使用
- 定期的に変更
-
macOS ファイアウォール
- システム設定からファイアウォールを有効化
- 必要なアプリケーションのみ許可
-
使用時のみ起動
- 作業終了後は socat を停止
pkill -f 'socat.*8081.*8080'
-
公共WiFi使用時
- VPN 経由での接続を推奨
- または一時的に接続を無効化
まとめ
devcontainer 内の Claude Code からホストマシンの Unity MCP へ接続するには、以下の手順を実施します。
実装手順の要約
-
socat をインストール
brew install socat -
ホストマシンで socat を起動
./.devcontainer/scripts/start-socat.sh -
devcontainer.json を設定
UNITY_HTTP_URLをhttp://host.docker.internal:8081に設定forwardPortsで 8081 を指定
-
Claude Code に MCP サーバーを登録
claude mcp add --transport http -s local UnityMCP \ "http://host.docker.internal:8081/mcp" \ --header "Authorization: Bearer unity-mcp-dev-key" -
接続確認
- curl で HTTP 406 が返ることを確認
- Claude Code でツールが表示されることを確認
重要なポイント
- SSEエラーは正常:
text/event-streamエラーは接続成功のサイン - セキュアなバインド:
127.0.0.1でバインドし、Docker ポートフォワーディングを使用 - API Key認証: セキュリティのため必ず設定
- 一時的な中継: 使用時のみ socat を起動
トラブルシューティングのチェックリスト
接続できない場合は、以下を順番に確認してください。
- Unity MCP が起動しているか(
lsof -i :8080) - socat が起動しているか(
ps aux | grep socat) - devcontainer の環境変数が正しいか(
echo $UNITY_HTTP_URL) - curl で HTTP 406 が返るか
- API Key が一致しているか
これらの手順により、devcontainer環境でもUnity MCPの機能をフルに活用できるようになります。socat によるポート中継は、他のローカルサービスへの接続にも応用できる汎用的な手法です。