import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; export type ErrorClassification = | 'auth_error' | 'timeout' | 'not_found' | 'connection_error' | 'x3_error' | 'unknown'; export function formatToolError(error: unknown, hint?: string): CallToolResult { const message = error instanceof Error ? error.message : String(error); const parts = [`Error: ${message}`]; if (hint) { parts.push(`\nHint: ${hint}`); } return { isError: true as const, content: [{ type: 'text' as const, text: parts.join('') }], }; } export function classifyError(error: unknown): ErrorClassification { if (!(error instanceof Error)) return 'unknown'; const msg = error.message.toLowerCase(); const statusMatch = msg.match(/status[:\s]*(\d{3})/); const status = statusMatch ? parseInt(statusMatch[1], 10) : undefined; if (status === 401 || status === 403 || msg.includes('unauthorized') || msg.includes('authentication')) { return 'auth_error'; } if (msg.includes('timeout') || msg.includes('etimedout') || msg.includes('econnaborted')) { return 'timeout'; } if (status === 404 || msg.includes('not found')) { return 'not_found'; } if (msg.includes('econnrefused') || msg.includes('enotfound') || msg.includes('connect')) { return 'connection_error'; } if (msg.includes('x3') || msg.includes('sage') || msg.includes('business')) { return 'x3_error'; } return 'unknown'; } const ERROR_HINTS: Record = { auth_error: 'Check SAGE_X3_USER and SAGE_X3_PASSWORD. Ensure the web service user has API access.', timeout: 'The X3 server is slow to respond. Try a simpler query or smaller count.', not_found: 'Record not found. Verify the entity name and key. Use sage_list_entities to discover available entities.', connection_error: 'Cannot connect to X3 server. Check SAGE_X3_URL and network connectivity.', x3_error: 'X3 returned a business error. Check the error messages for details.', unknown: 'An unexpected error occurred. Check server logs for details.', }; export function getErrorHint(classification: ErrorClassification): string { return ERROR_HINTS[classification]; }