2026 OpenClaw:リモート物理 Mac で MCP を接続——stdio と Streamable HTTP の再現 Runbook(spawn ENOENT、プロトコル不一致、ツールタイムアウト+CLI 断片+FAQ)
無人の物理 Mac ゲートウェイで OpenClaw を動かすチームが繰り返し踏む MCP の落とし穴は三つです。stdio の spawn ENOENT(PATH が削られた launchd 環境)、Streamable HTTP の版/Content-Type ズレ、そしてクライアント・ゲートウェイ・サーバーがバラバラに効かせるタイムアウトです。本稿では 7 ステップの展開、stdio/HTTP の意思決定表、コピペ可能な MCP サーバー JSON、症状別 Runbook、社内 SLO に貼れる数値、FAQ まで揃え、社内ドキュメントにそのまま転記できる形に整理します。
1. リモート Mac ゲートウェイで MCP が壊れる理由
MCP(Model Context Protocol)はトランスポート上の構造化メッセージに過ぎません。ノート PC では端末にエラーが直撃しますが、コロケーションやレンタルの Mac ではゲートウェイが launchd 下で動き、ログインシェルが無く、cwd も PATH も Homebrew や Volta の shim を含まない——その結果、stdio サーバーは最初の 1 行を吐く前に spawn ENOENT で落ちます。
- 環境ドリフト — 対話 SSH は
~/.zprofileを読みますがデーモンは読みません。SSH では動くコマンドがゲートウェイ下では ENOENT になります。 - トランスポート不一致 — Streamable HTTP/SSE はプロトコル改訂、
Accept、TLS 終端の挙動が揃っている必要があります。リバプロがバッファやヘッダ削除をすると「版不一致」や 406 として表れ、単純な切断とは見えません。 - タイムアウトの積層 — モデルクライアント、OpenClaw、MCP サーバー、ツール本体が別々の締切を持ちます。1 層だけ緩めると共有物理ノードにゾンビジョブが残ります。多層タイムアウトの設計は TestFlight 自動アップロードとタイムアウト/429 の記事 で整理した「どの経路が尾部を握るか」と同じ発想で切り分けます。
Streamable HTTP を Webhook と同じエッジに出す場合は、Bearer トークンとパス接頭辞の規律を OpenClaw 側のリバプロ運用と揃え、401/404 が MCP エラーに見えないようにしてください(社内 Runbook があれば同一チェックリストを流用します)。
2. stdio と Streamable HTTP:どちらのトランスポートか
同一ホストでは動く部品を最小にし、サーバー共有やプロキシ認証が必要になったら HTTP に移行します。
| 観点 | stdio MCP | Streamable HTTP MCP |
|---|---|---|
| 故障時の波及 | 子プロセス単位。ゲートウェイは 1 サーバーだけ再起動しやすい。 | ポートと証明書を共有。設定ミスは URL 経由の全クライアントに効く。 |
| PATH/cwd 感度 | 高い — ENOENT がデフォルトの失敗形。 | バイナリ解決は launchd 管理下で安定しやすいが、上流 URL 感度は残る。 |
| マルチテナント/遠隔クライアント | 手動で多重化しない限りゲートウェイ 1 プロセスあたり 1 系統。 | 自然 — HTTP 1 本に認証で多数の呼び出し。 |
| 可観測性 | ゲートウェイの構造化ログ+子の stderr。 | プロキシのアクセスログ、上流タイミング、ALPN/TLS トレースを追加。 |
3. 再現可能な 7 ステップ
- 身元の固定 — OpenClaw を所有するユーザー、LaunchAgent のラベル、
launchctl print相当で見える cwd を記録する。 - ゲートウェイ抜きで stdio 再生 — 同一ユーザーで
/bin/bash -lc 'which node; node -v'と、env ファイルまで揃えた MCP 起動コマンドを実行する。 - stdio 設定の硬化 —
commandの絶対パス、明示のargs、任意のcwd、env(下記 JSON 参照)。 - HTTP 経路(任意) — MCP HTTP を
127.0.0.1にバインドし、nginx/Caddy で TLS 終端。curl -vでAccept交渉を確認する。 - 版の固定 — OpenClaw 内の MCP クライアントとサーバー側 SDK/パッケージの major.minor を一致させ、変更履歴に両方を 1 行で残す。
- タイムアウト予算 — 現実的入力で
tools/callの P95 を測り、クライアント待ちを P95×1.5 程度にしつつハード上限を設ける。 - ログ契約 —
initialize/tools/list/tools/callを相関 ID 付き JSON 1 行で出す。
常時エージェントを再起動耐性まで含めて固める場合は、Cron/バックアップ/JSONL 可観測性の手順を別 Runbook と突き合わせ、同じ「無人 Mac」前提で環境変数と plist を二重管理しないようにしてください。
4. CLI 設定断片(JSON 例)
キー名は利用中の OpenClaw/ホスト設定に合わせてください。重要なのは絶対パスと明示 env です。
Node エントリポイントの stdio(macOS)
{
"mcpServers": {
"repo-tools": {
"command": "/opt/homebrew/bin/node",
"args": ["/usr/local/lib/mcp-servers/repo-tools/dist/main.js"],
"cwd": "/Users/shared/mcp/repo-tools",
"env": {
"PATH": "/opt/homebrew/bin:/usr/bin:/bin",
"NODE_ENV": "production"
}
}
}
}
プロファイル読込が必要なときの login-shell ラッパー
{
"mcpServers": {
"legacy-npx": {
"command": "/bin/bash",
"args": ["-lc", "exec npx --yes @example/[email protected]"],
"env": { "HOME": "/Users/shared" }
}
}
}
Streamable HTTP エンドポイント(クライアント側参照)
{
"mcpServers": {
"http-shared": {
"url": "https://mcp.internal.example.com/v1/mcp",
"headers": {
"Authorization": "Bearer ${MCP_EDGE_TOKEN}"
}
}
}
}
5. 症状別 Runbook
5.1 spawn ENOENT(stdio)
| 信号 | 想定原因 | 修正順 |
|---|---|---|
node の ENOENT |
デーモン PATH に Homebrew が無い。 | command を絶対パスにするか env.PATH を前置。 |
| スクリプトパスの ENOENT | cwd 違い、サービスユーザーからシンボリックリンクが見えない。 | cwd を固定し、symlink を realpath に置換。 |
| SSH のみ成功 | 対話シェルの export と launchd が不一致。 | bash -lc ラッパーか plist の EnvironmentVariables へ移行。 |
5.2 プロトコル版/406(Streamable HTTP)
サーバーとクライアントのハンドシェイクログを並べて比較します。サーバーが text/event-stream を期待しているのにプロキシが gzip を噛ませてフラッシュしないと、パッケージの版表記は揃っていても「版不一致」に見える停滞が起きます。
5.3 ツールタイムアウト
(A)モデル/ルータ待ち、(B)ゲートウェイ上流、(C)MCP サーバー内部の 3 タイマーを図にします。最もタイトな層から広げ、トレースでキュー滞留が証明された隣接層だけを緩めます。長尺の Git/依存取得は ビルドキャッシュと越境レイテンシの記事 と同様、単一ブロッキング呼び出しに押し込めない方が安全です。
6. SLO 資料に貼れる数値
- 約 4W — Apple Silicon Mac mini の待機電力の目安。軽量ゲートウェイ+ SSH を載せた TCO 試算に使える x86 タワーとの対比値。
- 25 秒 — 共有ノード上で「速い」
tools/callP95 の経験則上限。超えるならツール分割や部分結果ストリームへ寄せ、タイムアウトだけを無限に伸ばさない。 - 600 秒 — 大規模リポジトリ走査などのメンテ用途は非同期ジョブ+ポーリングへ逃がし、単一 MCP 呼び出しで塞がない。
7. FAQ
MCP サーバーを root で動かすべきですか?
専用サービスユーザーとワークスペース ACL を推奨します。root は macOS のプライバシイプロンプトや TCC 監査を難しくします。
Rosetta は MCP バイナリに効きますか?
効きます。arm64 の Node と x64 専用ネイティブ拡張が混ざるとクラッシュループとなり、外からはタイムアウトに見えがちです。アーキテクチャをサーバー単位で統一してください。
企業の HTTPS インスペクション証明書は流用できますか?
サービスユーザーが信頼するキーチェーンに MITM ルートを入れる必要があります。入れないと Streamable HTTP の TLS が不透明なハンドシェイク失敗になります。
プロトコル改訂はどこで追跡しますか?
社内 Wiki に 1 行互換表:OpenClaw ビルド、MCP SDK 版、サーバーパッケージのハッシュ、最後に tools/list スモークを回した日。
8. 静かで省電力な Mac mini でこのスタックを回す
stdio MCP は環境の完全一致を要求する仕事です。長期稼働の macOS ホストならパス構成が安定し、Gatekeeper と SIP により実行物の境界も読みやすく、Windows VM のようなドライバ揺れと組み合わせなくて済みます。Apple Silicon の Mac mini は待機電力が数ワット級に抑えやすく、ファン静音で 24 時間運用向きです。
OpenClaw と MCP サイドカーをリモートゲートウェイとして標準化するなら、エージェント・ビルドツール・可観測性エージェントを同一アーキテクチャに寄せられる Mac mini M4 クラスに集約すると部品点数が減ります。FileVault と TCC により、Linux イメージ混在より監査ストーリーを組み立てやすい場面も多いです。
上記 Runbook をステージングで叩き直すなら、コストパフォーマンスの良い物理アンカーとして Mac mini M4 が現実的な起点です。検証済みの JSON をそのまま載せられるノードを手元に置き、運用に載せてください。
OpenClaw+MCP 向けに安定した物理 Mac が必要ですか?
本 Runbook と同じ macOS ツールチェーンを載せた Mac mini ノードをレンタル。省電力・静音の 24 時間稼働と、stdio サーバー向けの読みやすいパス構成に向いています。