- sync-env.sh: replace sed with awk for safe value replacement, add flock
on /tmp/unraid-sync-env.lock, remove auto-token-generation (fail with
clear error if UNRAID_MCP_BEARER_TOKEN not set)
- ensure-ignore-files.sh: rename from ensure-gitignore.sh, add --check mode
that exits non-zero without modifying file (for CI/pre-commit use)
- hooks.json: update both references to new ensure-ignore-files.sh name
- docker-compose.yaml: add user PUID/PGID, external network, deploy.resources
limits (1024M/1cpu), wget healthcheck, start_period=30s
- Dockerfile: install wget, use wget healthcheck, start_period=30s,
add entrypoint.sh, ENTRYPOINT points to /entrypoint.sh
- entrypoint.sh: env validation (UNRAID_API_URL, UNRAID_API_KEY,
UNRAID_MCP_BEARER_TOKEN) with exec for signal forwarding
- .env.example: add PUID, PGID, DOCKER_NETWORK, UNRAID_MCP_ALLOW_DESTRUCTIVE,
UNRAID_MCP_ALLOW_YOLO; fix UNRAID_MCP_BEARER_TOKEN key name
- Add HealthMiddleware (outside BearerAuth) so GET /health bypasses auth;
Docker healthcheck no longer 401s and triggers restart loop
- Pre-create /home/mcp/.unraid-mcp in Dockerfile with mcp:mcp ownership
so named volume mounts inherit correct permissions; bearer token now
persists across container restarts
- Remove custom SIGTERM/SIGINT handlers that silently swallowed signals;
Uvicorn manages its own shutdown
- Distinguish stdio vs HTTP startup log (was always showing host:port for stdio)
- Move _chmod_safe to module level; convert f-strings to %-format in logger calls
- Expand .dockerignore to exclude test/doc/tooling files from image
- P1 (78s): _HEADERS is now an immutable tuple; content-length derived from
len(_BODY) rather than a hardcoded magic number
- P1 (92j): Remove no-op SIGTERM/SIGINT handlers that swallowed signals without
stopping the server; delegate shutdown to Uvicorn's built-in handlers
- P2 (37t): HealthMiddleware now only responds 200 to GET /health; all other
methods fall through to the auth layer (returns 401)
- P2 (696): Extract _chmod_safe() helper; remove redundant second chmod block
in ensure_token_exists()
- P3 (6cr): Reorder middleware — HealthMiddleware is now outermost so it
intercepts /health before BearerAuth; removes the need for a bypass condition
in BearerAuthMiddleware.__call__
- P3 (4yz): Add Scope/Receive/Send type hints to HealthMiddleware.__call__
- Replace pip/requirements.txt with uv and pyproject.toml
- Restructure as single-file MCP server using FastMCP
- Add comprehensive Unraid management tools (containers, VMs, storage, logs)
- Implement multiple transport support (streamable-http, SSE, stdio)
- Add robust error handling and timeout management
- Include project documentation and API feature tracking
- Remove outdated cline documentation structure
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>