内容
# mcpp
现代 C++20 客户端库,用于 [模型上下文协议(MCP)](https://modelcontextprotocol.io/)。
## 功能特点
- **完整的 MCP 协议支持** - 工具、资源、提示、补全、订阅
- **多种传输方式** - 进程(stdio)、HTTP with SSE
- **同步和异步 API** - 阻塞式 `McpClient` 和基于协程的 `AsyncMcpClient`
- **生产就绪** - 熔断器、URL 验证、会话管理、重试逻辑
- **现代 C++** - C++20 协程、概念、`std::expected` 风格的错误处理
- **全面的测试** - 495+ 个测试,涵盖单元测试、集成测试和真实服务器场景
## 架构概览
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ 您的应用程序 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │
│ │ McpClient │ │ AsyncMcpClient │ │
│ │ (同步) │ │ (协程) │ │
│ └──────────────┬──────────────┘ └──────────────┬──────────────┘ │
│ │ │ │
│ ┌──────────────┴───────────────────────────────────┴──────────────┐ │
│ │ 传输层 │ │
│ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │
│ │ │ 进程传输 │ │ HTTP 传输 │ │ │
│ │ │ (stdio 到子进程) │ (HTTP + SSE) │ │ │
│ │ └─────────────────────┘ └─────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ 弹性 & 安全 │ │
│ │ ┌───────────────┐ ┌───────────────┐ ┌───────────────────┐ │ │
│ │ │ 熔断器 │ │ URL 验证器 │ │ 会话管理器 │ │ │
│ │ └───────────────┘ └───────────────┘ └───────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ MCP 服务器 │
│ (文件系统、GitHub、Slack、自定义 AI 代理等) │
└─────────────────────────────────────────────────────────────────────────────┘
```
## 快速入门
### 要求
- C++20 编译器(GCC 11+,Clang 14+,MSVC 2022+)
- CMake 3.20+
### 构建
```bash
git clone https://github.com/your-org/mcpp.git
cd mcpp
mkdir build && cd build
cmake ..
make -j$(nproc)
```
### 基本用法
```cpp
#include <mcpp/transport/process_transport.hpp>
#include <mcpp/client/mcp_client.hpp>
using namespace mcpp;
int main() {
// 通过 stdio 连接到 MCP 服务器
ProcessTransportConfig config;
config.command = "npx";
config.args = {"-y", "@modelcontextprotocol/server-filesystem", "/tmp"};
auto transport = std::make_unique<ProcessTransport>(config);
transport->start();
McpClient client(std::move(transport));
client.connect();
client.initialize();
// 列出可用工具
auto tools = client.list_tools();
if (tools) {
for (const auto& tool : tools->tools) {
std::cout << "工具:" << tool.name << "\n";
}
}
// 调用工具
auto result = client.call_tool("read_file", {{"path", "/tmp/test.txt"}});
if (result) {
for (const auto& content : result->content) {
if (content.type == "text") {
std::cout << content.text.value_or("") << "\n";
}
}
}
client.disconnect();
return 0;
}
```
## 请求/响应流程
```
┌────────────┐ ┌────────────┐
│ 客户端 │ │ 服务器 │
└─────┬──────┘ └─────┬──────┘
│ │
│ ──────────── 初始化 ──────────────────► │
│ ◄─────────── 初始化结果 ──────────── │
│ │
│ ──────────── 通知/初始化 ───► │
│ │
│ ──────────── 工具/列表 ──────────────────► │
│ ◄─────────── 列表工具结果 ───────────── │
│ │
│ ──────────── 工具/调用 ──────────────────► │
│ ◄─────────── 调用工具结果 ────────────── │
│ │
│ ◄─────────── 通知/进度 ────── │ (可选)
│ │
│ ──────────── ping ────────────────────────► │
│ ◄─────────── pong ──────────────────────── │
│ │
▼ ▼
```
## 示例
在 [`examples/`](examples/) 目录中查看完整的示例:
| 示例 | 描述 |
|---------|-------------|
| [01_basic_sync](examples/01_basic_sync/) | 同步客户端基础 |
| [02_basic_async](examples/02_basic_async/) | 异步/协程客户端 |
| [03_filesystem_server](examples/03_filesystem_server/) | 文件操作 |
| [04_http_transport](examples/04_http_transport/) | 远程 HTTP 服务器 |
| [05_custom_handlers](examples/05_custom_handlers/) | 诱导、采样、根 |
| [06_circuit_breaker](examples/06_circuit_breaker/) | 弹性模式 |
| [07_arcade_toolkit](examples/07_arcade_toolkit/) | Arcade AI 集成 |
## MCP 协议覆盖
| 功能 | 状态 | 描述 |
|---------|--------|-------------|
| 初始化/关闭 | ✅ | 会话生命周期 |
| 工具(列表、调用) | ✅ | 执行服务器提供的工具 |
| 资源(列表、读取、订阅) | ✅ | 访问服务器资源 |
| 资源模板 | ✅ | URI 模板发现 |
| 提示(列表、获取) | ✅ | 提示模板 |
| 补全 | ✅ | 自动补全 API |
| Ping | ✅ | 健康检查 |
| 取消 | ✅ | 取消进行中的操作 |
| 进度通知 | ✅ | 跟踪长时间运行的操作 |
| 日志控制 | ✅ | 服务器日志级别 |
| 诱导处理程序 | ✅ | 用户输入请求 |
| 采样处理程序 | ✅ | LLM 补全请求 |
| 根处理程序 | ✅ | 文件系统根暴露 |
## 传输
### 进程传输(stdio)
```
┌──────────────┐ stdin ┌──────────────┐
│ 客户端 │───────────────►│ 服务器 │
│ │◄───────────────│ (进程) │
└──────────────┘ stdout └──────────────┘
```
```cpp
ProcessTransportConfig config;
config.command = "python";
config.args = {"-m", "my_mcp_server"};
config.use_content_length_framing = false; // 或 true 表示帧模式
config.working_directory = "/path/to/server";
config.environment = {{"API_KEY", "secret"}};
```
### HTTP 传输(HTTP + SSE)
```
┌──────────────┐ POST /message ┌──────────────┐
│ 客户端 │──────────────────►│ 服务器 │
│ │◄──────────────────│ (HTTP) │
└──────────────┘ SSE /sse └──────────────┘
```
```cpp
HttpClientConfig config;
config.base_url = "https://api.example.com/mcp/";
config.headers = {{"Authorization", "Bearer token"}};
config.timeout = std::chrono::seconds(30);
```
## 错误处理
使用 `tl::expected` 进行显式错误处理,无需异常:
```cpp
auto result = client.call_tool("my_tool", args);
if (!result) {
switch (result.error().code) {
case ClientErrorCode::NotConnected:
// 处理连接错误
break;
case ClientErrorCode::TransportError:
// 处理传输失败
break;
case ClientErrorCode::ProtocolError:
// 处理协议错误
break;
}
return;
}
// 使用 result.value()
```
## 熔断器
```
CLOSED ──────► OPEN ──────► HALF-OPEN
▲ │ │
│ │ 成功 │
└────────────┴───────────────┘
失败:回到 OPEN
```
```cpp
McpClientConfig config;
config.enable_circuit_breaker = true;
config.circuit_breaker.failure_threshold = 5;
config.circuit_breaker.recovery_timeout = std::chrono::seconds(30);
McpClient client(std::move(transport), config);
if (client.is_circuit_open()) {
// 快速失败,不要等待超时
}
```
## CLI 工具
```bash
# 列出工具
./mcpp-cli -c 'npx' -a '-y' -a '@modelcontextprotocol/server-filesystem' -a '/tmp' --list-tools
# 调用工具
./mcpp-cli -c 'python' -a 'server.py' --call-tool read_file --tool-args '{"path":"/tmp/test.txt"}'
# 交互模式
./mcpp-cli -c 'node' -a 'server.js' --interactive
# JSON 输出
./mcpp-cli -c 'python' -a 'server.py' --list-tools --json
```
## 项目结构
```
mcpp/
├── include/mcpp/
│ ├── protocol/ # MCP 类型和 JSON 序列化
│ ├── transport/ # 传输层(进程、HTTP/SSE)
│ ├── client/ # 同步 McpClient
│ ├── async/ # 异步 AsyncMcpClient
│ ├── resilience/ # 熔断器
│ ├── security/ # URL 验证
│ └── log/ # 日志接口
├── src/ # 实现文件
├── tests/ # 测试套件(495+ 个测试)
├── tools/mcpp-cli/ # 命令行界面
└── examples/ # 使用示例
```
## 依赖
所有依赖项均通过 CMake FetchContent 自动获取:
- [nlohmann/json](https://github.com/nlohmann/json) - JSON 解析
- [ASIO](https://think-async.com/Asio/) - 异步 I/O 和协程
- [tl::expected](https://github.com/TartanLlama/expected) - 错误处理
- [ada-url](https://github.com/nickvidal/ada) - URL 解析
- [spdlog](https://github.com/gabime/spdlog) - 日志记录
- [cpr](https://github.com/libcpr/cpr) - HTTP 客户端
- [Catch2](https://github.com/catchorg/Catch2) - 测试
- [cxxopts](https://github.com/jarro2783/cxxopts) - CLI 解析
## 运行测试
```bash
cd build
ctest --output-on-failure
# 或直接运行
./mcpp_tests # 所有测试
./mcpp_tests "[mcp_client]" # 客户端测试
./mcpp_tests "[real-server]" # 集成测试
```
## 许可证
MIT 许可证 - 请参阅 [LICENSE](LICENSE) 文件。