MCP FOR ITSM

by madosh
Verified
// MCP ITSM Tools - Smithery Integration const readline = require('readline'); // Create readline interface for stdio const rl = readline.createInterface({ input: process.stdin, output: process.stdout, terminal: false }); // Mock implementation of ITSM tools const tickets = {}; let nextTicketId = 1000; // Handle incoming messages rl.on('line', async (line) => { try { const message = JSON.parse(line); console.error(`Received message: ${line}`); // Handle MCP tool calls if (message.type === 'tool_call') { const { name, parameters } = message.data; let result; console.error(`Processing tool call: ${name}`); switch (name) { case 'create_ticket': result = handleCreateTicket(parameters); break; case 'get_ticket': result = handleGetTicket(parameters); break; case 'update_ticket': result = handleUpdateTicket(parameters); break; case 'list_tickets': result = handleListTickets(parameters); break; case 'assign_ticket': result = handleAssignTicket(parameters); break; case 'add_comment': result = handleAddComment(parameters); break; case 'search_knowledge_base': result = handleSearchKnowledgeBase(parameters); break; default: result = { error: `Unknown tool: ${name}` }; } // Send response back in MCP format const response = { type: 'tool_response', id: message.id, data: result }; console.log(JSON.stringify(response)); } // For backward compatibility, also handle function calls else if (message.type === 'function' || message.type === 'function_call') { console.error(`Received non-MCP message type: ${message.type}`); let name, params, id; if (message.type === 'function') { name = message.name; params = typeof message.arguments === 'string' ? JSON.parse(message.arguments) : message.arguments; id = message.id || 'function-call'; } else { name = message.function_call.name; params = message.function_call.arguments; id = message.id || 'function-call'; } let result; switch (name) { case 'create_ticket': result = handleCreateTicket(params); break; case 'get_ticket': result = handleGetTicket(params); break; case 'update_ticket': result = handleUpdateTicket(params); break; case 'list_tickets': result = handleListTickets(params); break; case 'assign_ticket': result = handleAssignTicket(params); break; case 'add_comment': result = handleAddComment(params); break; case 'search_knowledge_base': result = handleSearchKnowledgeBase(params); break; default: result = { error: `Unknown function: ${name}` }; } // Convert to MCP format for consistency const response = { type: 'tool_response', id: id, data: result }; console.log(JSON.stringify(response)); } } catch (error) { console.error('Error processing message:', error); // Send error response const errorResponse = { type: 'error', error: error.message }; console.log(JSON.stringify(errorResponse)); } }); // Tool handlers function handleCreateTicket(params) { const { title, description, priority = 'medium', system = 'jira' } = params; // Generate ticket ID based on system const prefix = system === 'jira' ? 'JIRA-' : system === 'servicenow' ? 'SN-' : 'ZD-'; const ticketId = `${prefix}${nextTicketId++}`; // Create ticket tickets[ticketId] = { id: ticketId, title, description, priority, status: 'open', system, created_at: new Date().toISOString(), updated_at: new Date().toISOString(), assignee: null, comments: [] }; return { success: true, ticket: { id: ticketId, title, system, status: 'open', url: `https://example.com/${system}/tickets/${ticketId}` } }; } function handleGetTicket(params) { const { ticket_id } = params; if (!tickets[ticket_id]) { return { success: false, error: `Ticket ${ticket_id} not found` }; } return { success: true, ticket: tickets[ticket_id] }; } function handleUpdateTicket(params) { const { ticket_id, status, priority, comment } = params; if (!tickets[ticket_id]) { return { success: false, error: `Ticket ${ticket_id} not found` }; } const ticket = tickets[ticket_id]; if (status) ticket.status = status; if (priority) ticket.priority = priority; if (comment) ticket.comments.push(comment); ticket.updated_at = new Date().toISOString(); return { success: true, ticket: { id: ticket.id, title: ticket.title, status: ticket.status, system: ticket.system } }; } function handleListTickets(params) { const { status, assigned_to, limit = 10, system } = params; let filteredTickets = Object.values(tickets); if (status && status !== 'all') { filteredTickets = filteredTickets.filter(t => t.status === status); } if (assigned_to) { filteredTickets = filteredTickets.filter(t => t.assignee === assigned_to); } if (system) { filteredTickets = filteredTickets.filter(t => t.system === system); } // Sort by created date (newest first) filteredTickets.sort((a, b) => new Date(b.created_at) - new Date(a.created_at)); // Apply limit filteredTickets = filteredTickets.slice(0, limit); return { success: true, tickets: filteredTickets.map(t => ({ id: t.id, title: t.title, status: t.status, system: t.system })), total: filteredTickets.length }; } function handleAssignTicket(params) { const { ticket_id, user_id } = params; if (!tickets[ticket_id]) { return { success: false, error: `Ticket ${ticket_id} not found` }; } tickets[ticket_id].assignee = user_id; tickets[ticket_id].updated_at = new Date().toISOString(); return { success: true, ticket: { id: tickets[ticket_id].id, title: tickets[ticket_id].title, assignee: user_id, system: tickets[ticket_id].system } }; } function handleAddComment(params) { const { ticket_id, comment, internal = false } = params; if (!tickets[ticket_id]) { return { success: false, error: `Ticket ${ticket_id} not found` }; } const commentObj = { text: comment, internal, created_at: new Date().toISOString() }; tickets[ticket_id].comments.push(commentObj); tickets[ticket_id].updated_at = new Date().toISOString(); return { success: true, comment: commentObj, ticket_id }; } function handleSearchKnowledgeBase(params) { const { query, limit = 5 } = params; // Mock knowledge base articles const articles = [ { id: 'KB-001', title: 'How to reset your password', summary: 'Step-by-step guide to reset your password', url: 'https://example.com/kb/password-reset' }, { id: 'KB-002', title: 'Common login issues', summary: 'Troubleshooting common login problems', url: 'https://example.com/kb/login-issues' }, { id: 'KB-003', title: 'Setting up email on mobile devices', summary: 'How to configure email on iOS and Android', url: 'https://example.com/kb/email-setup' }, { id: 'KB-004', title: 'VPN connection troubleshooting', summary: 'Fixing common VPN connection problems', url: 'https://example.com/kb/vpn-issues' }, { id: 'KB-005', title: 'Printer setup guide', summary: 'How to install and configure network printers', url: 'https://example.com/kb/printer-setup' } ]; // Simple mock search (in a real implementation, this would use proper search) const results = articles.filter(article => article.title.toLowerCase().includes(query.toLowerCase()) || article.summary.toLowerCase().includes(query.toLowerCase()) ).slice(0, limit); return { success: true, articles: results, total: results.length }; } // Log startup console.error('MCP ITSM Tools service started'); // Handle process termination process.on('SIGINT', () => { console.error('MCP ITSM Tools service shutting down'); process.exit(0); });