Skip to content

Commit 52b98d8

Browse files
committed
Add tool-call request/response types
1 parent 1209b95 commit 52b98d8

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed

toolcall/mcp_messages.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,82 @@ mcp::tools_list_response mcp::tools_list_response::fromJson(const nlohmann::json
280280
return tools_list_response(j["id"], std::move(tools), next_cursor);
281281
}
282282

283+
mcp::tools_call_request::tools_call_request(nlohmann::json id, std::string name, tool_arg_list args)
284+
: request(id, "tools/call"), name_(std::move(name)), args_(std::move(args))
285+
{
286+
refreshParams();
287+
}
288+
289+
void mcp::tools_call_request::name(std::string name) {
290+
name_ = std::move(name);
291+
refreshParams();
292+
}
293+
294+
void mcp::tools_call_request::args(mcp::tool_arg_list args) {
295+
args_ = std::move(args);
296+
refreshParams();
297+
}
298+
299+
void mcp::tools_call_request::refreshParams() {
300+
json params = json::object();
301+
params["name"] = name_;
302+
if (! args_.empty()) {
303+
json args = json::object();
304+
for (const auto & arg : args_) {
305+
args[arg.name] = arg.value;
306+
}
307+
params["arguments"] = args;
308+
}
309+
this->params(params);
310+
}
311+
312+
mcp::tools_call_response::tools_call_response(nlohmann::json id, tool_result_list result, bool error)
313+
: response(id), tool_result_(std::move(result)), error_(error)
314+
{
315+
refreshResult();
316+
}
317+
318+
void mcp::tools_call_response::tool_result(mcp::tool_result_list result) {
319+
tool_result_ = std::move(result);
320+
refreshResult();
321+
}
322+
323+
void mcp::tools_call_response::tool_error(bool error) {
324+
error_ = error;
325+
refreshResult();
326+
}
327+
328+
void mcp::tools_call_response::refreshResult() {
329+
json result = json::object();
330+
result["isError"] = error_;
331+
json content = json::array();
332+
for (const auto & res : tool_result_) {
333+
json r;
334+
r["type"] = res.type;
335+
if (res.type == "text") {
336+
r["text"] = res.value;
337+
338+
} else if (res.type == "image" || res.type == "audio") {
339+
r["data"] = res.value;
340+
r["mimeType"] = res.mime_type.value(); // throws
341+
342+
} else if (res.type == "resource") {
343+
json rr;
344+
rr["uri"] = res.uri.value(); // throws
345+
rr["mimeType"] = res.mime_type.value(); //throws
346+
rr["text"] = res.value;
347+
348+
r["resource"] = rr;
349+
350+
} else {
351+
// throw
352+
}
353+
content.push_back(r);
354+
}
355+
result["content"] = content;
356+
this->result(std::move(result));
357+
}
358+
283359
static bool has_initialized_response(const nlohmann::json & data) {
284360
return data["result"].contains("capabilities");
285361
}

toolcall/mcp_messages.h

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,14 +222,64 @@ namespace mcp
222222
: notification("notifications/tools/list_changed") {}
223223
};
224224

225+
struct tool_arg {
226+
std::string name;
227+
std::string value;
228+
};
229+
230+
using tool_arg_list = std::vector<tool_arg>;
231+
232+
class tools_call_request : public request {
233+
public:
234+
tools_call_request(nlohmann::json id, std::string name, tool_arg_list args = tool_arg_list());
235+
236+
void name(std::string name);
237+
const std::string & name() const { return name_; }
238+
239+
void args(tool_arg_list args);
240+
const tool_arg_list args() const { return args_; }
241+
242+
private:
243+
void refreshParams();
244+
std::string name_;
245+
tool_arg_list args_;
246+
};
247+
248+
struct tool_result {
249+
std::string type; // text, image, audio, or resource
250+
std::string value;
251+
std::optional<std::string> mime_type; // Only for: image, audio, and resource
252+
std::optional<std::string> uri; // Only for: resource
253+
};
254+
255+
using tool_result_list = std::vector<tool_result>;
256+
257+
class tools_call_response : public response {
258+
public:
259+
tools_call_response(nlohmann::json id, tool_result_list result = tool_result_list(), bool error = false);
260+
261+
void tool_result(tool_result_list result);
262+
const tool_result_list & tool_result() const { return tool_result_; }
263+
264+
void tool_error(bool error);
265+
bool tool_error() const { return error_; }
266+
267+
private:
268+
void refreshResult();
269+
tool_result_list tool_result_;
270+
bool error_;
271+
};
272+
225273
using message_variant =
226274
std::variant<std::monostate,
227275
initialize_request,
228276
initialize_response,
229277
initialized_notification,
230278
tools_list_request,
231279
tools_list_response,
232-
tools_list_changed_notification>;
280+
tools_list_changed_notification,
281+
tools_call_request,
282+
tools_call_response>;
233283

234284
bool create_message(const std::string & data, message_variant & message);
235285
}

0 commit comments

Comments
 (0)