Skip to main content
Glama

get_worklogs

Retrieve time tracking worklogs from JIRA Tempo for a specified date range, optionally filtered by issue key, to review logged hours and activities.

Instructions

Retrieve worklogs for authenticated user and date range

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
endDateNoEnd date in YYYY-MM-DD format (optional, defaults to startDate)
issueKeyNoOptional filter by specific issue key (e.g., PROJ-1234)
startDateYesStart date in YYYY-MM-DD format

Implementation Reference

  • Main handler function that fetches, processes, and formats worklogs from Tempo API for the given date range and optional issue key. Generates a concise markdown summary with totals, issue groups, and recent entries.
    export async function getWorklogs( tempoClient: TempoClient, input: GetWorklogsInput ): Promise<CallToolResult> { try { const { startDate, endDate, issueKey } = input; // Use endDate or default to startDate const actualEndDate = endDate || startDate; // Fetch worklogs from Tempo API (automatically filters by authenticated user) const worklogResponses = await tempoClient.getWorklogs({ from: startDate, to: actualEndDate, issueKey: issueKey }); // Process and format the worklogs const worklogs: TempoWorklog[] = worklogResponses.map((response: TempoWorklogResponse) => ({ id: response.tempoWorklogId?.toString() || response.id || 'unknown', issueKey: response.issue.key, issueSummary: response.issue.summary, timeSpentSeconds: response.timeSpentSeconds, billableSeconds: response.billableSeconds, started: response.started, worker: response.worker, attributes: response.attributes || {}, timeSpent: response.timeSpent, comment: response.comment || '' })); // Calculate total hours const totalSeconds = worklogs.reduce((sum, worklog) => sum + worklog.timeSpentSeconds, 0); const totalHours = Math.round((totalSeconds / 3600) * 100) / 100; // Round to 2 decimal places const result: GetWorklogsResponse = { worklogs, totalHours }; // Format response for display - CONCISE VERSION let displayText = `## Your Worklogs (${startDate}`; if (endDate && endDate !== startDate) { displayText += ` to ${endDate}`; } displayText += `)\n\n`; if (issueKey) { displayText += `**Issue:** ${issueKey}\n\n`; } if (worklogs.length === 0) { displayText += "No worklogs found.\n"; } else { displayText += `**Total:** ${totalHours}h (${worklogs.length} entries)\n\n`; // Group by issue for summary (more concise) const issueGroups = worklogs.reduce((acc, worklog) => { if (!acc[worklog.issueKey]) { acc[worklog.issueKey] = { totalSeconds: 0, entries: 0 }; } acc[worklog.issueKey].totalSeconds += worklog.timeSpentSeconds; acc[worklog.issueKey].entries += 1; return acc; }, {} as Record<string, { totalSeconds: number; entries: number }>); // Show summary by issue with issue summary for (const [key, data] of Object.entries(issueGroups)) { const hours = (data.totalSeconds / 3600).toFixed(1); // Get issue summary from first worklog with this key const sampleWorklog = worklogs.find(w => w.issueKey === key); const issueSummary = sampleWorklog?.issueSummary || ''; displayText += `• **${key}** (${issueSummary}): ${hours}h (${data.entries} entries)\n`; } // Show recent entries (limit to 100 most recent) const recentWorklogs = worklogs .sort((a, b) => b.started.localeCompare(a.started)) .slice(0, 100); if (recentWorklogs.length > 0) { displayText += `\n**Recent Entries:**\n`; for (const worklog of recentWorklogs) { // Extract date part from datetime string (handles both "2025-09-12 00:00:00.000" and "2025-09-12T00:00:00.000") const datePart = worklog.started.split(/[T\s]/)[0]; // Parse and format the human-readable date const parsedDate = parseISO(datePart); const humanReadableDate = format(parsedDate, "EEEE, MMMM do, yyyy"); // Create hybrid format: ISO date + human-readable in parentheses const formattedDate = `${datePart} (${humanReadableDate})`; const hours = (worklog.timeSpentSeconds / 3600).toFixed(1); let entryText = `• ${formattedDate}: **${worklog.issueKey}** (${worklog.issueSummary}) - ${hours}h - [ID: ${worklog.id}]`; if (worklog.comment && worklog.comment.trim()) { entryText += ` - "${worklog.comment}"`; } displayText += `${entryText}\n`; } } if (worklogs.length > 100) { displayText += `\n*Showing 100 most recent of ${worklogs.length} total entries*\n`; displayText += `*💡 Tip: Use a shorter date range or specific issueKey filter for more targeted results*\n`; } } return { content: [ { type: "text", text: displayText } ], isError: false }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text", text: `Error retrieving worklogs: ${errorMessage}` } ], isError: true }; } }
  • Zod schema for validating GetWorklogs tool input parameters: startDate (required YYYY-MM-DD), optional endDate and issueKey.
    export const GetWorklogsInputSchema = z.object({ startDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "Start date must be in YYYY-MM-DD format"), endDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "End date must be in YYYY-MM-DD format").optional(), issueKey: z.string().optional(), });
  • src/index.ts:72-95 (registration)
    Tool registration in MCP ListTools handler: defines name, description, and input schema for get_worklogs.
    { name: TOOL_NAMES.GET_WORKLOGS, description: "Retrieve worklogs for authenticated user and date range", inputSchema: { type: "object", properties: { startDate: { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$", description: "Start date in YYYY-MM-DD format", }, endDate: { type: "string", pattern: "^\\d{4}-\\d{2}-\\d{2}$", description: "End date in YYYY-MM-DD format (optional, defaults to startDate)", }, issueKey: { type: "string", description: "Optional filter by specific issue key (e.g., PROJ-1234)", }, }, required: ["startDate"], }, },
  • src/index.ts:221-224 (registration)
    Tool execution handler in MCP CallToolRequestSchema switch case: parses input with schema and calls the getWorklogs handler.
    case TOOL_NAMES.GET_WORKLOGS: { const input = GetWorklogsInputSchema.parse(args); return await getWorklogs(tempoClient, input); }
  • TypeScript interfaces defining input parameters and response structure for getWorklogs, used in TempoClient and handler.
    export interface GetWorklogsParams { user: string; startDate: string; // ISO date (YYYY-MM-DD) endDate?: string; // ISO date, defaults to startDate issueKey?: string; // Optional filter by specific issue } // Get worklogs response export interface GetWorklogsResponse { worklogs: TempoWorklog[]; totalHours: number; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/TRANZACT/tempo-filler-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server