fix bugs of tool calls
parent
ebf5c2ea1f
commit
b62d328780
|
@ -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
|
||||
|
|
|
@ -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<tool> 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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -14,8 +14,11 @@
|
|||
#include <future>
|
||||
|
||||
// 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");
|
||||
}
|
|
@ -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<std::string>() : "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;
|
||||
|
|
|
@ -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<std::string>()}};
|
||||
return {
|
||||
{
|
||||
{"type", "text"},
|
||||
{"text", "Result: " + params["input"].get<std::string>()}
|
||||
}
|
||||
};
|
||||
} 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
|
||||
|
|
Loading…
Reference in New Issue