Skip to content

About

A modern C++20 Model Context Protocol SDK

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

485 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mcp-cpp-sdk

A modern C++20 implementation of the Model Context Protocol (MCP), enabling seamless integration between LLM applications and external tools, resources, and prompts.

C++20 License: Apache 2.0 Build Status Conformance baseline

Why mcp-cpp-sdk?

  • Modern C++20: Coroutine-based asynchronous I/O with Boost.Asio.
  • Shared or Static: The same public API is available through explicit CMake targets for either linkage model.
  • Typed Protocol Models: Strongly typed models for the supported MCP surface, with nlohmann/json interoperability.
  • Flexible Transports: Native support for Stdio, WebSocket, and Streamable HTTP.
  • Measured Interoperability: Official client and server conformance suites run in CI against a pinned 2025-11-25 regression baseline, with unsupported scenarios kept visible. A green baseline means no drift, not that an SDK tier has been achieved.

How this implementation differs

The SDK combines a compiled client/server/transport runtime with header-based protocol models and typed handler templates. Ordinary tool return values are normalized into protocol-valid structured results, while complete raw CallToolResult values use an explicit API. Interoperability and performance claims are kept reproducible through the pinned conformance baseline and the shared-workload benchmark adapters in benchmark/.

Quick Start

1. Installation

Package-manager routes are documented in the installation guide. The GitHub, Cloudsmith (APT/RPM), and AUR jobs read the exact published object back before reporting success. ConanCenter, Homebrew, and Chocolatey remain pending while their provider review or moderation is outstanding. Install only after the requested version appears at the destination; an upload or open registry PR is not availability proof.

Versions 0.x.y are stable releases unless suffixed with -rc.N, but each pre-1.0 release has a distinct binary identity. Rebuild or relink consumers when changing 0.x versions; see the installation guide for exact CMake and runtime-package names.

The easiest way to use the SDK is via CMake's FetchContent:

include(FetchContent)
FetchContent_Declare(
    mcp-cpp-sdk
    GIT_REPOSITORY https://github.com/yurirocha15/mcp-cpp-sdk.git
    # Replace with a verified release tag or full 40-character commit.
    GIT_TAG <verified-tag-or-commit>
)
FetchContent_MakeAvailable(mcp-cpp-sdk)

target_link_libraries(your_target PRIVATE mcp::sdk)

2. Create a Minimal Server

#include <mcp/mcp.hpp>

int main() {
    mcp::ServerCapabilities capabilities;
    capabilities.tools = mcp::ServerCapabilities::ToolsCapability{};
    mcp::Server server({"hello-server", "1.0.0"}, capabilities);

    server.add_tool("hello", "Greets the user",
        {{"type", "object"}, {"properties", {{"name", {{"type", "string"}}}}}},
        [](const nlohmann::json& args) -> nlohmann::json {
            return nlohmann::json{
                {"message", "Hello, " + args["name"].get<std::string>() + "!"}};
        });

    server.run_http("127.0.0.1", 3000); // Serves http://127.0.0.1:3000/mcp
}

3. Create a Minimal Client

#include <mcp/client/client.hpp>
#include <mcp/transport/http_client.hpp>

#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <iostream>
#include <memory>

int main() {
    boost::asio::io_context io;
    auto transport = std::make_shared<mcp::HttpClientTransport>(
        io.get_executor(), "http://127.0.0.1:3000/mcp");
    mcp::Client client(transport, io.get_executor());

    boost::asio::co_spawn(io, [&]() -> mcp::Task<void> {
        co_await client.connect("my-client", "1.0.0");
        nlohmann::json arguments{{"name", "World"}};
        auto result = co_await client.call_tool("hello", arguments);
        std::cerr << nlohmann::json(result).dump(2) << '\n';
        client.close();
    }, boost::asio::detached);

    io.run();
}

Note the named arguments variable. See Compiler Notes for why it is not built inline.

