Skip to content

Server Overview ​

The McpServer class exposes capabilities (tools, resources, prompts) to connected MCP clients.

Creating a Server ​

cpp
auto transport = std::make_shared<StdioServerTransport>();

ServerOptions opts;
opts.server_info = Implementation{"MyServer", "1.0.0"};

auto server = McpServer::Create(transport, opts);
server->Run();

For Streamable HTTP mode:

cpp
StreamableHttpServerOptions http_opts;
http_opts.port = 3001;
http_opts.stateless = true;  // or false for session mode

auto transport = std::make_shared<StreamableHttpServerTransport>(http_opts);

ServerOptions opts;
opts.server_info = Implementation{"MyServer", "1.0.0"};

auto server = McpServer::Create(transport, opts);
server->Run();

ServerOptions ​

FieldTypeDescription
server_infooptional<Implementation>Server identity (name, version)
protocol_versionoptional<string>Pin to a specific version
server_instructionsoptional<string>Instructions sent to client
initialization_timeoutchrono::secondsHandshake timeout (default 60s)
declare_loggingboolExplicitly declare the logging capability (merged into derived capabilities; default false)
declare_completionsboolExplicitly declare the completions capability (default false)
task_storeshared_ptr<IMcpTaskStore>Task persistence backend
request_state_verifierfunction<bool(string_view)>HMAC/AEAD verifier for MRTR
request_state_keyoptional<string>Server-side requestState signing key (HMAC); when set without an explicit request_state_verifier, a built-in verifier is wired to reject tampered/expired states before handlers (-32602 with data.reason="invalid_request_state")
request_state_ttlchrono::secondsMax age of minted requestState payloads (default 0 = no expiry check)
cache_hintsoptional<map<string, CacheHint, less<>>>Per-method cache hints (ttlMs, cacheScope)
cache_hint_resolverfunction<optional<CacheHint>(string_view)>Escape hook resolving cache hints per method (takes precedence over the static cache_hints table; replaceable at runtime via SetCacheable)
supported_protocol_versionsoptional<vector<string>>Narrows the server's supported-version table (applies to the discover response, the initialize candidate set, and the _meta gate plus error data.supported together; empty means the full table)
subscriptions_enabledboolSubscription master switch (default true; when off, subscriptions/listen returns MethodNotFound)
max_tool_input_elementsoptional<size_t>Tool-argument element cap (object key count / array length; over-budget calls return an is_error tool result, not a protocol error)
input_required_configoptional<InputRequiredConfig>Configuration for MRTR/elicitation behavior
input_required_config.max_roundsintMaximum elicitation rounds (default 10)
input_required_config.round_timeoutchrono::secondsPer-round timeout (default 600s)
input_required_config.legacy_shimboolEnable legacy compatibility shim (default true)
on_requestfunctionCalled on each incoming JSON-RPC request with method name + full request body
on_responsefunctionCalled on each outgoing JSON-RPC response
on_errorfunctionCalled on each outgoing JSON-RPC error response
on_notificationfunctionCalled on each incoming JSON-RPC notification
on_method_calledfunction(string_view)Shorthand — method name only (fires alongside on_request)
on_protocol_errorfunction(string_view)Shorthand — error message only (fires alongside on_error)
on_client_connectedfunction(const Implementation&)Called when a client completes initialize
on_initializedfunction()Called when client sends notifications/initialized
on_transport_closefunction()Called when the transport connection closes
on_transport_errorfunction(string_view)Called on transport-level errors
incoming_filtersshared_ptr<FilterPipeline>Pipeline to intercept/modify/block inbound messages
outgoing_filtersshared_ptr<FilterPipeline>Pipeline to intercept/modify/block outbound messages

Shorthand callbacks (on_method_called, on_protocol_error) and full-message callbacks (on_request, on_error) are chained — both fire when set simultaneously.

RequestContext<TParams> ​

Every tool handler receives a RequestContext<CallToolRequestParams> providing request context:

MemberReturn TypeDescription
Params()const TParams&The deserialized request parameters
Server()McpServer&Reference to the owning server instance
GetRequest()const JsonRpcRequest&The raw JSON-RPC request
LogLevel()optional<LoggingLevel>Per-request log level from _meta (2026-era)
Log(level, data)voidSends a logging notification, filtered by LogLevel()
IsCancellationRequested()boolWhether notifications/cancelled has arrived for this request; handlers poll it for cooperative cancellation

The Log() method respects per-request log levels: messages below the request's LogLevel() are silently dropped.

McpServerTool ​

For reusable tool definitions, subclass McpServerTool or use McpServerTool::Create:

cpp
auto tool = McpServerTool::Create("get_weather",
    [](const RequestContext<CallToolRequestParams>& ctx) -> CallToolResult {
        // ...
    },
    ToolOptions{}.Description("Get weather"));
server->RegisterTool(tool);

The McpServerTool abstract class exposes:

  • ProtocolTool() — returns the protocol-level Tool struct
  • InvokeAsync(ctx, promise) — override for custom async execution

The lambda-based RegisterTool overload works identically — it creates an McpServerTool internally.

Properties ​

MethodReturn TypeDescription
GetClientCapabilities()std::shared_ptr<const ClientCapabilities>Only populated during a 2025-era client initialize handshake; always nullptr in the 2026 era (no initialize)
GetClientInfo()std::shared_ptr<const Implementation>Client identity (nullptr before connect)
GetNegotiatedProtocolVersion()std::stringThe negotiated protocol version string
GetCapabilities()const ServerCapabilities&Server capabilities auto-derived from registered primitives
IsMrtrSupported()boolWhether MRTR (Multi-Round Tool Retrieval) is supported

Notifications ​

MethodDescription
SendToolListChanged()Notifies clients of tool list changes
SendResourceListChanged()Notifies clients of resource list changes
SendResourceUpdated(uri)Notifies clients that a specific resource changed (delivered only to subscribers of that uri)
SendPromptListChanged()Notifies clients of prompt list changes
SendLoggingMessage(level, data)Sends a logging message (respects client's logging/setLevel)
SendLoggingMessage(level, data, min_level)Overload with explicit minimum level override

Completion Handler ​

Register an optional handler for completion/complete requests (e.g., argument auto-complete):

cpp
server->SetCompletionHandler(
    [](const CompleteRequestParams& params) -> CompleteResult {
        CompleteResult result;
        result.completion = JsonValue::Parse(R"({"values":["value1","value2"]})");
        return result;
    });

Lifecycle ​

  1. Construction: McpServer::Create — creates the session handler, wires handlers, starts message loop
  2. Registration: Register tools, resources, prompts via RegisterTool, RegisterResource, RegisterResourceTemplate, RegisterPrompt
  3. Run: server->Run() — blocks until Close() is called; the session handler processes messages asynchronously
  4. Shutdown: server->Close() — waits for pending async calls, closes handler and transport

Capability Derivation ​

Capabilities are automatically derived from registered primitives. For example, registering a tool sets capabilities.tools.list_changed = true. There is no ServerOptions.capabilities field — capabilities are always auto-derived from registered tools, resources, prompts, and task store. The only explicit overrides are declare_logging and declare_completions, which merge the logging / completions capabilities into the derived set (useful when handlers are wired outside the registration APIs, e.g. SetCompletionHandler).