Troubleshooting

Common issues and how to fix them.

Solutions for build errors, runtime problems, and integration issues.

Build Errors

CMake cannot find cxxmcp

Error: Could not find a package configuration file provided by "cxxmcp"

Solution: Install the SDK first, or use FetchContent:

# Option 1: Install then consume
cmake --install build --prefix /path/to/install
cmake -S myapp -B build -DCMAKE_PREFIX_PATH=/path/to/install

# Option 2: FetchContent (no install needed)
include(FetchContent)
FetchContent_Declare(cxxmcp URL https://github.com/caomengxuan666/cxxmcp/releases/download/v1.1.6/cxxmcp-sdk-source-v1.1.6.tar.gz)
FetchContent_MakeAvailable(cxxmcp)

HTTP transport symbols not found

Error: undefined reference to mcp::transport::StreamableHttpServerTransport

Solution: HTTP transport is off by default. Enable it:

cmake -S . -B build -DCXXMCP_ENABLE_HTTP=ON

Auth target not found

Error: Target "cxxmcp::auth" not found

Solution: Auth is opt-in:

cmake -S . -B build -DCXXMCP_ENABLE_AUTH=ON

# With OpenSSL DPoP/JWKS support
cmake -S . -B build -DCXXMCP_ENABLE_AUTH=ON -DCXXMCP_AUTH_CRYPTO=OpenSSL

OpenSSL not found

Error: Could not find a package configuration file provided by "OpenSSL"

Solution: Tell CMake where OpenSSL is:

# Windows (vcpkg)
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake

# Linux (system package)
sudo apt install libssl-dev
cmake -S . -B build

# Manual path
cmake -S . -B build -DOPENSSL_ROOT_DIR=/path/to/openssl

C++17 compiler errors

Error: error: 'optional' is not a member of 'std'

Solution: Ensure C++17 is enabled:

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

vcpkg cannot find cxxmcp

Error: error: Unable to find package cxxmcp-sdk

Solution: Use the overlay port from the repository:

vcpkg install cxxmcp-sdk --overlay-ports=path/to/cxxmcp/packaging/vcpkg/ports

Runtime Issues

Server does not respond to tools/list

Symptom: Client sends tools/list but gets method-not-found.

Solution: You must register at least one tool with the builder. An empty server has no tools capability:

auto server = mcp::ServerPeer::builder()
    .name("my-server").version("1.0.0").stdio()
    .tool<Json, Json>("echo", handler)  // This enables the tools capability
    .build();

HTTP server connection refused

Symptom: Client gets connection refused on HTTP.

Solution: Call wait_until_ready() before connecting:

auto running = mcp::serve(std::move(*server));
running->wait_until_ready();  // Wait for socket to bind
// Now safe to connect clients

Bearer token rejected

Symptom: Server returns 401 Unauthorized.

Solution: Ensure the auth provider is set before building:

auto auth = std::make_unique<mcp::server::StaticBearerAuthProvider>();
auth->add_token("my-token", mcp::server::AuthIdentity{"user", {}});

auto server = mcp::ServerPeer::builder()
    .name("my-server").version("1.0.0")
    .auth_provider(std::move(auth))  // Must be before .build()
    .streamable_http(...)
    .build();

Tool handler not called

Symptom: tools/call returns method-not-found.

Solution: Tool name in call_tool() must match the registered name exactly (case-sensitive):

// Registration
.tool<Json, Json>("my_tool", handler)

// Call — must match exactly
svc.peer().call_tool("my_tool", Json{{}});  // OK
svc.peer().call_tool("My_Tool", Json{{}});  // FAILS

Process stdio server exits immediately

Symptom: Client launches server process but it exits right away.

Solution: The server must block on wait():

auto running = mcp::serve(std::move(*server));
running->wait();  // Blocks until stdin closes or shutdown

Reflection and Serialization

CXXMCP_REFLECT compilation error

Error: no matching function for call to 'Reflect'

Solution: Place the macro at namespace scope. Global scope is the usual choice:

struct MyType { std::string name; int value; };

CXXMCP_REFLECT(MyType, name, value)

JSON deserialization returns empty fields

Symptom: Fields are default-initialized after reflect_from_json.

Solution: JSON keys must match the C++ field names exactly:

// C++ field: std::string query;
// JSON must have: {"query": "value"}
// NOT: {"q": "value"}

Optional field not serialized

Symptom: std::optional<T> field is missing from output JSON.

Behavior: This is correct. Empty optionals are omitted from JSON output. They deserialize as std::nullopt when the key is absent.

Conformance Testing

Conformance runner not found

Solution: The runner is a separate tool. See modelcontextprotocol/conformance:

git clone https://github.com/modelcontextprotocol/conformance.git
cd conformance
npm install
npm run build
node dist/cli.js --suite all --server-command "path/to/your/server"

Server conformance: 109/110

Result: 109 of 110 server tests pass. All 448 client tests pass.

Note: The remaining server exception is the SEP-2243 missing-method-header case described in conformance evidence.

Still Stuck?