Skip to content
Chris edited this page Jun 3, 2026 · 5 revisions

HTTP Transport

For remote access, web-based clients, or HTTP-compatible MCP hosts, use the HTTP transport. The server supports two MCP transport protocols simultaneously, enabling both modern and legacy clients to connect.


Starting the Server

Node.js

node dist/cli.js \
  --transport http \
  --port 3000 \
  --sqlite-native ./database.db \
  --allowed-io-roots $(pwd)

Docker

docker run --rm -p 3000:3000 \
  -v ./data:/app/data \
  writenotenow/db-mcp:latest \
  --transport http --port 3000 --server-host 0.0.0.0 \
  --sqlite-native /app/data/database.db \
  --allowed-io-roots /app/data

Important: Use --server-host 0.0.0.0 to bind to all interfaces in Docker. Without this, the server may only listen on localhost inside the container.


Streamable HTTP (Recommended)

Modern protocol (MCP 2025-03-26) β€” single endpoint, session-based:

Method Endpoint Purpose
POST /mcp JSON-RPC requests (initialize, tools/list, etc.)
GET /mcp SSE stream for server notifications
DELETE /mcp Session termination

Sessions are managed via the Mcp-Session-Id header.


Stateless Mode

For serverless or stateless deployments where sessions are not needed:

node dist/cli.js --transport http --port 3000 --stateless --sqlite-native ./database.db --allowed-io-roots $(pwd)

In stateless mode:

  • GET /mcp returns 405
  • DELETE /mcp returns 204
  • /sse and /messages return 404
  • Each POST /mcp creates a fresh transport

Legacy SSE (Backward Compatibility)

Legacy protocol (MCP 2024-11-05) β€” for clients like Python mcp.client.sse:

Method Endpoint Purpose
GET /sse Opens SSE stream, returns /messages?sessionId=<id> endpoint
POST /messages?sessionId=<id> Send JSON-RPC messages to the session

Utility Endpoints

Method Endpoint Purpose
GET /health Health check (bypasses rate limiting, always available for monitoring)
GET /metrics Prometheus metrics export (requires --metrics-export prometheus)

Security Features

The HTTP transport includes comprehensive security protections:

Feature Description
Filesystem Hard Gate Requires ALLOWED_IO_ROOTS to explicitly define authorized IO boundaries
DNS Rebinding Guard validateHostHeader() validates Host headers
Security Headers CSP, X-Content-Type-Options, X-Frame-Options, Cache-Control, and more
Rate Limiting 100 requests/minute per IP (configurable via MCP_RATE_LIMIT_MAX)
CORS Deny-all by default
Trust Proxy Rate limiting supports reverse proxies via trustedProxyIps
Slowloris Protection Protected via internal HTTP transport defaults
HSTS Opt-in via --enableHSTS for HTTPS deployments
Session Ownership Sessions bound to authenticated subjects (prevents hijacking)

See OAuth & Security for authentication configuration.


Configuration Reference

Variable Default Description
MCP_HOST 0.0.0.0 Host/IP to bind to (CLI: --server-host)
MCP_RATE_LIMIT_MAX 100 Max requests/minute per IP

Docker Examples

Basic HTTP

docker run --rm -p 3000:3000 \
  -v ./data:/app/data \
  writenotenow/db-mcp:latest \
  --transport http --port 3000 --server-host 0.0.0.0 \
  --sqlite-native /app/data/database.db \
  --allowed-io-roots /app/data

HTTP with OAuth

docker run --rm -p 3000:3000 \
  -v ./data:/app/data \
  writenotenow/db-mcp:latest \
  --transport http --port 3000 --server-host 0.0.0.0 \
  --oauth-enabled --oauth-issuer http://keycloak:8080/realms/db-mcp --oauth-audience db-mcp-server \
  --sqlite-native /app/data/database.db \
  --allowed-io-roots /app/data

Stateless + Audit

docker run --rm -p 3000:3000 \
  -v ./data:/app/data \
  writenotenow/db-mcp:latest \
  --transport http --port 3000 --server-host 0.0.0.0 --stateless \
  --audit-log stderr \
  --sqlite-native /app/data/database.db \
  --allowed-io-roots /app/data

Related

Clone this wiki locally