## ADDED Requirements ### Requirement: Configurable MCP allowed hosts The MCP server SHALL accept a `KB_MCP_ALLOWED_HOSTS` environment variable containing a comma-separated list of additional hosts (IP addresses or FQDNs) that are permitted to connect. The server SHALL always allow `127.0.0.1`, `localhost`, and `[::1]` regardless of this setting. DNS rebinding protection SHALL always be enabled. #### Scenario: Remote client connects with allowed host - **WHEN** `KB_MCP_ALLOWED_HOSTS` is set to `192.168.1.50` and a client connects with `Host: 192.168.1.50:3000` - **THEN** the server SHALL accept the request and process it normally #### Scenario: Remote client connects with disallowed host - **WHEN** `KB_MCP_ALLOWED_HOSTS` is set to `192.168.1.50` and a client connects with `Host: 10.0.0.99:3000` - **THEN** the server SHALL return HTTP 421 "Invalid Host header" #### Scenario: Multiple allowed hosts - **WHEN** `KB_MCP_ALLOWED_HOSTS` is set to `192.168.1.50,kb.example.com` - **THEN** the server SHALL accept requests with `Host` matching either `192.168.1.50` or `kb.example.com` on any port #### Scenario: Variable unset or empty - **WHEN** `KB_MCP_ALLOWED_HOSTS` is unset or empty - **THEN** the server SHALL allow only localhost addresses (`127.0.0.1`, `localhost`, `[::1]`) with any port #### Scenario: Localhost always allowed - **WHEN** `KB_MCP_ALLOWED_HOSTS` is set to `192.168.1.50` - **THEN** the server SHALL still accept requests with `Host: localhost:3000` or `Host: 127.0.0.1:3000` #### Scenario: Allowed origins derived from allowed hosts - **WHEN** `KB_MCP_ALLOWED_HOSTS` includes `192.168.1.50` - **THEN** the server SHALL accept `Origin: http://192.168.1.50:3000` (and any port) in addition to localhost origins ## MODIFIED Requirements ### Requirement: Compose files for deployment The project SHALL provide Docker Compose files for single-command deployment. Compose files SHALL use `build:` context for local development. Release notes SHALL document the versioned image tag for users pulling pre-built images. #### Scenario: Start NVIDIA deployment - **WHEN** an admin runs `docker compose -f compose.nvidia.yaml up -d` - **THEN** the engine SHALL start with GPU access, bind-mount the data directory, and be reachable on the configured port #### Scenario: Start ROCm deployment - **WHEN** an admin runs `docker compose -f compose.rocm.yaml up -d` - **THEN** the engine SHALL start with GPU access via ROCm device passthrough, bind-mount the data directory, and be reachable on the configured port #### Scenario: Automatic restart - **WHEN** the engine process crashes or the host reboots - **THEN** Docker SHALL automatically restart the container (restart policy `unless-stopped`) #### Scenario: Configure via environment - **WHEN** an admin sets environment variables in the compose file (KB_MODEL, KB_API_KEY, KB_DEVICE, KB_MCP_ALLOWED_HOSTS, etc.) - **THEN** the engine and MCP server SHALL use those values #### Scenario: Pre-built image deployment - **WHEN** an admin wants to use a pre-built engine image without building from source - **THEN** the engine release notes SHALL include the exact `docker pull` command with the versioned tag (e.g. `docker.dcglab.co.uk/dcg/kb/engine:engine-v2.1.0-nvidia`) #### Scenario: MCP allowed hosts in Compose - **WHEN** the kb-mcp service is defined in a Compose file - **THEN** the environment block SHALL include `KB_MCP_ALLOWED_HOSTS` with a comment explaining its format and purpose