diff --git a/README.md b/README.md index 80ebabc..a4fbd69 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ The bundled `config.json` configures two MCP servers: | Server | Type | Notes | |---|---|---| | `chrome-devtools` | local (`npx`) | Browser automation via Chromium | -| `jetbrains` | remote (SSE) | JetBrains IDE integration, host configured via `JETBRAINS_IDE_HOST` | +| `jetbrains` | remote (SSE) | JetBrains IDE integration via `host.docker.internal:${JETBRAINS_MCP_PORT}` (default `64343`) | ## Usage @@ -64,8 +64,9 @@ services: - opencode-state:/home/skpr/.local/state/opencode environment: ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} - JETBRAINS_IDE_HOST: ${JETBRAINS_IDE_HOST:-host.docker.internal} - network_mode: "${OPENCODE_NETWORK_MODE:-}" + JETBRAINS_MCP_PORT: ${JETBRAINS_MCP_PORT:-64343} + extra_hosts: + - "host.docker.internal:host-gateway" stdin_open: true tty: true restart: unless-stopped @@ -75,12 +76,21 @@ volumes: opencode-state: ``` -> **macOS (Docker Desktop):** `host.docker.internal` is provided automatically — no extra config needed. +> **JetBrains MCP:** The JetBrains MCP server only binds to `127.0.0.1` and validates the `Host` +> header. Use `caddy` on the host to reverse-proxy it so the container can reach it via +> `host.docker.internal` with the correct `Host` header. > -> **Linux:** PHPStorm binds to `127.0.0.1` only. Set the following in your `.env` file or shell: -> ``` -> OPENCODE_NETWORK_MODE=host -> JETBRAINS_IDE_HOST=127.0.0.1 +> ```bash +> # Install +> brew install caddy # macOS +> # or +> apt install caddy # Linux +> +> # Run on the host before starting the container. +> # caddy listens on 64343 (JETBRAINS_MCP_PORT) and forwards to JetBrains MCP on 64342, +> # rewriting the Host header to 127.0.0.1:64342 as PhpStorm expects. +> # If 64343 is already in use, pick any free port and set JETBRAINS_MCP_PORT in your .env. +> caddy reverse-proxy --from :64343 --to 127.0.0.1:64342 > ``` Start the container in the background. It will restart automatically after a reboot: @@ -111,4 +121,5 @@ Pass your API key via a `.env` file (ensure it is in `.gitignore`) — do not ba ``` ANTHROPIC_API_KEY=sk-ant-... +JETBRAINS_MCP_PORT=64343 # only needed if 64343 is already in use ``` diff --git a/config.json b/config.json index a1740be..8f2891a 100644 --- a/config.json +++ b/config.json @@ -17,7 +17,7 @@ }, "jetbrains": { "type": "remote", - "url": "http://{env:JETBRAINS_IDE_HOST}:64342/sse", + "url": "http://host.docker.internal:{env:JETBRAINS_MCP_PORT}/sse", "enabled": true } } diff --git a/docker-compose.example.yml b/docker-compose.example.yml index 94bc24b..ff92669 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -12,15 +12,17 @@ services: # Pass your Anthropic API key at runtime. Never hard-code it here. # Add ANTHROPIC_API_KEY to a .env file (gitignored) or export it in your shell. ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} - # JetBrains MCP server host. - # macOS (Docker Desktop): host.docker.internal resolves to the host automatically. - # Linux: PHPStorm binds to 127.0.0.1 only, so use network_mode: host (below) - # and set this to 127.0.0.1. - JETBRAINS_IDE_HOST: ${JETBRAINS_IDE_HOST:-host.docker.internal} - # Linux: PHPStorm only listens on 127.0.0.1, so set JETBRAINS_IDE_HOST=127.0.0.1 - # and OPENCODE_NETWORK_MODE=host in your .env file or shell. - # network_mode: host is Linux-only and not required on macOS (Docker Desktop). - network_mode: "${OPENCODE_NETWORK_MODE:-}" + # Port socat is listening on (forwarding to the JetBrains MCP server on the host). + # 64342 is taken by JetBrains itself, so socat must use a different port (default: 64343). + # Override if 64343 is already in use on your machine. + JETBRAINS_MCP_PORT: ${JETBRAINS_MCP_PORT:-64343} + # Expose host.docker.internal on Linux (Docker Desktop provides this automatically on macOS). + # JetBrains MCP only binds to 127.0.0.1 and validates the Host header; run caddy on the host + # to reverse-proxy it: caddy reverse-proxy --from :64343 --to 127.0.0.1:64342 — see README. + # Alternatively, if opencode shares a Compose project with your app (e.g. alongside nginx), you can use + # network_mode: "service:nginx" to share its network namespace — remove extra_hosts if you do this. + extra_hosts: + - "host.docker.internal:host-gateway" stdin_open: true tty: true # Restart automatically so the container survives reboots.