cpp-mcp/include/mcp_client.h

252 lines
6.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/**
* @file mcp_client.h
* @brief MCP Client implementation
*
* This file implements the client-side functionality for the Model Context Protocol.
* Follows the 2024-11-05 protocol specification.
*/
#ifndef MCP_CLIENT_H
#define MCP_CLIENT_H
#include "mcp_message.h"
#include "mcp_tool.h"
#include "mcp_logger.h"
// Include the HTTP library
#include "httplib.h"
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <mutex>
#include <functional>
#include <atomic>
#include <condition_variable>
#include <future>
namespace mcp {
/**
* @class client
* @brief Client for connecting to MCP servers
*
* The client class provides functionality to connect to MCP servers,
* initialize the connection, and send/receive JSON-RPC messages.
*/
class client {
public:
/**
* @brief Constructor
* @param host The server host (e.g., "localhost", "example.com")
* @param port The server port
* @param sse_endpoint The endpoint for server-sent events
*/
client(const std::string& host, int port = 8080, const std::string& sse_endpoint = "/sse");
/**
* @brief Constructor
* @param base_url The base URL of the server (e.g., "localhost:8080")
*/
client(const std::string& base_url, const std::string& sse_endpoint = "/sse");
/**
* @brief Destructor
*/
~client();
/**
* @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
*/
bool initialize(const std::string& client_name, const std::string& client_version);
/**
* @brief Ping request
* @return True if the server is alive
*/
bool ping();
/**
* @brief Set authentication token
* @param token The authentication token
*/
void set_auth_token(const std::string& token);
/**
* @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);
/**
* @brief Set client capabilities
* @param capabilities The capabilities of the client
*/
void set_capabilities(const json& capabilities);
/**
* @brief Send a request and wait for a response
* @param method The method to call
* @param params The parameters to pass
* @return The response
* @throws mcp_exception on error
*/
response send_request(const std::string& method, const json& params = json::object());
/**
* @brief Send a notification (no response expected)
* @param method The method to call
* @param params The parameters to pass
* @throws mcp_exception on error
*/
void send_notification(const std::string& method, const json& params = json::object());
/**
* @brief Get server capabilities
* @return The server capabilities
* @throws mcp_exception on error
*/
json get_server_capabilities();
/**
* @brief Call a tool
* @param tool_name The name of the tool to call
* @param arguments The arguments to pass to the tool
* @return The result of the tool call
* @throws mcp_exception on error
*/
json call_tool(const std::string& tool_name, const json& arguments = json::object());
/**
* @brief Get available tools
* @return List of available tools
* @throws mcp_exception on error
*/
std::vector<tool> get_tools();
/**
* @brief Get client capabilities
* @return The client capabilities
*/
json get_capabilities();
/**
* @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
*/
json list_resource_templates();
/**
* @brief 检查服务器是否可访问
* @return True if the server is accessible
*/
bool check_server_accessible();
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);
// 服务器主机和端口
std::string host_;
int port_ = 8080;
// 或者使用基础URL
std::string base_url_;
// SSE端点
std::string sse_endpoint_ = "/sse";
// 消息端点
std::string msg_endpoint_;
// HTTP客户端
std::unique_ptr<httplib::Client> http_client_;
// SSE专用HTTP客户端
std::unique_ptr<httplib::Client> sse_client_;
// SSE线程
std::unique_ptr<std::thread> sse_thread_;
// SSE运行状态
std::atomic<bool> sse_running_{false};
// 认证令牌
std::string auth_token_;
// 默认请求头
std::map<std::string, std::string> default_headers_;
// 超时设置(秒)
int timeout_seconds_ = 30;
// 客户端能力
json capabilities_;
// 服务器能力
json server_capabilities_;
// 互斥锁
mutable std::mutex mutex_;
// 条件变量,用于等待消息端点设置
std::condition_variable endpoint_cv_;
// 请求ID到Promise的映射用于异步等待响应
std::map<json, std::promise<json>> pending_requests_;
// 响应处理互斥锁
std::mutex response_mutex_;
// 响应条件变量
std::condition_variable response_cv_;
};
} // namespace mcp
#endif // MCP_CLIENT_H