Skip to content

Client Overview

The McpClient class connects to MCP servers, negotiates protocol versions, and invokes server capabilities.

Creating a Client

cpp
StdioClientTransportOptions transport_opts;
transport_opts.command = "path/to/server";
auto transport = std::make_shared<StdioClientTransport>(transport_opts);
ClientOptions opts;
opts.client_info = Implementation{"MyClient", "1.0.0"};

auto client = McpClient::Create(transport, opts);

ClientOptions

FieldTypeDescription
client_infoImplementationClient identity
capabilitiesoptional<ClientCapabilities>Declared capabilities
connect_modeConnectModeAuto (discover → initialize), Legacy, Pin
initialization_timeoutchrono::secondsHandshake timeout (default 60s)
pin_protocol_versionoptional<string>Pin to a specific protocol version (used with Pin mode)
discover_probe_timeoutchrono::secondsServer discovery probe timeout (default 5s)
supported_protocol_versionsvector<string>Protocol versions the client advertises
input_required_configInputRequiredConfigConfiguration for MRTR elicitation responses
cache_configCacheConfigClient-side caching configuration
extensionsoptional<JsonValue>Protocol extension declarations
enforce_strict_capabilitiesboolReject unknown capabilities (default false)
list_max_pagesintMax pages for paginated list operations (default 64)

Making Requests

cpp
// List tools
auto tools = client->ListTools();

// Call a tool
auto result = client->CallTool("echo",
    JsonValue(JsonValue::Object{{"text", "Hello"}}));

// Read a resource
auto resource = client->ReadResource("file:///config.json");

// Get a prompt
auto prompt = client->GetPrompt("code_review",
    JsonValue(JsonValue::Object{{"diff", "..."}}));

// Complete a prompt/resource reference
auto completion = client->Complete(params);

// Ping (heartbeat)
client->Ping();

Server-to-Client Handlers

Register handlers for server-initiated requests:

cpp
client->SetElicitationHandler(
    [](const ElicitRequestParams& params) -> ElicitResult {
        // Prompt user for input, return result
        ElicitResult result;
        result.values = JsonValue(JsonValue::Object{{"name", "Alice"}});
        return result;
    });

client->SetSamplingHandler(
    [](const CreateMessageRequestParams& params) -> CreateMessageResult {
        // Deprecated: use Elicitation instead
    });

client->SetRootsHandler(
    [](const ListRootsRequestParams& params) -> ListRootsResult {
        // Deprecated: provide root directories
    });

Subscriptions

cpp
// Subscribe to server notifications (2026-era)
SubscriptionsListenRequestParams subs;
subs.notifications.tools_list_changed = true;
subs.notifications.resources_list_changed = true;
client->SubscribeAsync(subs);

Version Negotiation

The client auto-negotiates the protocol version:

  1. Auto (default): Probe server/discover, fallback to initialize handshake
  2. Pin: Force a specific version
  3. Legacy: Only initialize handshake