/**
* MCP Handlers
*
* Application layer handlers for MCP protocol requests.
* Coordinates tool registry and request processing.
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
SetLevelRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { ToolRegistry } from './tools/tool-registry.js';
import { ILogger } from '../infrastructure/logging/logger.js';
/**
* Setup MCP request handlers on server
*
* @param server - MCP Server instance
* @param toolRegistry - Tool registry with registered tools
* @param logger - Logger instance
*/
export function setupMcpHandlers(
server: Server,
toolRegistry: ToolRegistry,
logger: ILogger
): void {
// Handle tools/list requests
server.setRequestHandler(ListToolsRequestSchema, async () => {
logger.debug('Handling tools/list request');
const tools = toolRegistry.getToolDefinitions();
logger.debug('Returning tool list', {
toolCount: tools.length,
tools: tools.map((t) => t.name),
});
return {
tools: tools.map((tool) => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
})),
};
});
// Handle tools/call requests
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
const { name: toolName, arguments: args } = request.params;
logger.info('Handling tools/call request', {
toolName,
args,
});
if (!toolName) {
const error = new Error('Tool name is required');
logger.error('Tool call failed', error);
throw error;
}
if (!args) {
const error = new Error('Tool arguments are required');
logger.error('Tool call failed', error, { toolName });
throw error;
}
try {
const result = await toolRegistry.execute(toolName, args);
logger.info('Tool executed successfully', {
toolName,
});
return result;
} catch (error) {
logger.error(
'Tool execution failed',
error instanceof Error ? error : new Error(String(error)),
{ toolName, args }
);
throw error;
}
});
// Handle logging/setLevel requests
server.setRequestHandler(SetLevelRequestSchema, async (request) => {
const { level } = request.params;
logger.info('Setting logging level', { level });
// In a production system, you might update the logger's min level here
// For now, just acknowledge the request
return {};
});
logger.info('MCP handlers registered successfully');
}