Get Item Details
get_item_detailsRetrieve the complete structured detail of a Codebeamer work item including project, priority, assignees, timestamps, story points, custom fields, and test steps. Does not include the description.
Instructions
Get the full structured detail of a Codebeamer work item: project, priority, assignees, created/updated timestamps, story points, custom fields and test steps. Description is intentionally omitted — fetch it via get_item.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| itemId | Yes | Numeric item (work item) ID |
Implementation Reference
- src/tools/item-details.ts:32-35 (handler)The async handler function for the 'get_item_details' tool. Calls client.getItem(itemId) and formats the result with formatItemDetails.
async ({ itemId }) => { const item = await client.getItem(itemId); return { content: [{ type: "text", text: formatItemDetails(item) }] }; }, - src/tools/item-details.ts:24-30 (schema)Input schema for get_item_details — requires a positive integer itemId.
inputSchema: { itemId: z .number() .int() .positive() .describe("Numeric item (work item) ID"), }, - src/tools/item-details.ts:16-36 (registration)Registration of the 'get_item_details' tool via server.registerTool() inside registerItemDetailTools.
server.registerTool( "get_item_details", { title: "Get Item Details", description: "Get the full structured detail of a Codebeamer work item: project, priority, assignees, " + "created/updated timestamps, story points, custom fields and test steps. " + "Description is intentionally omitted — fetch it via get_item.", inputSchema: { itemId: z .number() .int() .positive() .describe("Numeric item (work item) ID"), }, }, async ({ itemId }) => { const item = await client.getItem(itemId); return { content: [{ type: "text", text: formatItemDetails(item) }] }; }, ); - The formatItemDetails function that formats the full item details: project, priority, assignees, timestamps, story points, custom fields, and test steps.
export function formatItemDetails(item: CbItem): string { const lines: string[] = [ `## [${item.id}] ${item.name}`, "", `- **Project:** ${item.project?.name ?? "?"}`, `- **Priority:** ${item.priority?.name ?? "?"}`, `- **Assigned to:** ${item.assignedTo?.map((u) => u.name).join(", ") || "unassigned"}`, `- **Created:** ${item.createdAt ?? "?"} by ${item.createdBy?.name ?? "?"}`, `- **Updated:** ${item.updatedAt ?? "?"}`, ]; if (item.storyPoints !== undefined) { lines.push(`- **Story Points:** ${item.storyPoints}`); } if (item.customFields && item.customFields.length > 0) { const isTestStepField = (f: { type?: string }) => f.type === "TestStepsFieldValue" || f.type === "TableFieldValue"; const regularFields = item.customFields.filter((f) => !isTestStepField(f)); const testStepFields = item.customFields.filter((f) => isTestStepField(f)); if (regularFields.length > 0) { lines.push("", "### Custom Fields", ""); for (const field of regularFields) { const vals = field.values as Array<{ id: number; name?: string }> | undefined; const displayValue = vals && vals.length > 0 ? vals.map((v) => v.name ? `[${v.id}] ${v.name}` : String(v.id)).join(", ") : formatFieldValue(field.value); lines.push(`- **${field.name}:** ${displayValue}`); } } for (const field of testStepFields) { let steps: CbTestStep[]; if (field.type === "TableFieldValue") { const rows = Array.isArray(field.values) ? field.values : []; steps = rows.map((row, idx) => { const cols = Array.isArray(row) ? (row as Array<{ name: string; value: unknown }>) : []; const action = cols.find((c) => c.name === "Action")?.value; const expected = cols.find((c) => c.name === "Expected result")?.value; return { index: idx, actionDescription: typeof action === "string" ? action : undefined, expectedResults: typeof expected === "string" ? expected : undefined, }; }); } else { steps = Array.isArray(field.value) ? (field.value as CbTestStep[]) : []; } lines.push("", `### ${field.name}`, ""); if (steps.length === 0) { lines.push("_No test steps defined._"); } else { lines.push("| # | Action | Expected Result |"); lines.push("|---|--------|-----------------|"); for (const step of steps) { const num = (step.index ?? 0) + 1; const action = (step.actionDescription ?? "").replace(/\|/g, "\\|").replace(/\n/g, " "); const expected = (step.expectedResults ?? "").replace(/\|/g, "\\|").replace(/\n/g, " "); lines.push(`| ${num} | ${action} | ${expected} |`); } } } } return lines.join("\n"); } - The getItem method on CodebeamerClient that fetches a work item by ID from the Codebeamer API.
getItem(id: number): Promise<CbItem> { return this.http.get(`/items/${id}`, { resource: `item ${id}` }); }