diff --git a/include/mcp_client.h b/include/mcp_client.h index 9631b50..0266c91 100644 --- a/include/mcp_client.h +++ b/include/mcp_client.h @@ -105,11 +105,11 @@ public: /** * @brief Call a tool * @param tool_name The name of the tool to call - * @param parameters The parameters to pass to the tool + * @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& parameters = json::object()); + json call_tool(const std::string& tool_name, const json& arguments = json::object()); /** * @brief Get available tools diff --git a/src/mcp_client.cpp b/src/mcp_client.cpp index c8fb81b..9049cdc 100644 --- a/src/mcp_client.cpp +++ b/src/mcp_client.cpp @@ -109,10 +109,10 @@ json client::get_server_capabilities() { return server_capabilities_; } -json client::call_tool(const std::string& tool_name, const json& parameters) { +json client::call_tool(const std::string& tool_name, const json& arguments) { return send_request("tools/call", { {"name", tool_name}, - {"parameters", parameters} + {"arguments", arguments} }).result; } @@ -126,8 +126,8 @@ std::vector client::get_tools() { t.name = tool_json["name"]; t.description = tool_json["description"]; - if (tool_json.contains("parameters")) { - t.parameters_schema = tool_json["parameters"]; + if (tool_json.contains("inputSchema")) { + t.parameters_schema = tool_json["inputSchema"]; } tools.push_back(t); diff --git a/src/mcp_server.cpp b/src/mcp_server.cpp index 03760b5..0e781c2 100644 --- a/src/mcp_server.cpp +++ b/src/mcp_server.cpp @@ -159,8 +159,19 @@ void server::register_tool(const tool& tool, tool_handler handler) { throw mcp_exception(error_code::invalid_params, "Tool not found: " + tool_name); } - json tool_params = params.contains("parameters") ? params["parameters"] : json::object(); - return it->second.second(tool_params); + json tool_args = params.contains("arguments") ? params["arguments"] : json::array(); + + json tool_result = { + {"isError", false} + }; + + try { + tool_result["content"] = it->second.second(tool_args); + } catch (const std::exception& e) { + tool_result["isError"] = true; + } + + return tool_result; }; } } @@ -332,7 +343,7 @@ json server::handle_initialize(const request& req) { error_code::invalid_params, "Unsupported protocol version", { - {"supported", MCP_VERSION}, + {"supported", {MCP_VERSION}}, {"requested", params["protocolVersion"]} } ).to_json(); diff --git a/test/test_mcp_client.cpp b/test/test_mcp_client.cpp index f3b793d..cbc6256 100644 --- a/test/test_mcp_client.cpp +++ b/test/test_mcp_client.cpp @@ -14,8 +14,11 @@ #include // Mock tool handler function -mcp::json echo_tool_handler(const mcp::json& params) { - return params; +mcp::json echo_tool_handler(const mcp::json& args) { + return {{ + {"type", "text"}, + {"text", args["message"]} + }}; } // Mock resource handler @@ -96,12 +99,8 @@ protected: // Test client initialization TEST_F(ClientTest, InitializeTest) { // Initialize client - bool initialized = client->initialize("TestClient", mcp::MCP_VERSION); + bool initialized = client->initialize("TestClient", "1.0.0"); EXPECT_TRUE(initialized); - - // Verify server information - Note: these methods may not exist, modify according to actual implementation - // EXPECT_EQ(client->get_server_name(), "TestServer"); - // EXPECT_EQ(client->get_server_version(), "2024-11-05"); } // Test getting server capabilities @@ -139,10 +138,15 @@ TEST_F(ClientTest, CallToolTest) { client->initialize("TestClient", mcp::MCP_VERSION); // Call echo tool - mcp::json params = {{"message", "Test message"}}; - mcp::json result = client->call_tool("echo", params); + mcp::json args = {{"message", "Test message"}}; + mcp::json result = client->call_tool("echo", args); + + EXPECT_TRUE(result.contains("content")); + EXPECT_TRUE(result["content"].is_array()); + EXPECT_EQ(result["content"].size(), 1); - EXPECT_EQ(result["message"], "Test message"); + EXPECT_EQ(result["content"][0]["type"], "text"); + EXPECT_EQ(result["content"][0]["text"], "Test message"); } // Test getting resource list @@ -175,19 +179,6 @@ TEST_F(ClientTest, AccessResourceTest) { EXPECT_EQ(result["params"]["query"], "Test query"); } -// Test ping method -TEST_F(ClientTest, PingTest) { - // Initialize client - client->initialize("TestClient", mcp::MCP_VERSION); - - // Send ping - Note: this method may not exist, modify according to actual implementation - // bool pong = client->ping(); - // EXPECT_TRUE(pong); - - // Alternative test: ensure client can still call methods - EXPECT_NO_THROW(client->get_server_capabilities()); -} - // Test error handling TEST_F(ClientTest, ErrorHandlingTest) { // Initialize client @@ -242,5 +233,10 @@ TEST_F(ClientTest, CancellationTest) { mcp::json result = future.get(); // Since we didn't actually cancel the request, it should return normal result - EXPECT_TRUE(result.contains("message")); + EXPECT_TRUE(result.contains("content")); + EXPECT_TRUE(result["content"].is_array()); + EXPECT_EQ(result["content"].size(), 1); + + EXPECT_EQ(result["content"][0]["type"], "text"); + EXPECT_EQ(result["content"][0]["text"], "This call should be cancelled"); } \ No newline at end of file diff --git a/test/test_mcp_direct_requests.cpp b/test/test_mcp_direct_requests.cpp index e78a13b..8e3a3df 100644 --- a/test/test_mcp_direct_requests.cpp +++ b/test/test_mcp_direct_requests.cpp @@ -43,9 +43,14 @@ protected: .with_string_param("input", "Input parameter") .build(); - server->register_tool(test_tool, [](const mcp::json& params) { + server->register_tool(test_tool, [](const mcp::json& params) -> mcp::json { std::string input = params.contains("input") ? params["input"].get() : "Default input"; - return mcp::json{{"output", "Result: " + input}}; + return { + { + {"type", "text"}, + {"text", "Result: " + input} + } + }; }); // Register resources @@ -531,7 +536,7 @@ TEST_F(DirectRequestTest, ClientAndDirectRequests) { // Use client API to call tool try { mcp::json tool_result = client.call_tool("test_tool", {{"input", "Client API call"}}); - EXPECT_EQ(tool_result["output"], "Result: Client API call"); + EXPECT_EQ(tool_result["content"][0]["text"], "Result: Client API call"); } catch (const std::exception& e) { // Client API may throw exception if server doesn't implement callTool method std::cout << "Client API tool call failed: " << e.what() << std::endl; diff --git a/test/test_mcp_server.cpp b/test/test_mcp_server.cpp index 0df02b1..63888f8 100644 --- a/test/test_mcp_server.cpp +++ b/test/test_mcp_server.cpp @@ -17,9 +17,19 @@ // Mock tool handler function mcp::json test_tool_handler(const mcp::json& params) { if (params.contains("input")) { - return {{"output", "Result: " + params["input"].get()}}; + return { + { + {"type", "text"}, + {"text", "Result: " + params["input"].get()} + } + }; } else { - return {{"output", "Default result"}}; + return { + { + {"type", "text"}, + {"text", "Default result"} + } + }; } } @@ -163,7 +173,16 @@ TEST_F(ServerTest, MethodRegistrationTest) { .with_string_param("param1", "Parameter 1", false) .build(), [](const mcp::json& params) -> mcp::json { - return {{"result", "Method call successful"}, {"params", params}}; + return { + { + {"type", "text"}, + {"text", "Method call successful"} + }, + { + {"type", "text"}, + {"text", "params: " + params.dump()} + } + }; } ); @@ -177,8 +196,8 @@ TEST_F(ServerTest, MethodRegistrationTest) { // Call method (via tool) mcp::json result = client.call_tool("test_method", {{"param1", "value1"}}); - EXPECT_EQ(result["result"], "Method call successful"); - EXPECT_EQ(result["params"]["param1"], "value1"); + EXPECT_EQ(result["content"][0]["text"], "Method call successful"); + EXPECT_EQ(result["content"][1]["text"], "params: {\"param1\":\"value1\"}"); // Call non-existent method EXPECT_THROW(client.call_tool("non_existent_method"), mcp::mcp_exception); @@ -215,7 +234,7 @@ TEST_F(ServerTest, ServerClientInteractionTest) { // Call tool mcp::json tool_result = client.call_tool("test_tool", {{"input", "Test input"}}); - EXPECT_EQ(tool_result["output"], "Result: Test input"); + EXPECT_EQ(tool_result["content"][0]["text"], "Result: Test input"); // Access resource mcp::json resource_result = client.access_resource("/mock", {{"query", "Test query"}}); @@ -273,13 +292,9 @@ TEST_F(ServerTest, ErrorHandlingTest) { client.initialize("TestClient", mcp::MCP_VERSION); // Call tool that throws exception - try { - client.call_tool("error_tool"); - FAIL() << "Should throw an exception"; - } catch (const mcp::mcp_exception& e) { - // Verify error code - EXPECT_EQ(e.code(), mcp::error_code::internal_error); - } + mcp::json result = client.call_tool("error_tool"); + EXPECT_EQ(result.contains("isError"), true); + EXPECT_EQ(result["isError"], true); } // Test server stop and restart