cpp-mcp/include/mcp_stdio_client.h

205 lines
5.2 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_stdio_client.h
* @brief MCP Stdio Client implementation
*
* This file implements the client-side functionality for the Model Context Protocol
* using standard input/output (stdio) as the transport mechanism.
* Follows the 2024-11-05 protocol specification.
*/
#ifndef MCP_STDIO_CLIENT_H
#define MCP_STDIO_CLIENT_H
#include "mcp_message.h"
#include "mcp_tool.h"
#include "mcp_logger.h"
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <mutex>
#include <functional>
#include <atomic>
#include <condition_variable>
#include <future>
#include <thread>
namespace mcp {
/**
* @class stdio_client
* @brief Client for connecting to MCP servers using stdio transport
*
* The stdio_client class provides functionality to connect to MCP servers
* by spawning a separate process and communicating via standard input/output.
*/
class stdio_client {
public:
/**
* @brief Constructor
* @param command The command to execute to start the server
* @param capabilities The capabilities of the client
*/
stdio_client(const std::string& command, const json& capabilities = json::object());
/**
* @brief Destructor
*/
~stdio_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 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 Check if the server process is running
* @return True if the server process is running
*/
bool is_running() const;
private:
// 启动服务器进程
bool start_server_process();
// 停止服务器进程
void stop_server_process();
// 读取线程函数
void read_thread_func();
// 发送JSON-RPC请求
json send_jsonrpc(const request& req);
// 服务器命令
std::string command_;
// 进程ID
int process_id_ = -1;
// 标准输入管道
int stdin_pipe_[2] = {-1, -1};
// 标准输出管道
int stdout_pipe_[2] = {-1, -1};
// 读取线程
std::unique_ptr<std::thread> read_thread_;
// 运行状态
std::atomic<bool> running_{false};
// 客户端能力
json capabilities_;
// 服务器能力
json server_capabilities_;
// 互斥锁
mutable std::mutex mutex_;
// 请求ID到Promise的映射用于异步等待响应
std::map<json, std::promise<json>> pending_requests_;
// 响应处理互斥锁
std::mutex response_mutex_;
// 初始化状态
std::atomic<bool> initialized_{false};
// 初始化条件变量
std::condition_variable init_cv_;
};
} // namespace mcp
#endif // MCP_STDIO_CLIENT_H