ExMCP.Transport.HTTP (ex_mcp v0.9.0)
View SourceThis module implements the standard MCP specification.
Streamable HTTP transport for MCP with enhanced SSE support.
This transport uses HTTP POST and GET requests with optional Server-Sent Events (SSE) for streaming server-to-client messages. This is one of the two official MCP transports defined in the specification.
Features
- Auto-reconnection: Automatic reconnection with exponential backoff
- Keep-alive: Built-in heartbeat mechanism for connection health
- Event resumption: Supports Last-Event-ID for event replay
- Session management: Automatic session ID generation and tracking
- Configurable endpoint: Customize the MCP endpoint path
- Single response mode: Option to use HTTP responses instead of SSE
- Protocol Versioning: Sends
mcp-protocol-versionheader.
Security Features
The Streamable HTTP transport supports comprehensive security features:
- Authentication: Bearer tokens, API keys, basic auth
- Origin Validation: Prevent DNS rebinding attacks (recommended to enable)
- CORS Headers: Cross-origin resource sharing
- Security Headers: XSS protection, frame options, etc.
- TLS/SSL: Secure connections with certificate validation
Example with Security
{:ok, client} = ExMCP.Client.start_link(
transport: :http,
url: "https://api.example.com",
endpoint: "/mcp/v1", # Configurable endpoint
protocol_version: "2025-06-18", # Specify protocol version
use_sse: true, # Use SSE for responses (default: true)
session_id: "existing-session", # Resume existing session
security: %{
auth: {:bearer, "your-token"},
validate_origin: true,
allowed_origins: ["https://app.example.com"],
cors: %{
allowed_methods: ["GET", "POST"],
allow_credentials: true
}
}
)Session Management
The HTTP transport automatically manages sessions using the Mcp-Session-Id header.
Sessions enable:
- Request/response correlation
- Resumability after connection loss
- Server-side state management
Non-SSE Mode
For simpler deployments, the HTTP transport can operate without SSE:
{:ok, client} = ExMCP.Client.start_link(
transport: :http,
url: "https://api.example.com",
use_sse: false # Responses come in HTTP response body
)Security Best Practices
- Always use HTTPS in production
- Enable origin validation to prevent DNS rebinding attacks
- Bind to localhost when possible for local servers
- Implement proper authentication (bearer tokens, API keys, etc.)
- Set restrictive CORS policies for cross-origin requests
Summary
Functions
Builds SSL options from TLS configuration.
Types
@type t() :: %ExMCP.Transport.HTTP{ access_token: term(), auth_completed: term(), auth_config: term(), base_url: String.t(), endpoint: String.t(), headers: [{String.t(), String.t()}], http_client: module(), last_event_id: String.t() | nil, last_response: map() | nil, origin: String.t() | nil, protocol_version: String.t(), retry_delay: term(), security: ExMCP.Security.Validation.security_config() | nil, session_id: String.t() | nil, sse_deferred_attempted: boolean(), sse_pid: pid() | nil, timeouts: map(), use_sse: boolean() }