Skip to content

v0.6.0

Pre-release
Pre-release

Choose a tag to compare

@ajshedivy ajshedivy released this 26 Aug 17:16

IBM i MCP Server v0.6.0

Overview

  • DNS rebinding protection for the HTTP transport (Server) — Every request's Host and Origin headers are validated, and a server that holds IBM i credentials refuses to start unauthenticated on a network address
  • New defaults for HTTP deployments (Server)MCP_HTTP_HOST defaults to 127.0.0.1; remote and container deployments need MCP_ALLOWED_HOSTS and an authentication mode, or an explicit opt-out
  • dependency audit — 52 vulnerabilities cleared across both packages, including axios, hono, sanitize-html, and js-yaml
  • Docker image binds all interfaces (Server) — The published image sets MCP_HTTP_HOST=0.0.0.0 so published ports work with the new default

Stdio deployments (Claude Desktop, Cursor, VS Code, MCP Inspector) and the ibmi CLI are not affected by the HTTP changes.

Docker & Podman | Configuration | IBM i Authentication


Breaking Changes

HTTP transport hardening against DNS rebinding

The vulnerability: The HTTP transport holds the IBM i credentials it is started with. Through DNS rebinding, a web page opened in a browser on the same machine could send requests to the local server and run its SQL tools with those credentials. CORS does not prevent this; the request is same-origin from the browser's point of view.

What changed.

  • Every request's Host header must be a loopback name (localhost, 127.x.x.x, ::1) or listed in MCP_ALLOWED_HOSTS. Any other name returns 403 Forbidden: Host not allowed. A browser Origin header, when present, must match MCP_ALLOWED_ORIGINS or an allowlisted host. Non-browser clients send no Origin and are unaffected by that rule.
  • The server refuses to start when it is bound to a non-loopback address, holds IBM i credentials (DB2i_* variables or a tools YAML), and authentication is not enforced. "Not enforced" means MCP_AUTH_MODE=none, or MCP_AUTH_MODE=jwt without MCP_AUTH_SECRET_KEY. The log line begins Refusing to start: unauthenticated HTTP transport. Override with MCP_ALLOW_UNAUTHENTICATED_HTTP=true.
  • MCP_HTTP_HOST defaults to 127.0.0.1 (was 0.0.0.0).
  • The development CORS * fallback is removed. With MCP_ALLOWED_ORIGINS unset, no Access-Control-Allow-Origin header is sent.

Running the server over HTTP.

Local, with the client on the same machine: no configuration is needed. If your .env sets MCP_HTTP_HOST=0.0.0.0, remove that line.

Docker, local only, without authentication:

docker run -d --name ibmi-mcp-server \
  -p 127.0.0.1:3010:3010 \
  -e DB2i_HOST=your-ibmi-host -e DB2i_USER=your-username -e DB2i_PASS=your-password \
  -e MCP_ALLOW_UNAUTHENTICATED_HTTP=true \
  ghcr.io/ibm/ibmi-mcp-server:v0.6.0

On a network (remote host, OpenShift, Docker Compose): bind all interfaces, allowlist every name clients use to reach the server, and enable authentication.

MCP_HTTP_HOST=0.0.0.0
MCP_ALLOWED_HOSTS=mcp.example.com,ibmi-mcp-server
MCP_AUTH_MODE=ibmi

Kubernetes and OpenShift probes send the pod IP as Host; add httpHeaders: Host: localhost to the probe. Browser clients need their origin in MCP_ALLOWED_ORIGINS. Do not set MCP_HTTP_HOST=127.0.0.1 inside a container: Docker forwards published ports to the container's network interface, not its loopback, so the server becomes unreachable. Restrict exposure on the host side with -p 127.0.0.1:3010:3010.

New configuration.

Variable Default Purpose
MCP_HTTP_HOST 127.0.0.1 (was 0.0.0.0) Bind address
MCP_ALLOWED_HOSTS loopback only Comma-separated Host allowlist; extends loopback. * disables the Host check only
MCP_ALLOW_UNAUTHENTICATED_HTTP false Accept an unauthenticated, non-loopback server that holds credentials

Documentation: Docker & Podman, Configuration, Using the default tools

Reference: #163, #169


What's Changed

  • fix(deps): resolve all npm audit vulnerabilities in server and CLI (52 → 0) by @ajshedivy in #159
  • chore(deps): prune example-agent lockfiles feeding Dependabot alert noise by @ajshedivy in #160
  • fix(security): validate Host and Origin headers to block DNS rebinding by @ajshedivy in #163
  • fix(docker): ship MCP_HTTP_HOST=0.0.0.0 in the CI-built image; update Docker docs for DNS rebinding hardening by @ajshedivy in #169

Full Changelog: v0.5.1...v0.6.0