Usage Highlights

Tools, Resources, and Prompts

Resources and prompts use the same typed-handler model as tools: provide the protocol metadata (mcp::Resource, mcp::ResourceTemplate, or mcp::Prompt) and a handler whose input and output are serializable protocol types. See the stdio server example for complete, compiled registrations.

Server Context (Logging & Progress)

Async handlers have access to a Context for real-time interaction:

server.add_tool<nlohmann::json, nlohmann::json>("long_task", "A task with progress", schema,
    [](mcp::Context& ctx, const nlohmann::json& args) -> mcp::Task<nlohmann::json> {
        co_await ctx.log_info("Starting work...");
        co_await ctx.report_progress(50, 100);
        co_return nlohmann::json{{"status", "done"}};
    });

Compiler Notes

GCC 12 and 13: initializer lists inside a co_await expression

GCC 12 and GCC 13 crash with an internal compiler error when a co_await expression contains an initializer list whose elements have non-trivial destructors. GCC 13 is the default compiler on Ubuntu 24.04, so this is easy to hit on a stock toolchain. The error looks like this with GCC 13.3 (GCC 12.4 reports line 10556), and names the closing brace of the enclosing lambda rather than the offending argument:

internal compiler error: in build_special_member_call, at cp/call.cc:11096

Build the container into a named variable first:

// Crashes GCC 12 and GCC 13
auto result = co_await client.call_tool("hello", nlohmann::json{{"name", "World"}});
auto prompt = co_await client.get_prompt("greet", std::map<std::string, std::string>{{"who", "you"}});

// Compiles
nlohmann::json arguments{{"name", "World"}};
auto result = co_await client.call_tool("hello", arguments);

The trigger is the initializer list, not the type, so it is not specific to nlohmann::json: std::map<std::string, std::string>{{"a", "b"}} and std::vector<std::string>{"a", "b"} crash the same way, while std::vector<int>{1, 2, 3} and nlohmann::json::object() do not. Parentheses do not help, because nlohmann::json({{"a", 1}}) still forms an initializer list. Only hoisting the value out of the co_await expression avoids it.

This is a compiler defect rather than an SDK one, and no change to the SDK's signatures avoids it: taking the argument by value instead of by reference still crashes.

The contributing guide's Known Issues section carries the full case list, alongside the separate GCC 11 coroutine bug this codebase also works around.

Documentation

For full guides, API reference, and integration details, visit our Documentation Site.


For Developers

This section is for contributors and developers wanting to build, test, and contribute to mcp-cpp-sdk itself.

Building from Source

To build the library, tests, and examples locally:

# Install dependencies
python scripts/init.py

# Build project (release with examples and tests)
python scripts/build.py --examples --test

Build Commands Reference

Flag Description
--debug Build in debug mode
--test Build and run unit tests
--examples Build example applications
--conformance Build fixtures for the official MCP conformance runner
--linkage {both,shared,static} Select which SDK linkage variants to build
--cppstd {20,23} Select the C++ consumer standard (default: C++20)
--sanitize Build with ASan/UBSan (Linux/macOS)
--docs Generate local Doxygen + Sphinx documentation
--clean Clean build artifacts

Code Quality & Standards

  • Formatting: make format (requires clang-format)
  • Linting: make lint (requires clang-tidy)
  • Testing: We use GoogleTest for all unit and integration tests.

Contributing

Please see the CONTRIBUTING guide for the full process.

Project maintenance commitments and release gates are documented in the maintenance policy, dependency policy, versioning policy, Tier roadmap, and security policy.

License

Apache License 2.0 - see LICENSE for details.

Package Hosting

OSS hosting by Cloudsmith

Package repository hosting is graciously provided by Cloudsmith. Cloudsmith is the only fully hosted, cloud-native, universal package management solution that enables your organization to create, store and share packages in any format, to any place, with total confidence.

About

A modern C++20 Model Context Protocol SDK

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages