Skip to content

Commit c9c0259

Browse files
julienldclaude
andauthored
fix: resolve Docker environment variable validation error (#354) (#356)
* fix: resolve Docker environment variable validation error (#354) - Revert fastmcp config files to use hardcoded port/path values - fastmcp-http.json: port 8086, path "/mcp" - fastmcp-sse.json: port 8087, path "/mcp" - fastmcp-webclient.json: port 8086, path "/mcp" - Update Docker docs to use ha-mcp-web command instead of fastmcp run - Add documentation for customizing port/path via environment variables Root cause: FastMCP doesn't expand ${VAR:-default} syntax in JSON before Pydantic validates. The ha-mcp-web command reads MCP_PORT and MCP_SECRET_PATH environment variables directly in Python code (__main__.py:304-305). Fixes #354 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> * fix: use correct default port for ha-mcp-sse (8087) - Update _get_http_runtime to accept default_port parameter - Set ha-mcp-sse to use port 8087 (was incorrectly using 8086) - Add documentation note about Docker port mapping Addresses code review feedback from Gemini Code Assist: - Prevents port conflict between ha-mcp-web (8086) and ha-mcp-sse (8087) - Clarifies that both -p and MCP_PORT must match for custom ports 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent f4a72de commit c9c0259

5 files changed

Lines changed: 43 additions & 17 deletions

File tree

fastmcp-http.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
"deployment": {
88
"transport": "streamable-http",
99
"host": "0.0.0.0",
10-
"port": "${MCP_PORT:-8086}",
11-
"path": "${MCP_SECRET_PATH:-/mcp}",
10+
"port": 8086,
11+
"path": "/mcp",
1212
"env": {
1313
"HOMEASSISTANT_URL": "${HOMEASSISTANT_URL}",
1414
"HOMEASSISTANT_TOKEN": "${HOMEASSISTANT_TOKEN}"

fastmcp-sse.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
"deployment": {
88
"transport": "sse",
99
"host": "0.0.0.0",
10-
"port": "${MCP_PORT:-8087}",
11-
"path": "${MCP_SECRET_PATH:-/mcp}",
10+
"port": 8087,
11+
"path": "/mcp",
1212
"env": {
1313
"HOMEASSISTANT_URL": "${HOMEASSISTANT_URL}",
1414
"HOMEASSISTANT_TOKEN": "${HOMEASSISTANT_TOKEN}"

fastmcp-webclient.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
"deployment": {
88
"transport": "streamable-http",
99
"host": "0.0.0.0",
10-
"port": "${MCP_PORT:-8086}",
11-
"path": "${MCP_SECRET_PATH:-/mcp}",
10+
"port": 8086,
11+
"path": "/mcp",
1212
"env": {
1313
"HOMEASSISTANT_URL": "${HOMEASSISTANT_URL}",
1414
"HOMEASSISTANT_TOKEN": "${HOMEASSISTANT_TOKEN}"

site/src/content/deployment/docker.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,28 @@ docker run -d --name ha-mcp \
3838
-e HOMEASSISTANT_URL=http://homeassistant.local:8123 \
3939
-e HOMEASSISTANT_TOKEN=your_token \
4040
ghcr.io/homeassistant-ai/ha-mcp:latest \
41-
fastmcp run fastmcp-http.json
41+
ha-mcp-web
4242
```
4343

4444
Server will be available at: `http://YOUR_IP:8086/mcp`
4545

46+
**Customize port and path:**
47+
48+
```bash
49+
docker run -d --name ha-mcp \
50+
-p 9000:9000 \
51+
-e HOMEASSISTANT_URL=http://homeassistant.local:8123 \
52+
-e HOMEASSISTANT_TOKEN=your_token \
53+
-e MCP_PORT=9000 \
54+
-e MCP_SECRET_PATH=/my-secret-path \
55+
ghcr.io/homeassistant-ai/ha-mcp:latest \
56+
ha-mcp-web
57+
```
58+
59+
Server URL: `http://YOUR_IP:9000/my-secret-path`
60+
61+
> **Note:** Both the Docker port mapping (`-p 9000:9000`) and the `MCP_PORT` environment variable must match the desired port. The first number in `-p` is the host port, the second is the container port (which matches `MCP_PORT`).
62+
4663
### Management Commands
4764

4865
```bash
@@ -80,7 +97,7 @@ docker run -d --name ha-mcp \
8097
-e SSL_CERT_FILE=/certs/ca-bundle.crt \
8198
-v /path/to/combined-ca-bundle.crt:/certs/ca-bundle.crt:ro \
8299
ghcr.io/homeassistant-ai/ha-mcp:latest \
83-
fastmcp run fastmcp-http.json
100+
ha-mcp-web
84101
```
85102

86103
## Requirements

src/ha_mcp/__main__.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,14 @@ def main() -> None:
298298

299299

300300
# HTTP entry point for web clients
301-
def _get_http_runtime() -> tuple[int, str]:
302-
"""Return runtime configuration shared by HTTP transports."""
301+
def _get_http_runtime(default_port: int = 8086) -> tuple[int, str]:
302+
"""Return runtime configuration shared by HTTP transports.
303303
304-
port = int(os.getenv("MCP_PORT", "8086"))
304+
Args:
305+
default_port: Default port to use if MCP_PORT env var is not set.
306+
"""
307+
308+
port = int(os.getenv("MCP_PORT", str(default_port)))
305309
path = os.getenv("MCP_SECRET_PATH", "/mcp")
306310
return port, path
307311

@@ -375,9 +379,14 @@ async def _run_http_with_graceful_shutdown(
375379
pass
376380

377381

378-
def _run_http_server(transport: str) -> None:
379-
"""Common runner for HTTP-based transports."""
380-
port, path = _get_http_runtime()
382+
def _run_http_server(transport: str, default_port: int = 8086) -> None:
383+
"""Common runner for HTTP-based transports.
384+
385+
Args:
386+
transport: Transport type (streamable-http or sse).
387+
default_port: Default port to use if MCP_PORT env var is not set.
388+
"""
389+
port, path = _get_http_runtime(default_port)
381390

382391
# Set up signal handlers before running
383392
_setup_signal_handlers()
@@ -420,7 +429,7 @@ def main_web() -> None:
420429
format='%(asctime)s %(name)s %(levelname)s: %(message)s'
421430
)
422431

423-
_run_http_server("streamable-http")
432+
_run_http_server("streamable-http", default_port=8086)
424433

425434

426435
def main_sse() -> None:
@@ -429,7 +438,7 @@ def main_sse() -> None:
429438
Environment:
430439
- HOMEASSISTANT_URL (required)
431440
- HOMEASSISTANT_TOKEN (required)
432-
- MCP_PORT (optional, default: 8086)
441+
- MCP_PORT (optional, default: 8087)
433442
- MCP_SECRET_PATH (optional, default: "/mcp")
434443
"""
435444
# Configure logging before server creation
@@ -440,7 +449,7 @@ def main_sse() -> None:
440449
format='%(asctime)s %(name)s %(levelname)s: %(message)s'
441450
)
442451

443-
_run_http_server("sse")
452+
_run_http_server("sse", default_port=8087)
444453

445454

446455
if __name__ == "__main__":

0 commit comments

Comments
 (0)