permamind
Version:
An MCP server that provides an immortal memory layer for AI agents and clients
105 lines (104 loc) • 3.1 kB
JavaScript
export class ToolRegistry {
categories = new Map();
tools = new Map();
clear() {
this.tools.clear();
this.categories.clear();
}
getAllTools() {
return Array.from(this.tools.values());
}
getCategories() {
return Array.from(this.categories.values());
}
getCategoryCount() {
return this.categories.size;
}
getCategoryNames() {
return Array.from(this.categories.keys());
}
getStats() {
const toolsByCategory = {};
for (const [categoryName, category] of this.categories) {
toolsByCategory[categoryName] = category.tools.length;
}
return {
toolsByCategory,
totalCategories: this.categories.size,
totalTools: this.tools.size,
};
}
getTool(name) {
return this.tools.get(name);
}
getToolCount() {
return this.tools.size;
}
getToolDefinitions(context) {
return this.getAllTools().map((tool) => tool.toToolDefinition(context));
}
getToolsByCategory(categoryName) {
const category = this.categories.get(categoryName);
return category ? category.tools : [];
}
hasCategory(categoryName) {
return this.categories.has(categoryName);
}
hasTool(toolName) {
return this.tools.has(toolName);
}
register(tool, categoryName) {
const metadata = tool.getMetadata();
if (this.tools.has(metadata.name)) {
throw new Error(`Tool '${metadata.name}' is already registered`);
}
this.tools.set(metadata.name, tool);
if (categoryName) {
this.addToCategory(categoryName, tool);
}
}
registerCategory(name, description, tools) {
if (this.categories.has(name)) {
throw new Error(`Category '${name}' is already registered`);
}
const category = {
description,
name,
tools: [],
};
this.categories.set(name, category);
// Register all tools in the category
for (const tool of tools) {
this.register(tool, name);
}
}
unregister(toolName) {
const tool = this.tools.get(toolName);
if (!tool) {
return false;
}
this.tools.delete(toolName);
// Remove from categories
for (const category of this.categories.values()) {
const index = category.tools.indexOf(tool);
if (index > -1) {
category.tools.splice(index, 1);
}
}
return true;
}
addToCategory(categoryName, tool) {
let category = this.categories.get(categoryName);
if (!category) {
category = {
description: `${categoryName} tools`,
name: categoryName,
tools: [],
};
this.categories.set(categoryName, category);
}
category.tools.push(tool);
}
}
// Global registry instance
export const toolRegistry = new ToolRegistry();