Connection pool for managing multiple MCP connections.
The Pool provides load balancing and fault tolerance for MCP operations by maintaining multiple connections to one or more servers.
Use Cases
- High throughput: Distribute requests across multiple connections
- Redundancy: Multiple connections to the same server for failover
- Multi-server: Connect to multiple MCP servers simultaneously
Architecture
The Pool uses a DynamicSupervisor to manage connections. Each connection
is a supervised Hermolaos.Client.Connection process. The pool uses a
Registry for efficient connection lookup.
Example
# Start a pool
{:ok, pool} = Hermolaos.Pool.start_link(
name: MyApp.MCPPool,
connections: [
[transport: :stdio, command: "server1"],
[transport: :stdio, command: "server2"]
]
)
# Use checkout/checkin pattern
{:ok, conn} = Hermolaos.Pool.checkout(MyApp.MCPPool)
result = Hermolaos.call_tool(conn, "my_tool", %{})
Hermolaos.Pool.checkin(MyApp.MCPPool, conn)
# Or use transaction for automatic checkin
result = Hermolaos.Pool.transaction(MyApp.MCPPool, fn conn ->
Hermolaos.call_tool(conn, "my_tool", %{})
end)Strategies
:round_robin- Rotate through available connections (default):random- Randomly select a connection:least_busy- Select connection with fewest pending requests
Pool as Hermolaos Client
The pool itself implements the same interface as a single connection,
so you can use Hermolaos.call_tool/4 etc. directly with the pool name.
Summary
Functions
Adds a new connection to the pool.
Checks a connection back into the pool.
Checks out a connection from the pool.
Returns a specification to start this module under a supervisor.
Returns the list of all connections in the pool.
Removes a connection from the pool.
Starts a connection pool.
Returns pool statistics.
Executes a function with a checked-out connection.
Types
@type pool() :: Supervisor.supervisor()
@type pool_option() :: {:name, atom()} | {:connections, [keyword()]} | {:size, pos_integer()} | {:strategy, strategy()} | {:connection_opts, keyword()}
@type strategy() :: :round_robin | :random | :least_busy
Functions
@spec add_connection( pool(), keyword() ) :: {:ok, Hermolaos.Client.Connection.t()} | {:error, term()}
Adds a new connection to the pool.
Examples
{:ok, conn} = Hermolaos.Pool.add_connection(MyPool, transport: :stdio, command: "new-server")
@spec checkin(pool(), Hermolaos.Client.Connection.t()) :: :ok
Checks a connection back into the pool.
This is a no-op in the current implementation but is included for API compatibility with checkout/checkin patterns.
@spec checkout( pool(), keyword() ) :: {:ok, Hermolaos.Client.Connection.t()} | {:error, :no_connections}
Checks out a connection from the pool.
Returns a connection that should be checked back in after use,
or used within a transaction/2 block.
Options
:timeout- Maximum time to wait for a connection (default: 5000)
Examples
{:ok, conn} = Hermolaos.Pool.checkout(MyPool)
# use conn...
Hermolaos.Pool.checkin(MyPool, conn)
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec connections(pool()) :: [Hermolaos.Client.Connection.t()]
Returns the list of all connections in the pool.
@spec remove_connection(pool(), Hermolaos.Client.Connection.t()) :: :ok | {:error, :not_found}
Removes a connection from the pool.
Starts a connection pool.
Options
:name- Pool name (required, used for registration):connections- List of connection option keyword lists:size- Number of identical connections (alternative to:connections):connection_opts- Common options for all connections when using:size:strategy- Load balancing strategy (default::round_robin)
Examples
# Multiple connections with explicit configs
{:ok, pool} = Hermolaos.Pool.start_link(
name: MyPool,
connections: [
[transport: :stdio, command: "server1"],
[transport: :http, url: "http://localhost:3000/mcp"]
]
)
# Pool of identical connections
{:ok, pool} = Hermolaos.Pool.start_link(
name: MyPool,
size: 4,
connection_opts: [transport: :stdio, command: "my-server"]
)
Returns pool statistics.
@spec transaction(pool(), (Hermolaos.Client.Connection.t() -> result)) :: result when result: term()
Executes a function with a checked-out connection.
Automatically checks in the connection after the function completes.
Examples
result = Hermolaos.Pool.transaction(MyPool, fn conn ->
Hermolaos.call_tool(conn, "my_tool", %{arg: "value"})
end)