Implement MCP Phase 1 infrastructure for agent tool integration with central hub, tool registry, and STDIO transport layers. Components: - McpHubService: Central registry for MCP server lifecycle - StdioTransport: STDIO process communication with JSON-RPC 2.0 - ToolRegistryService: Tool catalog management - McpController: REST API for MCP management Endpoints: - GET/POST /mcp/servers - List/register servers - POST /mcp/servers/:id/start|stop - Lifecycle control - DELETE /mcp/servers/:id - Unregister - GET /mcp/tools - List tools - POST /mcp/tools/:name/invoke - Invoke tool Features: - Full JSON-RPC 2.0 protocol support - Process lifecycle management - Buffered message parsing - Type-safe with no explicit any types - Proper cleanup on shutdown Tests: 85 passing with 90.9% coverage Fixes #132 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
60 lines
1.3 KiB
TypeScript
60 lines
1.3 KiB
TypeScript
import { Injectable } from "@nestjs/common";
|
|
import type { McpTool } from "./interfaces";
|
|
|
|
/**
|
|
* Service for managing MCP tool registry
|
|
* Maintains catalog of tools provided by MCP servers
|
|
*/
|
|
@Injectable()
|
|
export class ToolRegistryService {
|
|
private tools = new Map<string, McpTool>();
|
|
|
|
/**
|
|
* Register a tool from an MCP server
|
|
*/
|
|
registerTool(tool: McpTool): void {
|
|
this.tools.set(tool.name, tool);
|
|
}
|
|
|
|
/**
|
|
* Unregister a tool
|
|
*/
|
|
unregisterTool(toolName: string): void {
|
|
this.tools.delete(toolName);
|
|
}
|
|
|
|
/**
|
|
* Get tool by name
|
|
*/
|
|
getTool(name: string): McpTool | undefined {
|
|
return this.tools.get(name);
|
|
}
|
|
|
|
/**
|
|
* List all registered tools
|
|
*/
|
|
listTools(): McpTool[] {
|
|
return Array.from(this.tools.values());
|
|
}
|
|
|
|
/**
|
|
* List tools provided by a specific server
|
|
*/
|
|
listToolsByServer(serverId: string): McpTool[] {
|
|
return Array.from(this.tools.values()).filter((tool) => tool.serverId === serverId);
|
|
}
|
|
|
|
/**
|
|
* Clear all tools for a server
|
|
*/
|
|
clearServerTools(serverId: string): void {
|
|
const toolsToRemove = Array.from(this.tools.values())
|
|
.filter((tool) => tool.serverId === serverId)
|
|
.map((tool) => tool.name);
|
|
|
|
for (const toolName of toolsToRemove) {
|
|
this.tools.delete(toolName);
|
|
}
|
|
}
|
|
}
|