Concepts

# Understand the cxxmcp architecture.

The SDK is organized in layers: Protocol, Transport, Handler, Peer, and Service. This page explains how they fit together.

## Layer Architecture

cxxmcp follows the RMCP-style role-aware design. Each layer has a specific responsibility and a corresponding CMake target:

Layer | Target | Responsibility
--- | --- | ---
`protocol` | `cxxmcp::protocol` | MCP data models, JSON-RPC serialization, reflection, schema
`transport` | `cxxmcp::transport` | Role-generic transport contracts (stdio, HTTP, custom)
`handler` | `cxxmcp::handler` | Client/server handler interfaces
`peer` | `cxxmcp::peer` | Role-aware execution boundary (`ServerPeer`, `ClientPeer`)
`service` | `cxxmcp::service` | Service lifecycle (start, stop, wait)
`server` | `cxxmcp::server` | Server SDK: registries, builders, auth providers
`client` | `cxxmcp::client` | Client SDK: connection, request helpers
`auth` | `cxxmcp::auth` | Optional OAuth 2.1 / DPoP contracts

## Peer and Service

Peer is the execution boundary. It owns the server or client state and routes incoming requests to registered handlers. Service wraps a Peer with a transport and manages the lifecycle (start, run, stop).

### ServerPeer

Owns tool/prompt/resource registries, auth provider, and request dispatch. Built via `ServerPeer::builder()`.

### ClientPeer

Owns connection state, sends requests to a server, handles notifications. Built via `ClientPeer::builder()`.

    // Server lifecycle
    auto server = mcp::ServerPeer::builder()
        .name("my-server").version("1.0.0")
        .stdio()
        .tool<Json, Json>("echo", handler)
        .build();

    auto running = mcp::serve(std::move(*server));
    running->wait();  // blocks until shutdown

    // Client lifecycle
    auto client = mcp::ClientPeer::builder()
        .streamable_http("http://localhost:3000/mcp")
        .build();

    auto svc = mcp::serve(std::move(*client));
    svc->peer().initialize();
    svc->peer().call_tool("echo", Json{{"value", "hi"}});

## Transports

A transport moves JSON-RPC messages between client and server. cxxmcp ships several built-in transports and lets you write custom ones.

Transport | Builder Method | CMake Flag | Use Case
--- | --- | --- | ---
stdio | `.stdio()` | default | CLI tools, local subprocess
Process stdio | `.process_stdio(cmd)` | default | Launch a server process and talk to it
Streamable HTTP | `.streamable_http(host, port, path)` | `CXXMCP_ENABLE_HTTP` | Web services, remote access
WebSocket | `.websocket(...)` | `CXXMCP_ENABLE_HTTP` + `CXXMCP_ENABLE_WEBSOCKET` | Full-duplex remote access
Custom | implement `mcp::transport::Transport` | — | Unix socket, in-memory loopback, etc.

## Capability Negotiation

During `initialize`, client and server exchange capability declarations. This tells each side what the other supports.

    // Server declares capabilities via builder
    auto server = mcp::ServerPeer::builder()
        .name("my-server")
        .version("1.0.0")
        .stdio()
        .tool(...)         // enables tools capability
        .prompt(...)       // enables prompts capability
        .resource(...)     // enables resources capability
        .build();

    // Client discovers capabilities after initialize
    auto& caps = svc.peer().server_capabilities();
    if (caps.tools) {
        auto tools = svc.peer().list_all_tools();
        // ...
    }

### Server Capabilities

tools, resources, prompts, logging, completions, tasks, experimental, extensions

### Client Capabilities

roots, sampling, elicitation, tasks, experimental, extensions

## Protocol Model

All MCP messages are JSON-RPC 2.0. The SDK provides typed C++ structs for every protocol object:

- `ToolDefinition`, `ToolResult`
- `Prompt`, `PromptMessage`, `PromptsGetResult`
- `Resource`, `ResourceContents`, `ResourceTemplate`
- `ContentBlock` (text, image, audio, embedded resource)
- `JsonRpcRequest`, `JsonRpcResponse`, `JsonRpcNotification`

Use `CXXMCP_REFLECT` on your own types to get automatic JSON serialization and JSON Schema generation. See Tutorials for examples.

## Reflection System

The reflection system gives you zero-boilerplate DTO serialization. One macro replaces hand-written `to_json`/`from_json` for every struct.

    #include <cxxmcp/protocol/reflect.hpp>

    struct MyInput {
        std::string name;
        int count;
        std::optional<std::string> tag;
    };

    CXXMCP_REFLECT(MyInput, name, count, tag)

This gives you:

- `reflect_to_json<MyInput>(value)` — serialize to JSON
- `reflect_from_json<MyInput>(json)` — deserialize from JSON
- `schema_for<MyInput>()` — auto-generated JSON Schema
- `has_reflect_v<MyInput>` — compile-time trait (`true`)

Supported field types: scalars, `std::string`, `std::optional<T>`, `std::vector<T>`, `std::variant`, `std::map`, nested reflected types, and raw `Json`.

## Next Steps

- Tutorials — build working examples step by step
- Cookbook — quick code snippets for common tasks
- Getting Started — install and first build
- API Reference — generated symbol-level docs