> ## Documentation Index
> Fetch the complete documentation index at: https://isthmus.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP Transport

> Serve MCP over HTTP instead of stdio — for web-based clients, remote access, and multi-session architectures.

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](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#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`:

```bash theme={null}
TRANSPORT=http DATABASE_URL=postgres://user:pass@localhost:5432/mydb isthmus
```

Or use the `--transport` CLI flag:

```bash theme={null}
isthmus --transport http
```

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:

```bash theme={null}
TRANSPORT=http HTTP_ADDR=:3000 isthmus
```

```bash theme={null}
# Bind to localhost only (reject external connections)
isthmus --transport http --http-addr 127.0.0.1:8080
```

```bash theme={null}
# 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:

```bash theme={null}
TRANSPORT=http HTTP_BEARER_TOKEN=my-secret-token isthmus
```

```bash theme={null}
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:

```bash theme={null}
# 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 |

```bash theme={null}
# 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

```yaml theme={null}
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:

```json theme={null}
{
  "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:

```bash theme={null}
# 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](https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http).

## Graceful shutdown

The HTTP server shuts down gracefully on `SIGTERM` or `SIGINT`:

1. Stops accepting new connections
2. Waits up to 5 seconds for in-flight requests to complete
3. 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

<Warning>
  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.
</Warning>
