Skip to content

HTTP Transport

Chris edited this page Aug 15, 2026 · 159 revisions

Enterprise HTTP Transport

Tools

Resources Prompts
OAuth

Code Mode Rate Limiting

Value Proposition Scale your deployments securely with the HTTP transport. Designed for cloud environments, it features OAuth 2.0 / OIDC security, robust connection pooling, and supports concurrent agent access for intensive workloads. Read the full value proposition.


Architect Your Enterprise Deployment: Stdio vs. HTTP Transport

Note

The http transport utilizes the stateless HTTP architecture via NodeStreamableHTTPServerTransport, exposing a unified POST endpoint at /mcp for JSON-RPC communication.

Use HTTP Transport to unlock enterprise-scale capabilities when:

  • Deploying globally to remote or cloud environments
  • Facilitating concurrent multi-agent access to a centralized server instance
  • Enforcing strict enterprise security via native OAuth 2.0 / OIDC
  • Running the server as a standalone network service
  • Serverless/stateless deployments (--stateless)
  • Horizontally scalable, stateless execution

Use stdio Transport (default) when:

  • Running locally with Claude Desktop or Cursor IDE
  • Single-user development environment
  • Simplest setup with no network configuration needed

Tip

Most users should use stdio Transport. HTTP Transport is for advanced deployments.


Get Started Quickly

Important

You must set --allowed-io-roots to explicitly authorize filesystem access for backup/export tools, not codemode. It is strictly required for HTTP transport (will fail to start), but only emits a warning for stdio (filesystem tools will be blocked, but the server will start).

Local Installation

# Local installation
npx -y @neverinfamous/mysql-mcp --transport http --server-host 0.0.0.0 --port 3000 --allowed-io-roots /data --mysql mysql://user:password@localhost:3306/database

Docker

# Run with port mapping (include Redis and rate limiting env vars for production/enterprise)
docker run -p 3000:3000 \
  -e MYSQL_HOST=host.docker.internal \
  -e MYSQL_USER=user \
  -e MYSQL_PASSWORD=password \
  -e MYSQL_DATABASE=database \
  -e REDIS_URL=redis://host.docker.internal:6379 \
  -e MCP_RATE_LIMIT_MAX=100 \
  -e CODEMODE_RATE_LIMIT_MAX=60 \
  neverinfamous/mysql-mcp:latest \
  --transport http \
  --server-host 0.0.0.0 \
  --port 3000 \
  --allowed-io-roots /data

With Simple Bearer Auth

npx -y @neverinfamous/mysql-mcp --transport http --server-host 0.0.0.0 --port 3000 --allowed-io-roots /data --auth-token my-secret --mysql mysql://user:password@localhost:3306/database

Stateless Mode

npx -y @neverinfamous/mysql-mcp --transport http --server-host 0.0.0.0 --port 3000 --stateless --allowed-io-roots /data --mysql mysql://user:password@localhost:3306/database

Understand Transport Protocols

The unified HTTP transport layer delivers a resilient, scalable foundation for enterprise network architectures. It utilizes the stateless architecture (NodeStreamableHTTPServerTransport) for standard POST requests.

Streamable HTTP (Recommended)

The modern protocol uses a stateless HTTP architecture:

Method Endpoint Purpose
POST /mcp JSON-RPC requests (initialize, tools/list, etc.)
GET /metrics Prometheus metrics export (when enabled)

In stateless mode (--stateless), all continuous streaming endpoints (e.g. /sse, GET /mcp) are explicitly disabled to guarantee strict stateless execution via POST /mcp. GET /mcp returns 405 (Method Not Allowed). DELETE /mcp returns 204. /sse and /messages return 404. Each POST /mcp creates a fresh transport. It relies solely on synchronous request-response cycles.

Warning

Stateless Limitations: --stateless disables resource subscriptions and progress notifications. It entirely disables Server-Sent Events. Do not use this mode if your AI needs long-running task updates.

The Mcp-Session-Id header manages sessions. The server returns a session ID during initialize. Clients must include it in subsequent requests. (Note: Strict MCP clients might structurally require the Mcp-Session-Id header. The --stateless mode ignores it internally.)

Example — Initialize a session:

curl -k -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"<protocol-version>","capabilities":{},"clientInfo":{"name":"my-client","version":"<client-version>"}}}'

Example — List tools (with session):

curl -k -X POST http://localhost:3000/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "Mcp-Session-Id: <session-id-from-initialize>" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

Important

