ToolRegistry¶
Central registry for managing tools available to agents. Handles registration, lookup, execution, parameter validation, metadata inspection, and scoped sub-registries.
Import¶
Constructor¶
The ToolRegistry is instantiated with no arguments. Tools are added after construction via register() or registerMultiple().
Methods¶
Registration¶
| Method | Signature | Description |
|---|---|---|
register | (name: string, tool: ITool, metadata?: ToolMetadata): void | Register a tool by name. If metadata is provided, it is used directly; otherwise metadata is read from the @Tool() decorator. Throws if the name is already registered or the tool lacks an execute method. |
registerMultiple | (tools: Array<{ name: string; tool: ITool }>): void | Register multiple tools atomically. If any registration fails, all previously registered tools in the batch are rolled back. |
unregister | (name: string): void | Remove a tool and its metadata from the registry. |
clear | (): void | Remove all tools and metadata. |
Lookup¶
| Method | Signature | Description |
|---|---|---|
get | (name: string): ITool \| undefined | Retrieve a tool instance by name. |
has | (name: string): boolean | Check whether a tool is registered. |
list | (): string[] | Return all registered tool names. |
Execution¶
| Method | Signature | Description |
|---|---|---|
execute | (name: string, params: Record<string, any>): Promise<any> | Execute a tool by name with the given parameters. Calls tool.validate(params) first if the tool defines a validator. Throws if the tool is not found. |
validateParameters | (name: string, params: Record<string, any>): void | Validate parameters against the tool's metadata schema without executing. Falls back to tool.validate() if no metadata parameters are defined. |
Metadata¶
| Method | Signature | Description |
|---|---|---|
getMetadata | (name: string): ToolMetadata \| undefined | Get metadata for a specific tool. Checks the explicit metadata map first, then falls back to reading @Tool() decorator metadata from the instance. |
getAllMetadata | (): Map<string, ToolMetadata \| undefined> | Get metadata for all registered tools. |
Search & Filtering¶
| Method | Signature | Description |
|---|---|---|
search | (criteria: { tags?: string[]; category?: string }): string[] | Find tools by category or tags. Returns tool names that match the category exactly or share at least one tag. |
hasCapability | (requiredTools: string[]): boolean | Check whether all of the given tool names are registered. Used by BaseAgent.hasCapability(). |
createScoped | (toolNames: string[]): ToolRegistry | Create a new ToolRegistry containing only the specified tools. The new registry shares tool instances (not copies) with the original. |
Statistics¶
| Method | Signature | Description |
|---|---|---|
getStats | (): RegistryStats | Returns summary statistics about the registry. |
RegistryStats shape:
{
totalTools: number;
categories: string[]; // distinct category values
tags: string[]; // distinct tag values
}
Usage¶
Basic Registration and Execution¶
import { ToolRegistry, Tool, ITool } from "@modernpath/agent-framework";
@Tool({
name: "weather",
description: "Get current weather for a city",
parameters: {
city: { type: "string", description: "City name", required: true },
},
category: "external",
tags: ["weather", "api"],
})
class WeatherTool implements ITool {
async execute(params: Record<string, any>): Promise<any> {
const response = await fetch(`https://api.weather.example/${params.city}`);
return response.json();
}
}
const registry = new ToolRegistry();
registry.register("weather", new WeatherTool());
// Execute directly
const forecast = await registry.execute("weather", { city: "Helsinki" });
// Validate without executing
registry.validateParameters("weather", { city: "Helsinki" }); // OK
registry.validateParameters("weather", {}); // throws: Missing required parameter: city
Batch Registration¶
registry.registerMultiple([
{ name: "weather", tool: new WeatherTool() },
{ name: "geocode", tool: new GeocodeTool() },
{ name: "alerts", tool: new AlertsTool() },
]);
// If any registration fails, all three are rolled back
Providing Explicit Metadata¶
When registering a tool that does not use the @Tool decorator (e.g., a plain object), pass metadata as the third argument:
const simpleTool: ITool = {
async execute(params) {
return { echo: params.message };
},
};
registry.register("echo", simpleTool, {
name: "echo",
description: "Echoes the input message",
parameters: {
message: { type: "string", description: "Message to echo" },
},
});
Searching Tools¶
// Find by category
const externalTools = registry.search({ category: "external" });
// => ["weather"]
// Find by tags
const apiTools = registry.search({ tags: ["api"] });
// => ["weather"]
// Check if all required tools are present
const ready = registry.hasCapability(["weather", "geocode"]);
// => true
Scoped Sub-registries¶
Use createScoped() to give an agent access to a subset of tools:
const allTools = new ToolRegistry();
allTools.register("weather", new WeatherTool());
allTools.register("geocode", new GeocodeTool());
allTools.register("admin-delete", new AdminDeleteTool());
// Create a scoped registry without the admin tool
const userRegistry = allTools.createScoped(["weather", "geocode"]);
const agent = new MyAgent(userRegistry);
// agent.getAvailableTools() => ["weather", "geocode"]
Scoped registries share tool instances
createScoped() does not clone tool objects. The scoped registry references the same instances as the parent. This is efficient but means tool state is shared.
Inspecting the Registry¶
// List all tools
console.log(registry.list());
// => ["weather", "geocode", "alerts"]
// Get metadata for one tool
const meta = registry.getMetadata("weather");
console.log(meta?.description); // "Get current weather for a city"
// Get all metadata
const allMeta = registry.getAllMetadata();
for (const [name, meta] of allMeta) {
console.log(`${name}: ${meta?.description}`);
}
// Statistics
console.log(registry.getStats());
// { totalTools: 3, categories: ["external"], tags: ["weather", "api"] }
Related Pages¶
- @Tool Decorator -- defining tools with decorators
- Dynamic Tools -- registering tools at runtime
- BaseAgent -- how agents use the registry via
useTool() - MCP Integration -- registering tools from remote MCP servers