MCP/Bash outbound TCP to LAN IPs fails (EHOSTUNREACH) while built-in browser tool reaches the same host fine
Platform: macOS (Tahoe), Claude Code desktop app.
Summary: An HTTP-transport MCP server configured against a LAN IP (http://192.168.1.x:PORT/..., both a custom port and HA's default 8123 tested) consistently fails to connect with EHOSTUNREACH / "No route to host" — both from the app's own MCP connector dial and from Bash-tool subprocesses (curl, python3 socket.connect, socat). The built-in Browser pane tool (mcp__Claude_Browser__*), however, reaches the exact same host:port successfully every time (confirmed via real HTTP responses, not just TCP connect).
Repro:
- Configure a
user-kind MCP server (http transport) pointed at a real LAN IP:port reachable from the Mac (confirmed independently via the OS's own network stack —pingsucceeds, ARP resolves correctly, and Chromium-based tools reach it). - Session start /
/mcpReconnect fails:TypeError dialing http://<lan-ip>:<port> (EHOSTUNREACH). - From Bash tool (including with
dangerouslyDisableSandbox: true):curl,python3raw socket connect, andsocat(freshlybrew installed, unrelated to any Claude-specific binary) all fail identically and near-instantly withEHOSTUNREACH/ "No route to host" to the same host:port. - From the built-in Browser pane tool (
preview_start/navigateto the samehttp://<lan-ip>:<port>/): succeeds, returns real page content.
Isolation performed (all ruled out as the cause):
- ARP cache flush (
sudo arp -d) — same MAC re-resolves, no change. - macOS Local Network permission for Claude — already granted.
- Full app restart after config change — no change (confirmed config was picked up correctly, since the dialed URL updated to match the new config, but same error class on a totally different port).
- Target service itself confirmed healthy and listening (proper HTTP 404 returned to the Browser pane on an unmatched path).
- Target's own updates applied — no change.
- macOS Application Firewall — disabled, not the cause.
- Not a proxy issue — no
http_proxy/https_proxyenv vars set.
Conclusion: Node/Bash-tool-level outbound TCP to non-loopback LAN IPs appears to fail from within the Claude Code desktop app's own process/sandbox, while the embedded Chromium-based Browser pane tool is unaffected — strongly suggesting an App Sandbox / Seatbelt network entitlement difference between the main app process (and what it spawns for Bash/MCP) and the Browser pane's renderer process, rather than any issue with the target host, local network, or user configuration.
Impact: Any user-kind HTTP MCP server pointed at a LAN IP (not 127.0.0.1) cannot be reached at all from Bash tools or the MCP connector layer, only from the Browser pane — this blocks legitimate local-network integrations (e.g. Home Assistant) that aren't tunneled through 127.0.0.1.