UNPKG

mcp-servicenow

Version:

ServiceNow MCP server for Claude AI integration

338 lines (337 loc) 12.4 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.emailTools = exports.GetEmailsTool = exports.SendEmailTool = void 0; exports.sendEmail = sendEmail; exports.getEmails = getEmails; const axios_1 = __importDefault(require("axios")); const logger_1 = require("../utils/logger"); // Tool definition for sending email exports.SendEmailTool = { name: 'send_email', description: 'Send an email through ServiceNow', inputSchema: { type: 'object', properties: { to: { type: 'string', description: 'Recipient email address (required)' }, subject: { type: 'string', description: 'Email subject line (required)' }, body: { type: 'string', description: 'Email body content (required)' }, cc: { type: 'string', description: 'CC recipients (comma-separated email addresses)' }, bcc: { type: 'string', description: 'BCC recipients (comma-separated email addresses)' }, from: { type: 'string', description: 'Sender email address (optional, uses default if not provided)' }, priority: { type: 'string', enum: ['1', '2', '3'], description: 'Email priority (1=high, 2=medium, 3=low)' }, content_type: { type: 'string', enum: ['text/plain', 'text/html'], description: 'Content type of the email body (default: text/plain)' } }, required: ['to', 'subject', 'body'] } }; // Tool definition for getting sent emails exports.GetEmailsTool = { name: 'get_emails', description: 'Get sent emails from ServiceNow', inputSchema: { type: 'object', properties: { recipient: { type: 'string', description: 'Filter by recipient email address' }, sender: { type: 'string', description: 'Filter by sender email address' }, subject: { type: 'string', description: 'Filter by subject containing this text' }, created_since: { type: 'string', description: 'Filter emails created since this date (YYYY-MM-DD)' }, state: { type: 'string', description: 'Filter by email state (e.g., "sent", "ready", "error")' }, limit: { type: 'number', description: 'Maximum number of emails to return (default: 50)' } } } }; // Logic for sending email async function sendEmail(params = {}) { try { (0, logger_1.log)(`sendEmail called with params: ${JSON.stringify(params)}`); // Extract and validate required parameters const { to, subject, body, cc, bcc, from, priority, content_type } = params; // Validate required fields if (!to) { return { content: [{ type: 'text', text: 'Error: "to" parameter is required (recipient email address)' }] }; } if (!subject) { return { content: [{ type: 'text', text: 'Error: "subject" parameter is required' }] }; } if (!body) { return { content: [{ type: 'text', text: 'Error: "body" parameter is required' }] }; } // Validate email format const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(to)) { return { content: [{ type: 'text', text: 'Error: "to" parameter must be a valid email address' }] }; } const instanceUrl = process.env.SERVICENOW_INSTANCE_URL; const username = process.env.SERVICENOW_USERNAME; const password = process.env.SERVICENOW_PASSWORD; const defaultSender = process.env.SERVICENOW_DEFAULT_SENDER_EMAIL; if (!instanceUrl || !username || !password) { return { content: [{ type: 'text', text: 'Error: Missing ServiceNow credentials. Please check environment variables.' }] }; } (0, logger_1.log)(`Sending email to: ${to}, subject: ${subject}`); // Build the email payload const emailPayload = { recipient: to, subject: subject, body: body, type: 'send-ready' // This tells ServiceNow to send the email }; // Optional fields if (cc) emailPayload.cc = cc; if (bcc) emailPayload.bcc = bcc; if (from) { emailPayload.sender = from; } else if (defaultSender) { emailPayload.sender = defaultSender; } if (priority) emailPayload.priority = priority; if (content_type) emailPayload.content_type = content_type; (0, logger_1.log)(`Email payload: ${JSON.stringify(emailPayload)}`); const response = await axios_1.default.post(`${instanceUrl}/api/now/table/sys_email`, emailPayload, { auth: { username, password }, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } }); const email = response.data.result; (0, logger_1.log)(`Email created successfully: ${email.sys_id}`); return { content: [{ type: 'text', text: `Email sent successfully: - Email ID: ${email.sys_id} - To: ${email.recipient} - Subject: ${email.subject} - From: ${email.sender || 'System Default'} - Created: ${email.sys_created_on} - State: ${email.state || 'Queued for sending'} - Priority: ${email.priority || 'Normal'}` }] }; } catch (error) { (0, logger_1.log)(`Error sending email: ${error.message}`); if (error.response) { (0, logger_1.log)(`Error response status: ${error.response.status}`); (0, logger_1.log)(`Error response data: ${JSON.stringify(error.response.data)}`); } let errorMessage = `Error sending email: ${error.message}`; if (error.response?.status === 401) { errorMessage += '\nAuthentication error. Please verify ServiceNow credentials.'; } else if (error.response?.status === 403) { errorMessage += '\nPermission error. Please verify ServiceNow user has email sending permissions.'; } else if (error.response?.status === 400) { errorMessage += '\nBad request. Please check email parameters and formats.'; if (error.response.data?.error?.message) { errorMessage += `\nServiceNow error: ${error.response.data.error.message}`; } } return { content: [{ type: 'text', text: errorMessage }] }; } } // Logic for getting sent emails async function getEmails(params = {}) { try { (0, logger_1.log)(`getEmails called with params: ${JSON.stringify(params)}`); const instanceUrl = process.env.SERVICENOW_INSTANCE_URL; const username = process.env.SERVICENOW_USERNAME; const password = process.env.SERVICENOW_PASSWORD; if (!instanceUrl || !username || !password) { return { content: [{ type: 'text', text: 'Error: Missing ServiceNow credentials. Please check environment variables.' }] }; } // Build query parameters const queryParts = []; if (params.recipient) { queryParts.push(`recipient=${params.recipient}`); } if (params.sender) { queryParts.push(`sender=${params.sender}`); } if (params.subject) { queryParts.push(`subjectCONTAINS${params.subject}`); } if (params.created_since) { queryParts.push(`sys_created_on>=${params.created_since}`); } if (params.state) { queryParts.push(`state=${params.state}`); } const query = queryParts.join('^'); // Build request parameters const requestParams = { sysparm_fields: 'sys_id,recipient,sender,subject,body,state,sys_created_on,sent_on,type,priority', sysparm_limit: params.limit || 50, sysparm_order_by: '-sys_created_on' }; if (query) { requestParams.sysparm_query = query; } (0, logger_1.log)(`Querying emails with: ${JSON.stringify(requestParams)}`); const response = await axios_1.default.get(`${instanceUrl}/api/now/table/sys_email`, { params: requestParams, auth: { username, password }, headers: { 'Accept': 'application/json' } }); (0, logger_1.log)(`ServiceNow response status: ${response.status}`); const emails = response.data.result; if (!emails) { return { content: [{ type: 'text', text: 'Error: Invalid response from ServiceNow.' }] }; } (0, logger_1.log)(`Found ${emails.length} emails`); if (emails.length === 0) { return { content: [{ type: 'text', text: 'No emails found matching the specified criteria.' }] }; } // Format emails for display const formattedEmails = emails.map((email) => { const bodyPreview = email.body ? (email.body.length > 100 ? email.body.substring(0, 100) + '...' : email.body) : 'No body'; return `• **Email ID:** ${email.sys_id} **To:** ${email.recipient} **From:** ${email.sender || 'System'} **Subject:** ${email.subject} **State:** ${email.state || 'Unknown'} **Priority:** ${email.priority || 'Normal'} **Created:** ${email.sys_created_on} **Sent:** ${email.sent_on || 'Not sent yet'} **Body Preview:** ${bodyPreview}`; }).join('\n\n'); return { content: [{ type: 'text', text: `Found ${emails.length} email(s):\n\n${formattedEmails}` }] }; } catch (error) { (0, logger_1.log)(`Error getting emails: ${error.message}`); if (error.response) { (0, logger_1.log)(`Error response status: ${error.response.status}`); (0, logger_1.log)(`Error response data: ${JSON.stringify(error.response.data)}`); } let errorMessage = `Error retrieving emails: ${error.message}`; if (error.response?.status === 401) { errorMessage += '\nAuthentication error. Please verify ServiceNow credentials.'; } else if (error.response?.status === 403) { errorMessage += '\nPermission error. Please verify ServiceNow user roles for email access.'; } return { content: [{ type: 'text', text: errorMessage }] }; } } // Collection of all email-related tools exports.emailTools = { [exports.SendEmailTool.name]: { definition: exports.SendEmailTool, execute: sendEmail }, [exports.GetEmailsTool.name]: { definition: exports.GetEmailsTool, execute: getEmails } };