@vfarcic/dot-ai
Version:
AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance
174 lines (173 loc) • 5.31 kB
JavaScript
;
/**
* REST API Tool Registry
*
* Central registry for all MCP tools exposed via REST API.
* Manages tool metadata, schema conversion, and tool discovery capabilities.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.RestToolRegistry = void 0;
const zod_1 = require("zod");
/**
* Registry for managing all tools available via REST API
*/
class RestToolRegistry {
tools = new Map();
logger;
schemaCache = new Map();
constructor(logger) {
this.logger = logger;
}
/**
* Register a tool in the registry
*/
registerTool(metadata) {
this.tools.set(metadata.name, metadata);
// Clear schema cache for this tool
this.schemaCache.delete(metadata.name);
this.logger.debug('Tool registered in REST registry', {
name: metadata.name,
description: metadata.description,
category: metadata.category,
tags: metadata.tags,
});
}
/**
* Get tool metadata by name
*/
getTool(name) {
return this.tools.get(name);
}
/**
* Get all registered tool names
*/
getToolNames() {
return Array.from(this.tools.keys()).sort();
}
/**
* Get all tools with their discovery information
*/
getAllTools() {
return this.getToolNames().map(name => {
const tool = this.tools.get(name);
return {
name: tool.name,
description: tool.description,
schema: this.convertZodSchemaToJsonSchema(tool.name, tool.inputSchema),
category: tool.category,
tags: tool.tags,
};
});
}
/**
* Check if a tool is registered
*/
hasTool(name) {
return this.tools.has(name);
}
/**
* Get the number of registered tools
*/
getToolCount() {
return this.tools.size;
}
/**
* Clear all registered tools
*/
clear() {
this.tools.clear();
this.schemaCache.clear();
this.logger.debug('REST tool registry cleared');
}
/**
* Convert Zod schema to JSON Schema using Zod v4 native toJSONSchema
*/
convertZodSchemaToJsonSchema(toolName, zodSchemas) {
const cached = this.schemaCache.get(toolName);
if (cached) {
return cached;
}
try {
const zodObjectSchema = zod_1.z.object(zodSchemas);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- JsonSchema index signature
const result = zod_1.z.toJSONSchema(zodObjectSchema);
// Remove $schema and additionalProperties (not valid in OpenAPI component schemas)
delete result.$schema;
delete result.additionalProperties;
this.schemaCache.set(toolName, result);
this.logger.debug('Converted Zod schema to JSON Schema', {
toolName,
schemaKeys: Object.keys(zodSchemas),
resultType: result.type,
});
return result;
}
catch (error) {
this.logger.error('Failed to convert Zod schema to JSON Schema', error instanceof Error ? error : new Error(String(error)), {
toolName,
errorMessage: error instanceof Error ? error.message : String(error),
});
const fallbackSchema = {
type: 'object',
description: `Schema conversion failed for ${toolName} - using fallback`,
properties: {},
additionalProperties: true,
};
return fallbackSchema;
}
}
/**
* Get tool discovery information with filtering
*/
getToolsFiltered(options = {}) {
let tools = this.getAllTools();
if (options.category) {
tools = tools.filter(tool => tool.category === options.category);
}
if (options.tag) {
tools = tools.filter(tool => tool.tags?.includes(options.tag));
}
if (options.search) {
const searchLower = options.search.toLowerCase();
tools = tools.filter(tool => tool.name.toLowerCase().includes(searchLower) ||
tool.description.toLowerCase().includes(searchLower));
}
return tools;
}
/**
* Get all unique categories
*/
getCategories() {
const categories = new Set();
for (const tool of this.tools.values()) {
if (tool.category) {
categories.add(tool.category);
}
}
return Array.from(categories).sort();
}
/**
* Get all unique tags
*/
getTags() {
const tags = new Set();
for (const tool of this.tools.values()) {
if (tool.tags) {
tool.tags.forEach(tag => tags.add(tag));
}
}
return Array.from(tags).sort();
}
/**
* Get registry statistics
*/
getStats() {
return {
totalTools: this.tools.size,
categories: this.getCategories(),
tags: this.getTags(),
cacheSize: this.schemaCache.size,
};
}
}
exports.RestToolRegistry = RestToolRegistry;