UNPKG

@todo-for-ai/mcp

Version:

Model Context Protocol server for Todo for AI task management system with Streamable HTTP transport. Provides AI assistants with access to task management, project information, and feedback submission capabilities through modern HTTP-based communication.

114 lines 3.36 kB
import { logger } from './logger.js'; export class McpError extends Error { code; statusCode; details; constructor(message, code = 'UNKNOWN_ERROR', statusCode, details) { super(message); this.name = 'McpError'; this.code = code; this.statusCode = statusCode; this.details = details; } } export class ValidationError extends McpError { constructor(message, details) { super(message, 'VALIDATION_ERROR', 400, details); this.name = 'ValidationError'; } } export class ApiConnectionError extends McpError { constructor(message, details) { super(message, 'API_CONNECTION_ERROR', 503, details); this.name = 'ApiConnectionError'; } } export class AuthenticationError extends McpError { constructor(message, details) { super(message, 'AUTHENTICATION_ERROR', 401, details); this.name = 'AuthenticationError'; } } export class NotFoundError extends McpError { constructor(message, details) { super(message, 'NOT_FOUND_ERROR', 404, details); this.name = 'NotFoundError'; } } /** * Global error handler for unhandled errors */ export function setupGlobalErrorHandlers() { process.on('uncaughtException', (error) => { logger.error('Uncaught Exception:', { name: error.name, message: error.message, stack: error.stack, }); // Give time for logs to flush setTimeout(() => { process.exit(1); }, 1000); }); process.on('unhandledRejection', (reason, promise) => { logger.error('Unhandled Promise Rejection:', { reason: reason instanceof Error ? { name: reason.name, message: reason.message, stack: reason.stack, } : reason, promise: promise.toString(), }); // Give time for logs to flush setTimeout(() => { process.exit(1); }, 1000); }); } /** * Validate required arguments for MCP tools */ export function validateArgs(args, requiredFields) { if (!args || typeof args !== 'object') { throw new ValidationError('Arguments must be an object'); } const missingFields = requiredFields.filter(field => !(field in args) || args[field] === undefined || args[field] === null); if (missingFields.length > 0) { throw new ValidationError(`Missing required fields: ${missingFields.join(', ')}`, { missingFields, providedFields: Object.keys(args), }); } } /** * Sanitize error for client response */ export function sanitizeError(error) { if (error instanceof McpError) { return { error: error.message, code: error.code, details: error.details, }; } // Don't expose internal error details to clients return { error: 'An internal error occurred', code: 'INTERNAL_ERROR', }; } /** * Wrap async functions with error handling */ export function withErrorHandling(fn, context) { return async (...args) => { try { return await fn(...args); } catch (error) { logger.error(`Error in ${context}:`, error); throw error; } }; } //# sourceMappingURL=error-handler.js.map