Streamable HTTP requests must include Accept: application/json, text/event-stream.

Review Security Headers

All HTTP responses include the following headers:

Header Value
X-Content-Type-Options nosniff
X-Frame-Options DENY
Cache-Control no-store, no-cache, must-revalidate
Content-Security-Policy default-src 'none'; frame-ancestors 'none'
Permissions-Policy camera=(), microphone=(), geolocation=()
Referrer-Policy no-referrer
Strict-Transport-Security Opt-in via the --enable-hsts CLI flag or MCP_ENABLE_HSTS environment variable

🛡️ Defend Against DoS Attacks with Enterprise Timeouts

Warning

Load Balancer Trap: Set your proxy's idle timeout lower than the server's keepAliveTimeout (65000 ms). Otherwise, the proxy might close active connections, which causes 502 Bad Gateway errors.

The HTTP server proactively applies three aggressive timeout layers to neutralize slow-connection DoS attacks (like Slowloris). These are robust, hardcoded internal defaults designed to protect your enterprise infrastructure:

Timeout Value Purpose
requestTimeout 120s Maximum time for the entire request lifecycle
keepAliveTimeout 65s Idle time before closing keep-alive connections
headersTimeout 66s Maximum time to receive complete headers

Manage Session Timeouts

The HTTP transport enforces strict session lifecycle management to prevent memory leaks:

  • Idle TTL: Defaults to 30 minutes (30min idle). The server terminates idle sessions.
  • Absolute TTL: Defaults to 24 hours (24hr absolute). Hard limit for any session duration.
  • Reaper Interval: Hardcoded 1-minute sweep. A background sweep cleans up orphaned sessions. In-flight requests protect active sessions from early termination.

Configure CORS

CORS is hardcoded to allow all origins (*). This permissiveness defaults to internal routing for seamless orchestrator integration. Secure CORS at the reverse proxy in production. Restricting origins via CLI flags is not currently supported.

Enable Trust Proxy

Enable trustProxy behind reverse proxies. This reads the client IP from X-Forwarded-For. Rate limiting and logging use the real IP.

Enforce Distributed Rate Limiting for Resiliency

Default per-IP request throttling prevents abuse. The Transport Rate limiter uses a sliding window with deterministic cleanup. Redis distributes rate limiting across deployments via REDIS_URL. An in-memory fallback exists for all rate limits.

  • /health bypass — The server processes health checks before rate limiting. This ensures monitoring probes always succeed.
  • Retry-After header — Rate-limited responses include a Retry-After header. It indicates the seconds remaining until the window resets.
  • Environment override — Set MCP_RATE_LIMIT_MAX to customize the HTTP request limit. Set CODEMODE_RATE_LIMIT_MAX to customize the Code Mode execution limit.

Enforce Body Size Limits

The HTTP transport enforces strict body size limits through a single-layer Content-Length validation mechanism, rejecting oversized requests immediately.

The default maximum body size is 1MB. Configure this via the MCP_MAX_BODY_SIZE environment variable.

Engineer Your Enterprise Configuration

Environment Variables

For production deployments, use a structured .env file following fleet groupings:

# Server
MYSQLMCP_PORT=3000
MCP_HOST=0.0.0.0
TRUST_PROXY=false
REDIS_URL=redis://localhost:6379
MCP_RATE_LIMIT_MAX=100
CODEMODE_RATE_LIMIT_MAX=60
# Database
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=app_user
MYSQL_PASSWORD=secure_password
MYSQL_DATABASE=production

Server Configurations

Note

This table highlights HTTP-relevant arguments and general server configurations. See Configuration for the complete list of CLI arguments.

Argument Environment Variable Default Description
--transport, -t - stdio Transport type (stdio or http)
--port, -p MYSQLMCP_PORT, PORT 3000 HTTP server port
--server-host MCP_HOST localhost Host to bind HTTP transport to (Alias: HOST)
--mysql, -m - - MySQL connection string
--auth-token MCP_AUTH_TOKEN - Simple bearer token for HTTP auth
--stateless - false Enable strictly stateless HTTP transport (disables sessions to support serverless scaling). Note: CLI-only flag, no direct env var equivalent.
--trust-proxy TRUST_PROXY false Trust X-Forwarded-For for client IP
--enable-hsts MCP_ENABLE_HSTS false Enable HTTP Strict Transport Security
--metrics-export MCP_METRICS_EXPORT disabled Enable Prometheus metrics endpoint /metrics (requires a string provider, e.g., prometheus)
--allowed-io-roots ALLOWED_IO_ROOTS - Explicitly authorize filesystem boundaries (Required for HTTP Transport)
--oauth-enabled, -o OAUTH_ENABLED false Enable OAuth 2.0 / OIDC authentication (Enterprise Identity Providers like Okta, Auth0, etc.)
--oauth-issuer OAUTH_ISSUER - OAuth issuer URL
--oauth-audience OAUTH_AUDIENCE mysql-mcp-client OAuth audience
--oauth-jwks-uri OAUTH_JWKS_URI - JWKS URI (auto-discovered)
--oauth-clock-tolerance OAUTH_CLOCK_TOLERANCE 60 Clock tolerance in seconds
--audit-log AUDIT_LOG - Path to the audit log file (enables forensic logging)
[ENV Only] AUDIT_LOG_PATH - Read-only path to audit JSONL used by Prometheus metrics exporter / fallback reader
--audit-backup AUDIT_BACKUP false Enable pre-mutation snapshots for destructive DDL and schema maintenance operations
--audit-reads AUDIT_READS false Include read-scope tool calls in audit log
--audit-redact AUDIT_REDACT false Redact sensitive arguments in audit log
--audit-log-max-size AUDIT_LOG_MAX_SIZE 10485760 Max file size before rotation (bytes)
--audit-backup-data AUDIT_BACKUP_DATA false Include sample data in pre-mutation snaps
--audit-backup-max-size AUDIT_BACKUP_MAX_SIZE 52428800 Max table size in bytes for data capture
--pool-size MYSQL_POOL_SIZE 10 Maximum connection pool size
--pool-timeout MYSQL_POOL_TIMEOUT 30000 Connection pool timeout in ms
--pool-queue-limit MYSQL_POOL_QUEUE_LIMIT 0 Connection pool queue limit
[ENV Only] CODEMODE_MAX_RESULT_SIZE 102400 Max Code Mode result payload in bytes (default 100KB, up to 100MB limit)
[ENV Only] CODEMODE_ISOLATION isolate Sandbox mode (only native isolate is supported)
[ENV Only] REDIS_URL - Redis connection URL (used for rate limiting)
[ENV Only] MCP_RATE_LIMIT_MAX 100 Custom HTTP request rate limit
[ENV Only] CODEMODE_RATE_LIMIT_MAX 60 Custom Code Mode execution rate limit
[ENV Only] METADATA_CACHE_TTL_MS 30000 Cache TTL for schema metadata in ms

Note

The --stateless configuration lacks an environment variable equivalent. Standard MYSQL_* environment variables are natively parsed. Note that the --mysql CLI flag only overrides connection-specific variables (Host, Port, User, Password, DB), not all MYSQL_* variables.


Secure Deployments with OAuth 2.0

HTTP Transport supports OAuth 2.0 / OIDC authentication for enterprise deployments:

npx -y @neverinfamous/mysql-mcp \
  --transport http \
  --port 3000 \
  --allowed-io-roots /data \
  --mysql mysql://user:password@localhost:3306/database \
  --oauth-enabled \
  --oauth-issuer http://localhost:8080/realms/mysql-mcp \
  --oauth-audience mysql-mcp-client

See the OAuth page for complete setup instructions.

Connect Your Enterprise Clients

Using MCP Inspector

Test your HTTP server with MCP Inspector:

# Start the server
npx -y @neverinfamous/mysql-mcp --transport http --server-host 0.0.0.0 --port 3000 --allowed-io-roots /data --mysql mysql://...
# In another terminal, connect Inspector
npx -y @modelcontextprotocol/inspector http://localhost:3000/mcp

Health Check

curl -k http://localhost:3000/health
# {"status":"healthy","timestamp":"<ISO-8601-Timestamp>"}

Tip

Exporter Healthcheck: You can verify the exporter is running using wget --spider -q http://127.0.0.1:3000/metrics.


Deploy Enterprise Workloads with Docker

Basic Deployment

# Run container with port mapping
docker run -d \
  --name mysql-mcp-server \
  -p 3000:3000 \
  -e MYSQL_HOST=host.docker.internal \
  -e MYSQL_USER=user \
  -e MYSQL_PASSWORD=password \
  -e MYSQL_DATABASE=database \
  -e REDIS_URL=redis://host.docker.internal:6379 \
  -e MCP_RATE_LIMIT_MAX=100 \
  -e CODEMODE_RATE_LIMIT_MAX=60 \
  -v mcp-data:/data \
  neverinfamous/mysql-mcp:latest \
  --transport http \
  --server-host 0.0.0.0 \
  --port 3000 \
  --allowed-io-roots /data

Docker Compose

The following is a minimal excerpt for deploying the HTTP transport via docker-compose.yml. See the Observability & Telemetry page for the full Datadog test ecosystem. It is located in test-server/infrastructure. Metrics can be seamlessly ingested into Datadog or OpenTelemetry-compatible observability pipelines via standard Prometheus scraping.

# Note: Always include a healthcheck when deploying HTTP transport
services:
  mysql-mcp:
    image: neverinfamous/mysql-mcp:latest
    ports:
      - "3000:3000"
    command:
      - --transport
      - http
      - --server-host
      - "0.0.0.0"
      - --port
      - "3000"
      - --allowed-io-roots
      - /data
      - --mysql
      - mysql://user:password@mysql:3306/database
    environment:
      - MYSQL_POOL_SIZE=20
      - REDIS_URL=redis://redis:6379
      - MCP_RATE_LIMIT_MAX=100
      - CODEMODE_RATE_LIMIT_MAX=60
    depends_on:
      - mysql
      - redis
    healthcheck:
      test: ["CMD", "curl", "-k", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    volumes:
      - mcp-data:/data
  mysql:
    image: mysql:lts
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: database
    volumes:
      - mysql-data:/var/lib/mysql
  redis:
    image: redis:alpine
    ports:
      - "6379:6379"
volumes:
  mysql-data:
  mcp-data:

Scale in the Cloud

AWS ECS / Fargate

  1. Push Docker image to ECR
  2. Create ECS task definition with port 3000 exposed
  3. Configure ALB to route traffic to the container
  4. Set environment variables for MySQL connection

Google Cloud Run

# Build and push to GCR
gcloud builds submit --tag gcr.io/PROJECT_ID/mysql-mcp

# Deploy to Cloud Run
gcloud run deploy mysql-mcp \
  --image gcr.io/PROJECT_ID/mysql-mcp \
  --port 3000 \
  --set-env-vars MYSQL_HOST=...,MYSQL_USER=...,MYSQL_PASSWORD=... \
  --args="--transport","http","--server-host","0.0.0.0","--port","3000","--allowed-io-roots","/data","--stateless"

Azure Container Instances

az container create \
  --resource-group myResourceGroup \
  --name mysql-mcp \
  --image neverinfamous/mysql-mcp:latest \
  --ports 3000 \
  --environment-variables \
    MYSQL_HOST=... \
    MYSQL_USER=... \
    MYSQL_PASSWORD=... \
  --command-line "node dist/cli.js --transport http --server-host 0.0.0.0 --port 3000 --allowed-io-roots /data --stateless"

Troubleshoot Issues

Connection Refused

Problem: Client cannot connect to the server

Solutions:

  • Verify server is running: curl -k http://localhost:3000/health
  • Check firewall rules allow port 3000
  • Ensure --server-host 0.0.0.0 if connecting from another machine
  • Check Docker port mapping: -p 3000:3000

406 Not Acceptable (Streamable HTTP)

Problem: POST /mcp returns 406

Solution: Include the required Accept header:

Accept: application/json, text/event-stream

The server requires clients to accept JSON and SSE formats.

Session Not Found

Problem: Requests return 400 Bad Request or 404 Not Found with session errors

Solutions:

  • Send the Mcp-Session-Id header from the initialize response

  • Sessions expire when clients disconnect

OAuth Authentication Failures

Problem: Requests return 401 Unauthorized

Solutions:

  • Verify OAuth issuer URL is correct
  • Check token audience matches --oauth-audience
  • Ensure JWKS URI is accessible from the server
  • See OAuth troubleshooting section

Performance Benchmarks

Engineered for high-throughput operations, the server delivers microsecond-level latency across schema parsing, rate limiting, and Code Mode sandbox initialization. For comprehensive benchmark data, refer to Performance Tuning.

Explore Related Topics

MySQL MCP Documentation

Unlock autonomous database orchestration with an enterprise-grade MySQL MCP server. Featuring blazing-fast sandboxed Code Mode, uncompromising schema enforcement, and seamless ecosystem integrations to power secure, intelligent AI workflows.

🏠 Home


Launch Your Setup


Connect Ecosystem Tools


Enforce Security & Compliance


Scale Your Operations


Explore External Links

Clone this wiki locally