Move JSON-RPC messages between client and server.
cxxmcp ships four built-in transports and lets you implement custom ones. This page covers each transport's API, options, and behavior.
Transport Overview
| Transport | Role | CMake Flag | Builder Method | Class |
|---|---|---|---|---|
| stdio | Server + Client | default | .stdio() | StdioTransport |
| Process stdio | Client | default | .process_stdio(cmd) | ProcessStdioClientTransport |
| Streamable HTTP | Server + Client | CXXMCP_ENABLE_HTTP | .streamable_http(...) | StreamableHttp{Server,Client}Transport |
| WebSocket | Server + Client | CXXMCP_ENABLE_HTTP + CXXMCP_ENABLE_WEBSOCKET | .websocket(...) | WebSocket{Server,Client}Transport |
| Custom | Either | — | implement Transport<Role> | your class |
stdio Transport
Reads JSON-RPC messages from stdin, writes responses to stdout. The simplest transport — ideal for CLI tools, local subprocess integrations, and editors that launch MCP servers as child processes.
Server
#include <cxxmcp/peer.hpp>
#include <cxxmcp/run.hpp>
int main() {
return mcp::ServerPeer::builder()
.name("my-server").version("1.0.0")
.stdio() // enables stdio transport
.tool<Json, Json>("echo", handler)
.run();
}
Client
// Launch a server process and talk to it via stdin/stdout
auto client = mcp::ClientPeer::builder()
.process_stdio("./my-server") // launches the process
.build();
Behavior
- One JSON-RPC message per line (newline-delimited JSON)
- Server blocks until stdin is closed or
stop()is called - No multiplexing — one request at a time
- No network overhead — fastest transport for local use
Process stdio Transport
Client-only transport that launches a server as a subprocess and communicates over its stdin/stdout. The process lifecycle is managed by the transport.
Usage
// Simple command
auto client = mcp::ClientPeer::builder()
.process_stdio("node my-server.js")
.build();
// With arguments
auto client = mcp::ClientPeer::builder()
.process_stdio("python -m my_mcp_server --port stdio")
.build();
// With options
mcp::transport::ProcessStdioClientTransportOptions opts;
opts.command = "./my-server";
opts.working_directory = "/path/to/server";
auto client = mcp::ClientPeer::builder()
.process_stdio(opts)
.build();
Behavior
- Process is started on first
send()orinitialize() - Process is terminated when the transport is destroyed or
close()is called - Response ID validation ensures responses match requests
- Timeout on process startup (configurable)
Streamable HTTP Transport
Full-duplex HTTP transport with SSE streaming. Supports stateful
sessions, concurrent requests, and server-to-client notifications.
Requires CXXMCP_ENABLE_HTTP=ON.
Build
cmake -S . -B build -DCXXMCP_ENABLE_HTTP=ON -DCXXMCP_BUILD_SERVER=ON -DCXXMCP_BUILD_CLIENT=ON
Server
#include <cxxmcp/peer.hpp>
#include <cxxmcp/run.hpp>
auto server = mcp::ServerPeer::builder()
.name("http-server").version("1.0.0")
.streamable_http("127.0.0.1", 3000, "/mcp")
.tool<Json, Json>("echo", [](const Json& in) { return in; })
.build();
auto running = mcp::serve(std::move(*server));
running->wait_until_ready();
running->wait();
Server Options
mcp::transport::StreamableHttpServerTransportOptions opts;
opts.listen_host = "0.0.0.0"; // Bind address
opts.listen_port = 8080; // Port
opts.path = "/mcp"; // Endpoint path
opts.session_header = "Mcp-Session-Id"; // Session header name
auto server = mcp::ServerPeer::builder()
.name("my-server").version("1.0.0")
.streamable_http(opts)
.build();
Client
auto client = mcp::ClientPeer::builder()
.streamable_http("http://127.0.0.1:3000/mcp")
.build();
// With bearer token
auto client = mcp::ClientPeer::builder()
.streamable_http("http://127.0.0.1:3000/mcp")
.bearer_token("my-secret-token")
.build();
Client Options
mcp::transport::StreamableHttpClientTransportOptions opts;
opts.base_url = "http://127.0.0.1:3000/mcp";
opts.timeout = std::chrono::seconds(30);
opts.bearer_token = "my-secret-token";
auto client = mcp::ClientPeer::builder()
.streamable_http(opts)
.build();
Behavior
- POST requests carry JSON-RPC messages; responses may be SSE streams
- GET opens an SSE channel for server-to-client notifications
- DELETE terminates the session
- Session state is tracked via
Mcp-Session-Idheader - SEP-2243:
Mcp-MethodandMcp-Nameheaders are validated when present (optional for backward compat) - Legacy SSE endpoint
/sseis supported for older clients
WebSocket Transport
Full-duplex message transport over WebSocket with client reconnect
support. Requires CXXMCP_ENABLE_HTTP=ON and
CXXMCP_ENABLE_WEBSOCKET=ON.
Build
cmake -S . -B build -DCXXMCP_ENABLE_HTTP=ON -DCXXMCP_ENABLE_WEBSOCKET=ON -DCXXMCP_BUILD_SERVER=ON -DCXXMCP_BUILD_CLIENT=ON
Server
auto server = mcp::ServerPeer::builder()
.name("ws-server").version("1.0.0")
.websocket(3001)
.tool<Json, Json>("echo", [](const Json& in) { return in; })
.build();
Client
auto client = mcp::ClientPeer::builder()
.websocket("ws://127.0.0.1:3001/mcp")
.build();
Custom Transports
Implement the Transport<Role> interface to create
your own transport (Unix socket, in-memory loopback, shared memory,
etc.).
#include <cxxmcp/transport/transport.hpp>
// Client transport
class MyClientTransport : public mcp::transport::ClientTransport {
public:
mcp::core::Result<mcp::protocol::JsonRpcResponse> send(
const mcp::protocol::JsonRpcRequest& request) override {
// Serialize request, send over your channel, return response
}
mcp::core::Result<mcp::core::Unit> send_notification(
const mcp::protocol::JsonRpcNotification& notification) override {
// Send notification (no response expected)
}
};
// Server transport
class MyServerTransport : public mcp::transport::ServerTransport {
public:
void on_request(RequestHandler handler) override {
// Store handler; call it when a request arrives on your channel
}
mcp::core::Result<mcp::core::Unit> send_response(
const mcp::protocol::JsonRpcResponse& response) override {
// Send response back to client
}
};
Built-in Adapters
The SDK provides adapter classes for common patterns:
FunctionTransport<Role>— wrap lambda functions as a transportJsonLineTransport<Role>— newline-delimited JSON over any streamQueueTransport<Role>— in-memory queue for testing
Next Steps
- Auth — secure your HTTP transport
- Tutorials — build with each transport
- API Reference — full transport class docs