cpp-mcp/include/mcp_client.h

248 lines
6.4 KiB
C
Raw Normal View History

2025-03-08 01:50:39 +08:00
/**
* @file mcp_client.h
2025-03-08 22:49:19 +08:00
* @brief MCP Client implementation
2025-03-08 01:50:39 +08:00
*
* This file implements the client-side functionality for the Model Context Protocol.
2025-03-10 03:24:54 +08:00
* Follows the 2024-11-05 protocol specification.
2025-03-08 01:50:39 +08:00
*/
#ifndef MCP_CLIENT_H
#define MCP_CLIENT_H
2025-03-08 22:49:19 +08:00
#include "mcp_message.h"
#include "mcp_tool.h"
2025-03-08 01:50:39 +08:00
// Include the HTTP library
#include "httplib.h"
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <mutex>
#include <functional>
2025-03-11 23:29:38 +08:00
#include <atomic>
#include <condition_variable>
#include <future>
2025-03-08 01:50:39 +08:00
namespace mcp {
/**
* @class client
* @brief Client for connecting to MCP servers
*
* The client class provides functionality to connect to MCP servers,
2025-03-08 22:49:19 +08:00
* initialize the connection, and send/receive JSON-RPC messages.
2025-03-08 01:50:39 +08:00
*/
class client {
public:
/**
* @brief Constructor
* @param host The server host (e.g., "localhost", "example.com")
* @param port The server port
*/
2025-03-11 23:29:38 +08:00
client(const std::string& host, int port = 8080, const json& capabilities = json::object(), const std::string& sse_endpoint = "/sse");
2025-03-10 03:24:54 +08:00
/**
* @brief Constructor
* @param base_url The base URL of the server (e.g., "localhost:8080")
2025-03-10 03:24:54 +08:00
* @param capabilities The capabilities of the client
*/
2025-03-11 23:29:38 +08:00
client(const std::string& base_url, const json& capabilities = json::object(), const std::string& sse_endpoint = "/sse");
2025-03-10 03:24:54 +08:00
2025-03-08 01:50:39 +08:00
/**
* @brief Destructor
*/
~client();
/**
2025-03-08 22:49:19 +08:00
* @brief Initialize the connection with the server
* @param client_name The name of the client
* @param client_version The version of the client
* @return True if initialization was successful
2025-03-08 01:50:39 +08:00
*/
2025-03-08 22:49:19 +08:00
bool initialize(const std::string& client_name, const std::string& client_version);
2025-03-09 17:24:46 +08:00
/**
* @brief Ping request
* @return True if the server is alive
*/
bool ping();
2025-03-08 22:49:19 +08:00
/**
* @brief Set authentication token
* @param token The authentication token
*/
void set_auth_token(const std::string& token);
2025-03-08 01:50:39 +08:00
/**
* @brief Set a request header that will be sent with all requests
* @param key Header name
* @param value Header value
*/
void set_header(const std::string& key, const std::string& value);
/**
* @brief Set timeout for requests
* @param timeout_seconds Timeout in seconds
*/
void set_timeout(int timeout_seconds);
2025-03-08 22:49:19 +08:00
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Set client capabilities
* @param capabilities The capabilities of the client
2025-03-08 01:50:39 +08:00
*/
2025-03-08 22:49:19 +08:00
void set_capabilities(const json& capabilities);
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Send a request and wait for a response
* @param method The method to call
* @param params The parameters to pass
* @return The response
2025-03-08 01:50:39 +08:00
* @throws mcp_exception on error
*/
2025-03-08 22:49:19 +08:00
response send_request(const std::string& method, const json& params = json::object());
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Send a notification (no response expected)
* @param method The method to call
* @param params The parameters to pass
2025-03-08 01:50:39 +08:00
* @throws mcp_exception on error
*/
2025-03-08 22:49:19 +08:00
void send_notification(const std::string& method, const json& params = json::object());
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Get server capabilities
* @return The server capabilities
2025-03-08 01:50:39 +08:00
* @throws mcp_exception on error
*/
2025-03-08 22:49:19 +08:00
json get_server_capabilities();
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Call a tool
* @param tool_name The name of the tool to call
2025-03-09 17:10:01 +08:00
* @param arguments The arguments to pass to the tool
2025-03-08 22:49:19 +08:00
* @return The result of the tool call
2025-03-08 01:50:39 +08:00
* @throws mcp_exception on error
*/
2025-03-09 17:10:01 +08:00
json call_tool(const std::string& tool_name, const json& arguments = json::object());
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Get available tools
* @return List of available tools
2025-03-08 01:50:39 +08:00
* @throws mcp_exception on error
*/
2025-03-08 22:49:19 +08:00
std::vector<tool> get_tools();
2025-03-08 01:50:39 +08:00
/**
2025-03-08 22:49:19 +08:00
* @brief Get client capabilities
* @return The client capabilities
2025-03-08 01:50:39 +08:00
*/
2025-03-08 22:49:19 +08:00
json get_capabilities();
2025-03-10 03:24:54 +08:00
2025-03-08 01:50:39 +08:00
/**
2025-03-10 03:24:54 +08:00
* @brief List available resources
* @param cursor Optional cursor for pagination
* @return List of resources
*/
json list_resources(const std::string& cursor = "");
/**
* @brief Read a resource
* @param resource_uri The URI of the resource
* @return The resource content
*/
json read_resource(const std::string& resource_uri);
/**
* @brief Subscribe to resource changes
* @param resource_uri The URI of the resource
* @return Subscription result
*/
json subscribe_to_resource(const std::string& resource_uri);
/**
* @brief List resource templates
* @return List of resource templates
2025-03-08 01:50:39 +08:00
*/
2025-03-10 03:24:54 +08:00
json list_resource_templates();
2025-03-08 01:50:39 +08:00
/**
* @brief 访
* @return True if the server is accessible
*/
bool check_server_accessible();
2025-03-08 01:50:39 +08:00
private:
// 初始化HTTP客户端
void init_client(const std::string& host, int port);
void init_client(const std::string& base_url);
// 打开SSE连接
void open_sse_connection();
// 解析SSE数据
bool parse_sse_data(const char* data, size_t length);
// 关闭SSE连接
void close_sse_connection();
// 发送JSON-RPC请求
json send_jsonrpc(const request& req);
// 服务器主机和端口
2025-03-08 01:50:39 +08:00
std::string host_;
int port_ = 8080;
// 或者使用基础URL
std::string base_url_;
// SSE端点
std::string sse_endpoint_ = "/sse";
// 消息端点
2025-03-11 23:29:38 +08:00
std::string msg_endpoint_;
// HTTP客户端
std::unique_ptr<httplib::Client> http_client_;
// SSE线程
std::unique_ptr<std::thread> sse_thread_;
// SSE运行状态
std::atomic<bool> sse_running_{false};
// 认证令牌
2025-03-08 22:49:19 +08:00
std::string auth_token_;
// 默认请求头
std::map<std::string, std::string> default_headers_;
// 超时设置(秒)
2025-03-08 01:50:39 +08:00
int timeout_seconds_ = 30;
// 客户端能力
2025-03-08 22:49:19 +08:00
json capabilities_;
2025-03-08 01:50:39 +08:00
// 服务器能力
json server_capabilities_;
2025-03-08 01:50:39 +08:00
// 互斥锁
2025-03-08 01:50:39 +08:00
mutable std::mutex mutex_;
// 条件变量,用于等待消息端点设置
std::condition_variable endpoint_cv_;
2025-03-11 23:29:38 +08:00
// 请求ID到Promise的映射用于异步等待响应
std::map<json, std::promise<json>> pending_requests_;
2025-03-08 01:50:39 +08:00
// 响应处理互斥锁
std::mutex response_mutex_;
2025-03-08 01:50:39 +08:00
// 响应条件变量
std::condition_variable response_cv_;
2025-03-08 01:50:39 +08:00
};
} // namespace mcp
#endif // MCP_CLIENT_H