By default, Isthmus communicates with AI clients over stdio (standard input/output). This is the simplest setup — the MCP client launches Isthmus as a subprocess and pipes JSON back and forth.
HTTP transport is an alternative that serves MCP over a network socket using the Streamable HTTP transport. This enables clients that don’t support stdio, remote access scenarios, and multi-session architectures.
When to use HTTP transport
| Scenario | Transport |
|---|
| Claude Desktop, Cursor, Windsurf, Gemini CLI | stdio (default) |
| Web-based MCP clients | HTTP |
| Remote access (Isthmus on a server, client elsewhere) | HTTP |
| Multiple concurrent clients sharing one Isthmus instance | HTTP |
| ChatGPT Desktop | HTTP |
| Custom integrations via HTTP API | HTTP |
Most users should stick with stdio. Use HTTP when your client requires it or when you need network access.
Enabling HTTP transport
Set the TRANSPORT environment variable to http:
TRANSPORT=http DATABASE_URL=postgres://user:pass@localhost:5432/mydb isthmus
Or use the --transport CLI flag:
Isthmus will start an HTTP server and log the listen address:
{"level":"INFO","msg":"serving MCP over HTTP","addr":":8080"}
Configuration
| Option | Env var | CLI flag | Default | Description |
|---|
| Transport | TRANSPORT | --transport | stdio | Transport mode: stdio or http |
| HTTP address | HTTP_ADDR | --http-addr | :8080 | Listen address for HTTP transport |
| Bearer token | HTTP_BEARER_TOKEN | --http-bearer-token | (required) | Bearer token for authenticating HTTP requests |
Custom listen address
To change the port or bind to a specific interface:
TRANSPORT=http HTTP_ADDR=:3000 isthmus
# Bind to localhost only (reject external connections)
isthmus --transport http --http-addr 127.0.0.1:8080
# Bind to all interfaces on port 3000
isthmus --transport http --http-addr 0.0.0.0:3000
Bearer authentication
When HTTP transport is enabled, Isthmus requires a bearer token. Every request to the /mcp endpoint must include an Authorization header with the token:
Authorization: Bearer <your-token>
Setting the token
Set the bearer token via environment variable or CLI flag:
TRANSPORT=http HTTP_BEARER_TOKEN=my-secret-token isthmus
isthmus --transport http --http-bearer-token my-secret-token
Isthmus refuses to start in HTTP mode without a bearer token — this prevents accidentally exposing an unauthenticated MCP endpoint on the network.
How it works
- The token is compared using constant-time comparison (
crypto/subtle.ConstantTimeCompare) to prevent timing attacks
- Requests with a missing, malformed, or incorrect
Authorization header receive 401 Unauthorized
- Only the
Bearer scheme is accepted — Basic, Digest, and other schemes are rejected
- Health check endpoints (
/health and /ready) are not behind bearer auth — orchestrators need unauthenticated access to these
Generating a secure token
Use a cryptographically random token:
# Generate a 32-byte random token
openssl rand -hex 32
Store the token securely — treat it like a password. Do not commit it to version control.
Health check endpoints
When running in HTTP mode, Isthmus exposes two unauthenticated health check endpoints for container orchestrators (Kubernetes, ECS, Docker Compose):
| Endpoint | Auth | Description |
|---|
GET /health | None | Liveness probe — returns 200 OK if the process is running |
GET /ready | None | Readiness probe — returns 200 OK if the database pool is healthy, 503 Service Unavailable otherwise |
# Liveness check
curl http://localhost:8080/health
# 200 OK
# Readiness check
curl http://localhost:8080/ready
# 200 OK (database reachable)
# 503 Service Unavailable (database unreachable)
Kubernetes example
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
Server hardening
The HTTP server includes production-grade timeouts and error handling:
| Setting | Value | Purpose |
|---|
| Read timeout | 30s | Prevents slow-read attacks (slowloris) |
| Write timeout | 60s | Prevents connection exhaustion from slow clients |
| Idle timeout | 120s | Cleans up idle keep-alive connections |
| Panic recovery | Enabled | Handler panics return 500 instead of crashing the server |
| Graceful shutdown | 5s drain | In-flight requests complete before exit |
MCP client configuration
Clients that support HTTP
For MCP clients that support the Streamable HTTP transport, point them at the Isthmus HTTP endpoint with the bearer token in the headers:
{
"mcpServers": {
"isthmus": {
"url": "http://localhost:8080/mcp",
"headers": {
"Authorization": "Bearer my-secret-token"
}
}
}
}
Running Isthmus separately
With HTTP transport, Isthmus runs as a standalone process — not as a subprocess of the MCP client. Start it in a terminal or as a system service:
# Terminal
TRANSPORT=http \
HTTP_BEARER_TOKEN=my-secret-token \
DATABASE_URL=postgres://user:pass@localhost:5432/mydb \
isthmus
# Or with all options
isthmus \
--transport http \
--http-addr :8080 \
--http-bearer-token my-secret-token \
--audit-log /var/log/isthmus-audit.ndjson \
--policy-file ./policy.yaml
Then configure your MCP client to connect to the HTTP endpoint.
Streamable HTTP
Isthmus uses the Streamable HTTP transport from the MCP specification. This is a modern HTTP-based transport that supports:
- Standard HTTP request/response for tool calls
- Server-Sent Events (SSE) for streaming responses
- Session management for stateful interactions
This is the transport specified in the MCP 2025-03-26 specification.
Graceful shutdown
The HTTP server shuts down gracefully on SIGTERM or SIGINT:
- Stops accepting new connections
- Waits up to 5 seconds for in-flight requests to complete
- Closes the listener
{"level":"INFO","msg":"shutting down HTTP server"}
{"level":"INFO","msg":"shutdown complete"}
Feature parity
HTTP and stdio transports have full feature parity. All MCP tools, policy engine, column masking, SQL validation, audit logging, and OpenTelemetry work identically regardless of transport.
Security considerations
When using HTTP transport, keep in mind:
- Bearer auth is mandatory — Isthmus refuses to start in HTTP mode without a token
- Bind to localhost (
127.0.0.1) in development to prevent external access
- Use TLS in production — bearer tokens are sent in plaintext over HTTP. Use a reverse proxy (nginx, Caddy, Envoy) for TLS termination, or tunnel through SSH
- Use a reverse proxy for rate limiting if Isthmus is exposed beyond localhost
- All other safety layers (SQL validation, read-only transactions, row limits, column masking) still apply regardless of transport
HTTP transport opens a network port. Unlike stdio, where the MCP client launches Isthmus as a subprocess with no network exposure, HTTP makes Isthmus accessible to any process that can reach the listen address. Always bind to 127.0.0.1 unless you specifically need remote access, and always use TLS in production to protect the bearer token in transit.