@pavi_thran_7/jira-mcp-server
Version:
MCP server for Jira integration with ticket creation and time logging
183 lines (161 loc) • 6.2 kB
JavaScript
/**
* @fileoverview Billing account management tools for Jira MCP server
*/
/**
* @typedef {import('../types/jira.js').McpToolResult} McpToolResult
* @typedef {import('../jira-client.js').JiraClient} JiraClient
*/
/**
* List billing accounts for time logging
* @param {JiraClient} jiraClient - Jira client instance
* @param {Object} params - Parameters
* @param {string} [params.projectKey] - Project key to filter billing accounts
* @returns {Promise<McpToolResult>} Billing accounts list result
*/
export async function listBillingAccounts(jiraClient, params = {}) {
try {
let billingAccounts = [];
if (params.projectKey) {
// Get billing accounts for specific project
const worklogSchemesResult = await jiraClient.getWorklogSchemes(params.projectKey);
if (!worklogSchemesResult.success) {
// If worklog schemes are not available, return helpful message
if (worklogSchemesResult.statusCode === 404) {
return {
content: [
{
type: 'text',
text: `⚠️ **Billing Accounts Not Available**
Project "${params.projectKey}" does not have billing accounts configured, or this feature is not enabled in your Jira instance.
**Note:** Billing accounts are typically available in:
- Jira Cloud with time tracking apps (like Tempo)
- Jira Server/Data Center with billing plugins
- Enterprise Jira configurations
You can still log work without billing accounts using the log_work tool.`,
},
],
isError: false,
};
}
return {
content: [
{
type: 'text',
text: `Error getting billing accounts: ${worklogSchemesResult.error}`,
},
],
isError: true,
};
}
// Parse worklog schemes to extract billing accounts
const schemes = worklogSchemesResult.data;
if (schemes && schemes.length > 0) {
for (const scheme of schemes) {
const schemeDetailsResult = await jiraClient.getWorklogScheme(scheme.id);
if (schemeDetailsResult.success && schemeDetailsResult.data.billingAccounts) {
billingAccounts.push(...schemeDetailsResult.data.billingAccounts);
}
}
}
} else {
// Get all projects and their billing accounts
const projectsResult = await jiraClient.getProjects();
if (!projectsResult.success) {
return {
content: [
{
type: 'text',
text: `Error getting projects: ${projectsResult.error}`,
},
],
isError: true,
};
}
const projects = projectsResult.data.values;
for (const project of projects.slice(0, 10)) { // Limit to first 10 projects to avoid too many requests
const worklogSchemesResult = await jiraClient.getWorklogSchemes(project.key);
if (worklogSchemesResult.success) {
const schemes = worklogSchemesResult.data;
if (schemes && schemes.length > 0) {
for (const scheme of schemes) {
const schemeDetailsResult = await jiraClient.getWorklogScheme(scheme.id);
if (schemeDetailsResult.success && schemeDetailsResult.data.billingAccounts) {
billingAccounts.push(...schemeDetailsResult.data.billingAccounts.map(ba => ({
...ba,
projectKey: project.key,
})));
}
}
}
}
}
}
// Remove duplicates based on ID
const uniqueBillingAccounts = billingAccounts.filter((account, index, self) =>
index === self.findIndex(a => a.id === account.id)
);
if (uniqueBillingAccounts.length === 0) {
const projectFilter = params.projectKey ? ` for project "${params.projectKey}"` : '';
return {
content: [
{
type: 'text',
text: `⚠️ **No Billing Accounts Found${projectFilter}**
This could mean:
- Billing accounts are not configured in your Jira instance
- You don't have permission to view billing accounts
- The project doesn't have time tracking with billing enabled
- Your Jira instance doesn't support billing accounts
**Alternative:** You can still log work without billing accounts using the log_work tool.`,
},
],
isError: false,
};
}
// Format billing accounts list
const accountsList = uniqueBillingAccounts.map(account => {
const projectInfo = account.projectKey ? ` (${account.projectKey})` : '';
const clientInfo = account.clientName ? ` - Client: ${account.clientName}` : '';
const costCenterInfo = account.costCenter ? ` - Cost Center: ${account.costCenter}` : '';
const activeStatus = account.active === false ? ' [INACTIVE]' : '';
return `- **${account.id}**: ${account.name}${projectInfo}${clientInfo}${costCenterInfo}${activeStatus}`;
}).join('\n');
const projectFilter = params.projectKey ? ` for project "${params.projectKey}"` : '';
return {
content: [
{
type: 'text',
text: `💰 **Available Billing Accounts${projectFilter} (${uniqueBillingAccounts.length})**
${accountsList}
**Usage:**
- Use the billing account ID (e.g., "${uniqueBillingAccounts[0].id}") when logging work
- Include billingAccountId parameter in log_work calls for proper cost tracking
- Only active billing accounts should be used for new work logs
**Example:**
\`\`\`json
{
"tool": "log_work",
"arguments": {
"issueKey": "PROJ-123",
"timeSpent": "2h",
"comment": "Development work",
"billingAccountId": "${uniqueBillingAccounts[0].id}"
}
}
\`\`\``,
},
],
isError: false,
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error listing billing accounts: ${error.message}`,
},
],
isError: true,
};
}
}