Dynamically Manage MCP Tool Groups
MCP server exposing dynamic tool groups for AI models, including arithmetic operations like add and multiply.
Maintainer of this project? Claim this page to edit the listing.
1.0.0Add to Favorites
Why it matters
This asset enables dynamic management of tool groups within MCP servers using annotated Java interfaces. It allows for the runtime addition and removal of tool specifications, supporting both synchronous and asynchronous operations.
Outcomes
What it gets done
Dynamically generate tool specifications from Java annotations.
Add and remove tool groups from MCP servers at runtime.
Support asynchronous operations for tools like asyncAdd and asyncMultiply.
Organize tools into groups for better management.
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/vb-mcp-dynamic-tool-groups | bash Capabilities
Tools your agent gets
Computes the sum of two double-precision input arguments a and b
Returns the product of two given double-precision arguments named a and b
Asynchronously returns the sum of two double-precision input arguments a and b
Asynchronously returns the product of two given double-precision arguments named a and b
Overview
MCP Dynamic Tool Groups MCP Server
This MCP server exposes dynamic tool groups, allowing AI models to discover and execute tools. It supports both synchronous and asynchronous operations, providing metadata for tool inputs and outputs. The example demonstrates arithmetic operations like addition and multiplication, defined using MCP annotations. Use this MCP server when you need to integrate AI models with external functionalities and allow them to perform specific tasks. It is suitable for scenarios requiring AI to leverage predefined operations, such as calculations, data manipulation, or service interactions.
What it does
As an AI developer, I want to enable my AI model to perform complex calculations and operations, so that it can solve a wider range of problems.
This MCP server allows AI models to discover and utilize tools for various tasks. For example, an AI can call arithmetic operations defined in an ExampleToolGroup interface:
@McpToolGroup(description="Arithmetic operations exposed as mcp tools")
public interface ExampleToolGroup {
@McpTool(description = "computes the sum of the two double precision input arguments a and b")
double add(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
@McpTool(description = "return the product of the two given double precision arguments named a and b")
double multiply(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
@McpTool(description = "return asynchronously the sum of the two double precision input arguments a and b")
Mono<Double> asyncAdd(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
@McpTool(description = "return asynchronously the product of the two given double precision arguments named a and b")
Mono<Double> asyncMultiply(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
}
Source README
MCP Dynamic Tool Groups
The Model Context Protocol (MCP) includes support for tools, allowing AI models to a) Get metadata (descriptions) of tool input and output; b) Provide input, call/take action and c) get output via the use of one or more of the available tools.
In this example application the com.composent.ai.mcp.examples.toolgroup.api project declares a ExampleToolGroup interface class, with McpTool and McpToolGroup metadata:
@McpToolGroup(description="Arithmetic operations exposed as mcp tools")
public interface ExampleToolGroup {
@McpTool(description = "computes the sum of the two double precision input arguments a and b")
double add(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
@McpTool(description = "return the product of the two given double precision arguments named a and b")
double multiply(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
@McpTool(description = "return asynchronously the sum of the two double precision input arguments a and b")
Mono<Double> asyncAdd(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
@McpTool(description = "return asynchronously the product of the two given double precision arguments named a and b")
Mono<Double> asyncMultiply(@McpToolParam(description = "x is the first argument") double x,
@McpToolParam(description = "y is the second argument") double y);
}
Each method is annotated with the @McpTool and @McpToolParam annotations from the mcp_annotations_java project. There are both synchronous mcp server methods (add, multiply) and asynchronous mcp server methods (asyncAdd and asyncMultiply).
Notice also the use of @McpToolGroup annotation for the ExampleToolGroup class along with the parent package. This shows the static creation of a hierarchical relationship between the top-level toolgroup (package), and a child toolgroup (class) with two tools (add and multiply) as leaves of this simple toolgroup tree.
Here is an OSGi component implementing the ExampleToolGroup interface.
public class ToolGroupComponent implements ExampleToolGroup {
private static Logger logger = LoggerFactory.getLogger(ToolGroupComponent.class);
// This reference will wait for the SyncToolGroupServerComponent
// to be activated
@Reference
private SyncToolGroupServerComponent syncServer;
// This reference will wait for the AsyncToolGroupServerComponent
// to be activated
@Reference
private AsyncToolgroupServerComponent asyncServer;
@Activate
void activate() {
// Add to syncServer
syncServer.addToolGroups(this, ExampleToolGroup.class);
// Add to asyncServer
asyncServer.addToolGroups(this, ExampleToolGroup.class);
}
@Override
public double add(double x, double y) {
logger.debug("Adding x={} y={}", x, y);
return x + y;
}
@Override
public double multiply(double x, double y) {
logger.debug("Multiplying x={} y={}", x, y);
return x * y;
}
@Override
public Mono<Double> asyncAdd(double x, double y) {
logger.debug("Async Adding x={} y={}", x, y);
return Mono.just(add(x, y));
}
@Override
public Mono<Double> asyncMultiply(double x, double y) {
logger.debug("Async Multiplying x={} y={}", x, y);
return Mono.just(multiply(x, y));
}
}
The ExampleToolGroup tools are processed and added to the appropriate (sync or async) server at runtime with this line:
syncServer.addToolGroups(this, ExampleToolGroup.class);
FAQ
Common questions
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.