A C++ implementation of the Model Context Protocol (MCP) with full stdio transport support including process spawning.
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)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-wideThen 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)#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();#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);IMPORTANT: Always build from the build/ directory to keep source tree clean.
mkdir -p build && cd build
cmake ..
make
ctest --output-on-failure
# For verbose output
ctest --output-on-failure --verbose# From project root (uses build/ directory)
make clean # Clean build
make # Build all
make test # Run testsDo NOT run cmake or make from the project root - this will pollute the source tree with build artifacts.
- 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 allows servers to interactively request structured information from users during tool execution or other operations.
#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...
}#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.
- Process Spawning Guide - Detailed usage and API reference
- Elicitation Guide - Interactive user input requests
- Examples - Working code examples
- Tests - Comprehensive test suite