/** * @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 #include #include #include #include #include #include #include #include #include // 添加Windows平台特定的头文件 #if defined(_WIN32) || defined(_WIN64) #include #endif 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 env_vars Optional environment variables to set for the server process * @param capabilities The capabilities of the client */ stdio_client(const std::string& command, const json& env_vars = json::object(), const json& capabilities = json::object()); /** * @brief Destructor */ ~stdio_client(); /** * @brief Set environment variables for the server process * @param env_vars JSON object containing environment variables (key: variable name, value: variable value) * @note This must be called before initialize() */ void set_environment_variables(const json& env_vars); /** * @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 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; #if defined(_WIN32) || defined(_WIN64) // Windows平台特定的进程句柄 HANDLE process_handle_ = NULL; // 标准输入输出管道 (Windows) HANDLE stdin_pipe_[2] = {NULL, NULL}; HANDLE stdout_pipe_[2] = {NULL, NULL}; #else // 标准输入管道 (POSIX) int stdin_pipe_[2] = {-1, -1}; // 标准输出管道 (POSIX) int stdout_pipe_[2] = {-1, -1}; #endif // 读取线程 std::unique_ptr read_thread_; // 运行状态 std::atomic running_{false}; // 客户端能力 json capabilities_; // 服务器能力 json server_capabilities_; // 互斥锁 mutable std::mutex mutex_; // 请求ID到Promise的映射,用于异步等待响应 std::map> pending_requests_; // 响应处理互斥锁 std::mutex response_mutex_; // 初始化状态 std::atomic initialized_{false}; // 初始化条件变量 std::condition_variable init_cv_; // 环境变量 json env_vars_; }; } // namespace mcp #endif // MCP_STDIO_CLIENT_H