UNPKG

@ivelin-web/tempo-mcp-server

Version:

MCP server for managing Tempo worklogs in Jira

91 lines (90 loc) 3.23 kB
import axios from 'axios'; import { issueIdSchema, idOrKeySchema } from './types.js'; import config from './config.js'; // Jira API client with authentication const jiraApi = axios.create({ baseURL: config.jiraApi.baseUrl, headers: { Authorization: `Basic ${Buffer.from(`${config.jiraApi.email}:${config.jiraApi.token}`).toString('base64')}`, Accept: 'application/json', 'Content-Type': 'application/json', }, }); // Standardized error handling for Jira API function formatJiraError(error, context) { if (axios.isAxiosError(error)) { const statusCode = error.response?.status; const message = error.response?.data?.message || error.response?.data?.errorMessages?.join(', ') || error.message; return new Error(`${context}: ${statusCode} - ${message}`); } return new Error(`${context}: ${error.message}`); } /** * Get user's account ID using the configured email */ export async function getCurrentUserAccountId() { try { const response = await jiraApi.get('/rest/api/3/user/search', { params: { query: config.jiraApi.email }, }); const users = response.data; if (!users || users.length === 0) { throw new Error(`No user found with email: ${config.jiraApi.email}`); } // Find exact email match const user = users.find((u) => u.emailAddress === config.jiraApi.email); if (!user) { throw new Error(`No exact match for email: ${config.jiraApi.email}`); } return user.accountId; } catch (error) { throw formatJiraError(error, 'Failed to get user account ID'); } } /** * Get Jira issue key from issue ID */ export async function getIssueKeyById(issueId) { try { // Validate issue ID using the schema const result = issueIdSchema().safeParse(issueId); if (!result.success) { throw new Error(result.error.errors[0].message || 'Issue ID validation failed'); } const response = await jiraApi.get(`/rest/api/3/issue/${issueId}`); return response.data.key; } catch (error) { throw formatJiraError(error, `Failed to get issue key for ID ${issueId}`); } } /** * Get Jira issue from issue ID or key */ export async function getIssue(idOrKey) { try { // Validate issue ID using the schema const result = idOrKeySchema().safeParse(idOrKey); if (!result.success) { throw new Error(result.error.errors[0].message || 'Issue identifier validation failed'); } const response = await jiraApi.get(`/rest/api/3/issue/${idOrKey}`); // Find the Tempo account key const tempoAccountId = config.jiraApi.tempoAccountCustomFieldId ? response.data.fields[`customfield_${config.jiraApi.tempoAccountCustomFieldId}`].id : undefined; const id = response.data.id; const key = response.data.key; return { id, key, ...(tempoAccountId ? { tempoAccountId } : {}), }; } catch (error) { throw formatJiraError(error, `Failed to get issue for ${idOrKey}`); } }