Skip to content

MKAbdElrahman/cpp-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP C++ SDK

A C++ implementation of the Model Context Protocol (MCP) with full stdio transport support including process spawning.

Installation

Using CMake FetchContent

Add the MCP SDK to your CMake project:

include(FetchContent)

FetchContent_Declare(
    mcp-sdk
    GIT_REPOSITORY https://github.com/MKAbdElrahman/cpp-mcp-sdk.git
    GIT_TAG main
)

FetchContent_MakeAvailable(mcp-sdk)

# Link to your target
target_link_libraries(your_target PRIVATE mcp)

# Include headers
target_include_directories(your_target PRIVATE ${mcp-sdk_SOURCE_DIR}/include)

Manual Build and Install

git clone https://github.com/MKAbdElrahman/cpp-mcp-sdk.git
cd cpp-mcp-sdk
mkdir build && cd build
cmake ..
make
sudo make install  # Optional: install system-wide

Then in your CMakeLists.txt:

# If installed system-wide
find_package(mcp REQUIRED)
target_link_libraries(your_target PRIVATE mcp)

# Or use local build
target_include_directories(your_target PRIVATE /path/to/cpp-mcp-sdk/include)
target_link_libraries(your_target PRIVATE /path/to/cpp-mcp-sdk/build/libmcp.a pthread)

Usage

Client - Spawn MCP Server

#include <mcp/transport/stdio_client_transport.hpp>

using namespace mcp;

// Configure server to spawn
StdioServerParameters params("python");
params.with_args({"my_mcp_server.py"})
      .with_env({{"API_KEY", "secret"}})
      .with_cwd("/path/to/server");

// Create and connect
auto transport = create_stdio_client_transport(params);

// Communicate
json request = {{"jsonrpc", "2.0"}, {"method", "tools/list"}, {"id", 1}};
transport->write(request);
json response = transport->read();

// Clean shutdown (automatic in destructor)
transport->close();

Server - Handle Stdio Transport

#include <mcp/transport/stdio_transport.hpp>

using namespace mcp;

// Use stdin/stdout
StdioConnection conn(std::cin, std::cout);

// Read requests
json request = conn.read();

// Send responses
json response = {{"jsonrpc", "2.0"}, {"id", request["id"]}, {"result", {}}};
conn.write(response);

Testing

IMPORTANT: Always build from the build/ directory to keep source tree clean.

Recommended: Build from build directory

mkdir -p build && cd build
cmake ..
make
ctest --output-on-failure

# For verbose output
ctest --output-on-failure --verbose

Alternative: Using Makefile wrapper

# From project root (uses build/ directory)
make clean  # Clean build
make        # Build all
make test   # Run tests

Do NOT run cmake or make from the project root - this will pollute the source tree with build artifacts.

Features

  • Full MCP protocol support (protocol version 2025-06-18)
  • Stdio transport with process spawning
  • Client and server implementations
  • Tools, resources, and prompts support
  • Elicitation support - Interactive user input requests (NEW!)
  • Thread-safe design
  • Comprehensive test suite

Elicitation Support

Elicitation allows servers to interactively request structured information from users during tool execution or other operations.

Server Usage

#include <mcp/server/server_session.hpp>
#include <mcp/types/elicitation.hpp>

// In a tool handler with access to ServerSession*
json schema = {
    {"type", "object"},
    {"properties", {
        {"apiKey", {{"type", "string"}}},
        {"timeout", {{"type", "number"}, {"minimum", 1}}},
        {"debug", {{"type", "boolean"}}}
    }},
    {"required", json({"apiKey"})}
};

ElicitRequestParams params;
params.message = "Please provide your API configuration";
params.requestedSchema = schema;

ElicitResult result = session->send_elicit_request(params);

if (result.action == ElicitAction::Accept) {
    auto api_key = (*result.content)["apiKey"].get<std::string>();
    // Use configuration...
}

Client Usage

#include <mcp/client/client.hpp>

// Define elicitation handler
ClientOptions options;
options.elicitation_handler = [](const ElicitRequestParams& params) {
    std::cout << "Server asks: " << params.message << std::endl;

    // Collect user input (show UI, prompt, etc.)
    ElicitResult result;
    result.action = ElicitAction::Accept;
    result.content = {
        {"apiKey", "sk-test-12345"},
        {"timeout", 30},
        {"debug", true}
    };
    return result;
};

// Client automatically advertises elicitation capability
Client client("my-client", "1.0.0", options);

See docs/ELICITATION.md for detailed documentation and examples/elicitation_example.cpp for a complete example.

Documentation

About

C++ SDK for the Model Context Protocol

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •