当サイトの一部ページには、アフィリエイト・アドセンス・アソシエイト・プロモーション広告を掲載しています。

Amazonのアソシエイトとして、Security Akademeiaは適格販売により収入を得ています。

広告配信等の詳細については、プライバシーポリシーページに掲載しています。

消費者庁が、2023年10月1日から施行する景品表示法の規制対象(通称:ステマ規制)にならないよう、配慮して記事を作成しています。もし問題の表現がありましたら、問い合わせページよりご連絡ください。

参考:令和5年10月1日からステルスマーケティングは景品表示法違反となります。 | 消費者庁

「ホストOS上のMCP Inspector操作UIページ」から「WSL上のMCPサーバー」にConnectできない問題を解決した記録

WSL(Ubuntu)上でMCPサーバー(stdioベース)を検証するためにMCP Inspectorツールを使っていたところ、ホストOS(Windows)でMCP Inspectorの操作UIが開くのに、Connectボタンを押しても接続できないという状況に何度か遭遇しました。
具体的に言えば、UI上で各項目を設定してConnectを押したところ、以下の現象が発生しました。
・エラーが出る
・無反応
・WSL側のサーバーログが一切増えない
また同様の問題が起きたときにすぐに対処できるか不安でしたので、忘備録として記事にしておきます。

【前提】環境状態

以下の二重サンドボックスを構築済みとします。

Windows(ホストOS)
 └─ WSL2(実験専用Ubuntu、名前は任意)
     └─ Python venv(プロジェクト単位)

【症状の整理】何が起きていたのか

発生していた状況をそのまま列挙します。

  • MCP Inspector(以後、Inspectorと略する)のUIは表示される
  • Command/Argumentsの入力欄も操作できる
  • Connectを押すとエラーが出る、または接続できない
  • サーバープロセス側(WSL)にログが出ない

ここで重要なのは最後の点です。

Connectボタンを押してもサーバー側のstderr/stdoutに何も出ませんでした。

元々の自作MCPサーバーでは、stderrには MCPサーバーのログを、stdoutにはMCPクライアントへのメッセージを出力するように設計しています[1]https://modelcontextprotocol.io/specification/2025-11-25/basic/transports

これは 「サーバーに処理が届いていない」ことを強く示唆します。

試行錯誤の過程でさまざまな症状を見受けられましたが、ここでは上記の内容に絞ります。
余談として、どういった症状が出たのかを言及しておくと、UI自体が開かないケース、localhost指定でUIが表示されないケースもありました。
・「/usr/bin/npx @modelcontextprotocol/inspector」コマンドを実行しても、ホストOS側で既定ブラウザーが開かない。
・手動でブラウザーを開いてhttp://localhost:6274にアクセスしようとしてもできない
・WSL側から「wslview http://127.0.0.1:6274」コマンドを実行すると、ホストOS側でブラウザーが開らくが、UIページが表示されない。
・http://<WSLのIPアドレス>:6274だとUIページが表示されるが、ボタンを押してもエラーが出る

MCP Inspectorとは

MCP Inspector は、MCPクライアント兼デバッグ用プロキシーです。UIそのものではありませんし、サーバーでもありません。

一言で言うなら、「stdioで動くMCPサーバーを、人間が観測・操作できる形に変換する中継ツール」です。

[ Browser UI ]
      │  HTTP / SSE
      ▼
[ Inspector Proxy (Node.jsプロセス) ]
      │  stdio (stdin/stdout)
      ▼
[ サーバープロセス(例:Python製のMCPサーバー)]
  • UI:表示・操作だけ
  • Proxy:すべての実体
  • サーバー:受動的に応答するだけ

ポイントは以下です。

  • ブラウザーはstdioを扱えない
  • サーバーはHTTPを話さない
  • 両者の間をつなぐのがInspector Proxy

MCP Inspectorとは、MCP サーバーを起動・接続・観測するためのクライアント兼プロキシーです。
MCP Inspectorは以下のようにWSL上で実行します。
すると、ホストOS側の既定ブラウザーが勝手に立ち上がって、操作UIページが表示されます。

「UIが開く」と「接続できる」は別物

実際に混乱を生んだのは、「UIが開いている=サーバーと通信できている」という誤解でした。

これは成立しません。

実際に起きうる状態 <パターン1>

[ Browser UI ]        ← 表示される
      │
      ✕(通信できていない)
[ Inspector Proxy ]   ← 別世界で動いている
      │
      ✕
[ サーバー ]          ← 起動すらしていない

実際に起きうる状態 <パターン2>

[ Browser UI ]        ← 表示される
      │
      ✕(通信できていない)
[ Inspector Proxy ]   ← 別世界で動いている
      │
      ▼
[ サーバー ]          ← 起動している

以上の状態では、ブラウザーで開いたUIでConnectを何度押しても、サーバー側は沈黙したままです。

【切り分けの第一歩】Proxy 側ログを見る

今回もっとも役に立ったのは、Inspector Proxyを起動したターミナルのログでした。

正常に「UI→Proxy」が届いた場合

Connectを押した直後に、次のようなログが出ます。

New STDIO connection request
STDIO transport: command=./venv/bin/python, args=server.py
Created client transport
Created server transport

これは、以下を意味します。

  • UIから接続要求が届いた
  • Proxyがサーバープロセスを起動しようとしている

何も出ない場合

Connectを押しても何も表示されない場合は、以下を疑う段階です。

  • 「UI → Proxy」の通信が成立していない
  • ネットワーク境界(WSL/Windows)
  • 認証トークン
  • Proxyの待受アドレス

「Proxy→サーバー起動」で失敗する典型例

Proxyログに"Error: spawn ./venv/bin/python ENOENT"といったエラーが出ることがあります。

これは、以下の原因によってよく起こります。

  • 指定したコマンドが見つからない
  • Proxyが想定と違う世界(Windows側)で動いている

実際、Inspector実行後のターミナルログに"C:\Users\…\npm-cache\_npx\…"のようなパスが混じっていたら要注意です。

この場合、以下に示すような世界線の不一致が起きています。

[ Inspector Proxy (Windows node) ]
        ↓
./venv/bin/python(WSLのパス)

【今回の本当の原因】Proxyがどの世界で動いているか

今回ややこしかったのは、WSL上でnpxを実行していても、内部で"cmd.exe"が呼び出され、実行コンテキストがWindows側へフォールバックするケースがあった点です。実際、ログには次のような出力がありました。

'¥¥wsl.localhost¥mcp-ubuntu¥home¥ipusiron¥mcp-sandbox'
上記の現在のディレクトリで CMD.EXE を開始しました。
UNC パスはサポートされません。Windows ディレクトリを既定で使用します。

「CMD.EXEを開始しました」とあり、Node/npx自身がWindowsの"cmd.exe"を呼び出していることを意味します。

これは、WSLの作業ディレクトリがWindows側ではUNCパスとして扱われ、"cmd.exe"がそれをカレントにできないため、Windowsディレクトリへフォールバックしたことを示しています。その結果、Inspector Proxyの実行環境が意図せずWindows側に切り替わり、WSL上の相対パス("./venv/bin/python")が見えなくなる状況が発生していました。

内部的の構成は次のとおりです。

[ Browser UI (Windows) ]
      │
[ Inspector Proxy (Windows node) ]
      │
      ✕ ./venv/bin/python が見えない

WindowsノードからはWSL内(その中のvenv環境はもちろん)にアクセスできていなかったのです。

この状態では、以下のように非常に分かりにくい症状になります。

  • UIは開く
  • Connectも押せる
  • しかし サーバーは永遠に起動しない

【解決の決め手】Proxyとサーバーを同じ世界に揃える

最終的に安定した構成はこれでした。

[ Browser UI (Windows) ]
      │
[ Inspector Proxy (WSL / Node.js) ]
      │
[ サーバー (WSL / Python) ]

具体的には、以下を実行しました。

# WSLにNode.jsをちゃんと入れて、WSLのnpxを使う。
ipusiron@MHL:~/mcp-sandbox$ node -v
v12.22.9 ←古い!? 入れ直すついでに、一気にNode 20にする。

# WSLにNode 20を入れる
ipusiron@MHL:~/mcp-sandbox$ curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
ipusiron@MHL:~/mcp-sandbox$ sudo apt-get install -y nodejs
(中略)
Preparing to unpack .../nodejs_20.20.0-1nodesource1_amd64.deb ...
Unpacking nodejs (20.20.0-1nodesource1) over (12.22.9~dfsg-1ubuntu3.6) ...
dpkg: error processing archive /var/cache/apt/archives/nodejs_20.20.0-1nodesource1_amd64.deb (--unpack):
 trying to overwrite '/usr/include/node/common.gypi', which is also in package libnode-dev 12.22.9~dfsg-1ubuntu3.6
dpkg-deb: error: paste subprocess was killed by signal (Broken pipe)
Errors were encountered while processing: ←エラー発生。
 /var/cache/apt/archives/nodejs_20.20.0-1nodesource1_amd64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)
# Ubuntu標準のNode 12系の開発ヘッダ(libnode-dev)が残っていて、NodeSourceのnodejsとファイル衝突したことがエラーの原因。
# 以下ではこれを解消する。
ipusiron@MHL:~/mcp-sandbox$ sudo apt remove -y libnode-dev ←競合している libnode-dev を外す
ipusiron@MHL:~/mcp-sandbox$ sudo apt --fix-broken install -y ←いったん壊れた状態を修復1
ipusiron@MHL:~/mcp-sandbox$ sudo dpkg --configure -a ←いったん壊れた状態を修復2
ipusiron@MHL:~/mcp-sandbox$ sudo apt install -y nodejs ←Node.js 20を再インストール

# WSL側でNode/npxを確認
ipusiron@MHL:~/mcp-sandbox$ node -v
v20.20.0
ipusiron@MHL:~/mcp-sandbox$ which node
/usr/bin/node
ipusiron@MHL:~/mcp-sandbox$ npx -v
10.9.3
ipusiron@MHL:~/mcp-sandbox$ which npx
/usr/bin/npx

# WSL側のnpxでInspectorを起動
ipusiron@MHL:~/mcp-sandbox$ export DANGEROUSLY_OMIT_AUTH=true ←認証エラーを回避するため
ipusiron@MHL:~/mcp-sandbox$ /usr/bin/npx inspector@0.19.0 ←今回は「0.19.0」を指定。
# 以下の画像のように、6行のワーニングが表示されるが、MCPサーバーとクライアントの通信実験としてはうまくいったので、一応通信成功とする。

この状態にすると、Connectを押した瞬間に以下の挙動を示しました。

  • Proxyログが流れ
  • サーバーが起動し
  • initializeがHistoryに表示

最後の「/usr/bin/npx inspector@0.19.0」コマンドの代わりに、従来通り「/usr/bin/npx inspector」コマンドを実行すると、ホストOS側でUIが開きません。wslviewコマンドで、WSL側から無理やり開くことはできます(でもページは表示されない)。

チェックリスト:UIは開くのに接続できないとき

今回の経験から、次の順で切り分けると迷いません。

  1. Proxy側ログに接続要求が来ているか
  2. Proxyが どのnode/npxで動いているか
  3. 「Proxy → サーバー」のspawnが成功しているか
  4. サーバー側 stderr にログが出ているか
  5. 初期化ハンドシェイク(initialize)がHistoryに出ているか

サーバー実装を疑うのは、これらを潰してからで十分です。

【補足】今回の話はMCP固有ではない

今回 MCP Inspectorを使いましたが、構造的には次のようなツールでも同じ問題が起こり得ます。

  • Language Server Protocol(LSP)
  • Debug Adapter Protocol(DAP)
  • JSON-RPC over stdio の各種ツール
  • ブラウザーUI+ローカルプロセスを橋渡しするデバッガー全般

共通しているのは、「UI」「Proxy」「サーバー」が別プロセスで、別の世界線で動くという点です。

おわりに

今回の問題は、設定ミスというより「構造を理解していないと切り分けられないタイプの罠」でした。
逆に言えば、「どこまで通信が届いているか」「どのプロセスがどの世界で動いているか」を意識するだけで、この種の問題は 観測できる問題になります。
同じように「UIは開くのに接続できない」という状況に遭遇した人の助けになれば幸いです。