Hermolaos.Transport.Http (Hermolaos v0.3.0)
View SourceHTTP/SSE transport for MCP communication with remote servers.
This transport connects to remote MCP servers using HTTP POST for sending messages and optionally Server-Sent Events (SSE) for receiving streamed responses and server-initiated messages.
How It Works
- Messages are sent via HTTP POST to the server endpoint
- Responses come as either JSON (immediate) or SSE stream
- Session state is maintained via
Mcp-Session-Idheader - Optional GET endpoint can open persistent SSE stream for server notifications
Example
{:ok, transport} = Hermolaos.Transport.Http.start_link(
owner: self(),
url: "http://localhost:3000/mcp"
)
:ok = Hermolaos.Transport.Http.send_message(transport, %{
"jsonrpc" => "2.0",
"id" => 1,
"method" => "initialize",
"params" => %{}
})Messages Sent to Owner
{:transport_ready, pid}- Transport is ready{:transport_message, pid, map}- Received a JSON message{:transport_closed, pid, reason}- Connection closed{:transport_error, pid, error}- Error occurred
Options
:owner- PID to receive messages (required):url- Server endpoint URL (required):headers- Additional HTTP headers (default: []):req_options- Options passed to Req (default: []):connect_timeout- Connection timeout in ms (default: 30000):receive_timeout- Response timeout in ms (default: 60000)
Performance Notes
This transport uses Req with Finch for connection pooling. Multiple concurrent requests share the same connection pool, making it efficient for high-throughput scenarios.
Summary
Functions
Sends a message asynchronously (non-blocking).
Returns a specification to start this module under a supervisor.
Closes the transport.
Checks if the transport is connected.
Returns transport information and statistics.
Sends a JSON-RPC message to the server via HTTP POST.
Starts the HTTP transport.
Types
@type option() :: {:owner, pid()} | {:url, String.t()} | {:headers, [{String.t(), String.t()}]} | {:req_options, keyword()} | {:connect_timeout, pos_integer()} | {:receive_timeout, pos_integer()} | {:name, GenServer.name()}
@type stats() :: %{ requests_sent: non_neg_integer(), responses_received: non_neg_integer(), errors: non_neg_integer() }
Functions
@spec cast_message(GenServer.server(), map()) :: :ok
Sends a message asynchronously (non-blocking).
The HTTP request is performed in a background task.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec close(GenServer.server()) :: :ok
Closes the transport.
@spec connected?(GenServer.server()) :: boolean()
Checks if the transport is connected.
@spec info(GenServer.server()) :: map()
Returns transport information and statistics.
@spec send_message(GenServer.server(), map()) :: :ok | {:error, term()}
Sends a JSON-RPC message to the server via HTTP POST.
This is a synchronous call that waits for the HTTP request to complete. The response message(s) will be sent to the owner process.
Examples
:ok = Hermolaos.Transport.Http.send_message(transport, %{
"jsonrpc" => "2.0",
"id" => 1,
"method" => "tools/list"
})
Starts the HTTP transport.
Options
:owner- PID to receive transport messages (required):url- The MCP server endpoint URL (required):headers- Additional HTTP headers (default:[]):req_options- Options passed to Req (default:[]):connect_timeout- Connection timeout in ms (default: 30000):receive_timeout- Response timeout in ms (default: 60000):name- GenServer name (optional)
Examples
{:ok, pid} = Hermolaos.Transport.Http.start_link(
owner: self(),
url: "http://localhost:3000/mcp",
headers: [{"authorization", "Bearer token"}]
)