400 lines
12 KiB
C++
400 lines
12 KiB
C++
/**
|
|
* @file mcp_tools.h
|
|
* @brief Tool definitions and helper functions for MCP
|
|
*
|
|
* This file provides tool-related functionality and abstractions for the MCP protocol.
|
|
*/
|
|
|
|
#ifndef MCP_TOOLS_H
|
|
#define MCP_TOOLS_H
|
|
|
|
#include "mcp_protocol.h"
|
|
#include <functional>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <memory>
|
|
|
|
namespace mcp {
|
|
|
|
/**
|
|
* @class tool_registry
|
|
* @brief Registry for MCP tools
|
|
*
|
|
* The tool_registry class provides a centralized registry for tools that can
|
|
* be used by agents and clients.
|
|
*/
|
|
class tool_registry {
|
|
public:
|
|
/**
|
|
* @brief Get the singleton instance
|
|
* @return Reference to the singleton registry
|
|
*/
|
|
static tool_registry& instance() {
|
|
static tool_registry instance;
|
|
return instance;
|
|
}
|
|
|
|
/**
|
|
* @brief Register a tool
|
|
* @param tool The tool to register
|
|
* @param handler The function to call when the tool is invoked
|
|
*/
|
|
void register_tool(const tool& tool, tool_handler handler);
|
|
|
|
/**
|
|
* @brief Unregister a tool
|
|
* @param tool_name The name of the tool to unregister
|
|
* @return True if the tool was found and unregistered
|
|
*/
|
|
bool unregister_tool(const std::string& tool_name);
|
|
|
|
/**
|
|
* @brief Get a tool by name
|
|
* @param tool_name The name of the tool
|
|
* @return A pair containing the tool definition and handler, or nullptr if not found
|
|
*/
|
|
std::pair<tool, tool_handler>* get_tool(const std::string& tool_name);
|
|
|
|
/**
|
|
* @brief Get all registered tools
|
|
* @return A vector of all registered tools
|
|
*/
|
|
std::vector<tool> get_all_tools() const;
|
|
|
|
/**
|
|
* @brief Call a tool
|
|
* @param tool_name The name of the tool to call
|
|
* @param parameters The parameters to pass to the tool
|
|
* @return The result of the tool call
|
|
* @throws mcp_exception if the tool doesn't exist or execution fails
|
|
*/
|
|
json call_tool(const std::string& tool_name, const json& parameters);
|
|
|
|
private:
|
|
// Private constructor for singleton
|
|
tool_registry() {}
|
|
|
|
// Mapping of tool names to their definitions and handlers
|
|
std::map<std::string, std::pair<tool, tool_handler>> tools_;
|
|
|
|
// Mutex for thread safety
|
|
mutable std::mutex mutex_;
|
|
};
|
|
|
|
/**
|
|
* @class tool_builder
|
|
* @brief Utility class for building tools with a fluent API
|
|
*
|
|
* The tool_builder class provides a simple way to create tools with
|
|
* a fluent (chain-based) API.
|
|
*/
|
|
class tool_builder {
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
* @param name The name of the tool
|
|
*/
|
|
explicit tool_builder(const std::string& name);
|
|
|
|
/**
|
|
* @brief Set the tool description
|
|
* @param description The description
|
|
* @return Reference to this builder
|
|
*/
|
|
tool_builder& with_description(const std::string& description);
|
|
|
|
/**
|
|
* @brief Add a string parameter
|
|
* @param name The parameter name
|
|
* @param description The parameter description
|
|
* @param required Whether the parameter is required
|
|
* @return Reference to this builder
|
|
*/
|
|
tool_builder& with_string_param(const std::string& name,
|
|
const std::string& description,
|
|
bool required = true);
|
|
|
|
/**
|
|
* @brief Add a number parameter
|
|
* @param name The parameter name
|
|
* @param description The parameter description
|
|
* @param required Whether the parameter is required
|
|
* @return Reference to this builder
|
|
*/
|
|
tool_builder& with_number_param(const std::string& name,
|
|
const std::string& description,
|
|
bool required = true);
|
|
|
|
/**
|
|
* @brief Add a boolean parameter
|
|
* @param name The parameter name
|
|
* @param description The parameter description
|
|
* @param required Whether the parameter is required
|
|
* @return Reference to this builder
|
|
*/
|
|
tool_builder& with_boolean_param(const std::string& name,
|
|
const std::string& description,
|
|
bool required = true);
|
|
|
|
/**
|
|
* @brief Add an array parameter
|
|
* @param name The parameter name
|
|
* @param description The parameter description
|
|
* @param item_type The type of the array items ("string", "number", "object", etc.)
|
|
* @param required Whether the parameter is required
|
|
* @return Reference to this builder
|
|
*/
|
|
tool_builder& with_array_param(const std::string& name,
|
|
const std::string& description,
|
|
const std::string& item_type,
|
|
bool required = true);
|
|
|
|
/**
|
|
* @brief Add an object parameter
|
|
* @param name The parameter name
|
|
* @param description The parameter description
|
|
* @param properties JSON schema for the object properties
|
|
* @param required Whether the parameter is required
|
|
* @return Reference to this builder
|
|
*/
|
|
tool_builder& with_object_param(const std::string& name,
|
|
const std::string& description,
|
|
const json& properties,
|
|
bool required = true);
|
|
|
|
/**
|
|
* @brief Build the tool
|
|
* @return The constructed tool
|
|
*/
|
|
tool build() const;
|
|
|
|
private:
|
|
std::string name_;
|
|
std::string description_;
|
|
json parameters_;
|
|
std::vector<std::string> required_params_;
|
|
|
|
// Helper to add a parameter of any type
|
|
tool_builder& add_param(const std::string& name,
|
|
const std::string& description,
|
|
const std::string& type,
|
|
bool required);
|
|
};
|
|
|
|
/**
|
|
* @brief Create a simple tool with a function-based approach
|
|
* @param name Tool name
|
|
* @param description Tool description
|
|
* @param handler Function to handle tool invocations
|
|
* @param parameter_definitions A vector of parameter definitions as {name, description, type, required}
|
|
* @return The created tool
|
|
*/
|
|
inline tool create_tool(
|
|
const std::string& name,
|
|
const std::string& description,
|
|
const std::vector<std::tuple<std::string, std::string, std::string, bool>>& parameter_definitions) {
|
|
|
|
tool_builder builder(name);
|
|
builder.with_description(description);
|
|
|
|
for (const auto& [param_name, param_desc, param_type, required] : parameter_definitions) {
|
|
if (param_type == "string") {
|
|
builder.with_string_param(param_name, param_desc, required);
|
|
} else if (param_type == "number") {
|
|
builder.with_number_param(param_name, param_desc, required);
|
|
} else if (param_type == "boolean") {
|
|
builder.with_boolean_param(param_name, param_desc, required);
|
|
} else if (param_type == "array") {
|
|
builder.with_array_param(param_name, param_desc, "string", required);
|
|
} else if (param_type == "object") {
|
|
builder.with_object_param(param_name, param_desc, json::object(), required);
|
|
}
|
|
}
|
|
|
|
return builder.build();
|
|
}
|
|
|
|
/**
|
|
* @class workflow_step
|
|
* @brief Represents a step in a workflow
|
|
*
|
|
* The workflow_step class defines a single step in a workflow, which includes
|
|
* a tool call or other action to be performed.
|
|
*/
|
|
class workflow_step {
|
|
public:
|
|
|
|
/**
|
|
* @brief Default constructor
|
|
*/
|
|
workflow_step() : id_(""), tool_name_(""), parameters_(json::object()) {}
|
|
|
|
/**
|
|
* @brief Constructor for a tool call step
|
|
* @param tool_name The name of the tool to call
|
|
* @param parameters The parameters to pass to the tool
|
|
*/
|
|
workflow_step(const std::string& tool_name, const json& parameters = json::object());
|
|
|
|
/**
|
|
* @brief Execute the step
|
|
* @param context The context to execute in
|
|
* @return The result of the step execution
|
|
*/
|
|
json execute(json& context) const;
|
|
|
|
/**
|
|
* @brief Get the step ID
|
|
* @return The step ID
|
|
*/
|
|
const std::string& id() const { return id_; }
|
|
|
|
/**
|
|
* @brief Get the tool name
|
|
* @return The tool name
|
|
*/
|
|
const std::string& tool_name() const { return tool_name_; }
|
|
|
|
/**
|
|
* @brief Get the parameters
|
|
* @return The parameters
|
|
*/
|
|
const json& parameters() const { return parameters_; }
|
|
|
|
private:
|
|
std::string id_;
|
|
std::string tool_name_;
|
|
json parameters_;
|
|
static int next_id_;
|
|
};
|
|
|
|
/**
|
|
* @class workflow
|
|
* @brief Represents a workflow of connected steps
|
|
*
|
|
* The workflow class defines a sequence of steps that can be executed in order,
|
|
* with optional branching based on conditions.
|
|
*/
|
|
class workflow {
|
|
public:
|
|
/**
|
|
* @brief Default constructor
|
|
*/
|
|
workflow();
|
|
/**
|
|
* @brief Constructor
|
|
* @param name The name of the workflow
|
|
* @param description The description of the workflow
|
|
*/
|
|
workflow(const std::string& name, const std::string& description = "");
|
|
|
|
/**
|
|
* @brief Add a step to the workflow
|
|
* @param step The step to add
|
|
* @return Reference to this workflow
|
|
*/
|
|
workflow& add_step(const workflow_step& step);
|
|
|
|
/**
|
|
* @brief Add a tool call step to the workflow
|
|
* @param tool_name The name of the tool to call
|
|
* @param parameters The parameters to pass to the tool
|
|
* @return Reference to this workflow
|
|
*/
|
|
workflow& add_tool_call(const std::string& tool_name, const json& parameters = json::object());
|
|
|
|
/**
|
|
* @brief Execute the workflow
|
|
* @param initial_context Initial context data
|
|
* @return The final context after execution
|
|
*/
|
|
json execute(const json& initial_context = json::object()) const;
|
|
|
|
/**
|
|
* @brief Get the workflow name
|
|
* @return The workflow name
|
|
*/
|
|
const std::string& name() const { return name_; }
|
|
|
|
/**
|
|
* @brief Get the workflow description
|
|
* @return The workflow description
|
|
*/
|
|
const std::string& description() const { return description_; }
|
|
|
|
/**
|
|
* @brief Get the workflow steps
|
|
* @return The workflow steps
|
|
*/
|
|
const std::vector<workflow_step>& steps() const { return steps_; }
|
|
|
|
private:
|
|
std::string name_;
|
|
std::string description_;
|
|
std::vector<workflow_step> steps_;
|
|
};
|
|
|
|
/**
|
|
* @class agent
|
|
* @brief Base class for MCP agents
|
|
*
|
|
* The agent class defines the interface and common functionality for
|
|
* agents that can use MCP tools and resources.
|
|
*/
|
|
class agent {
|
|
public:
|
|
/**
|
|
* @brief Constructor
|
|
* @param name The name of the agent
|
|
*/
|
|
explicit agent(const std::string& name);
|
|
|
|
/**
|
|
* @brief Virtual destructor
|
|
*/
|
|
virtual ~agent() = default;
|
|
|
|
/**
|
|
* @brief Initialize the agent
|
|
* @param config Configuration parameters
|
|
*/
|
|
virtual void initialize(const json& config) = 0;
|
|
|
|
/**
|
|
* @brief Process a request
|
|
* @param input The input data
|
|
* @return The processed output
|
|
*/
|
|
virtual json process(const json& input) = 0;
|
|
|
|
/**
|
|
* @brief Get the agent name
|
|
* @return The agent name
|
|
*/
|
|
const std::string& name() const { return name_; }
|
|
|
|
/**
|
|
* @brief Call a tool
|
|
* @param tool_name The name of the tool to call
|
|
* @param parameters The parameters to pass to the tool
|
|
* @return The result of the tool call
|
|
*/
|
|
json call_tool(const std::string& tool_name, const json& parameters = json::object());
|
|
|
|
/**
|
|
* @brief Execute a workflow
|
|
* @param workflow The workflow to execute
|
|
* @param initial_context Initial context data
|
|
* @return The final context after execution
|
|
*/
|
|
json execute_workflow(const workflow& workflow, const json& initial_context = json::object());
|
|
|
|
protected:
|
|
std::string name_;
|
|
json context_;
|
|
};
|
|
|
|
} // namespace mcp
|
|
|
|
#endif // MCP_TOOLS_H
|