getNextBug
Retrieve the next active bug assigned to you in a ZenTao product. Filter by keyword or status to prioritize bug resolution in project management workflows.
Instructions
Get the next active bug assigned to me under a product (first match).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| productId | Yes | Product ID (required) | |
| keyword | No | Keyword filter on bug title | |
| status | No | Status filter (e.g., active) |
Implementation Reference
- src/zentao-mcp-server.js:665-698 (handler)Handler implementation for 'getNextBug' tool: Paginates through up to 10 pages of bugs assigned to the current account in the specified product, filters by keyword and status, returns the first matching bug's details including extracted images from steps.if (name === "getNextBug") { const { productId, keyword, status } = args; let page = 1; const pageSize = 20; while (page <= 10) { const { bugs } = await fetchBugsByProduct({ productId, keyword, status, limit: pageSize, page, }); if (bugs.length) { const bugDetail = await getBugWithImages(bugs[0].id || bugs[0].bugId); return { content: [ { type: "text", text: JSON.stringify({ bug: bugDetail }, null, 2), }, ], }; } page += 1; } return { content: [ { type: "text", text: `No active bugs assigned to ${account || "me"} found under product ${productId}`, }, ], }; }
- src/zentao-mcp-server.js:481-495 (registration)Tool registration in the MCP tools list, including name, description, and input schema definition.{ name: "getNextBug", description: "Get the next active bug assigned to me under a product (first match).", inputSchema: { type: "object", properties: { productId: { type: "number", description: "Product ID (required)" }, keyword: { type: "string", description: "Keyword filter on bug title" }, status: { type: "string", description: "Status filter (e.g., active)" }, }, required: ["productId"], additionalProperties: false, }, },
- src/zentao-mcp-server.js:235-280 (helper)Core helper function used by getNextBug to fetch and filter bugs assigned to the current user from ZenTao API, applying assignee, keyword, and status filters.async function fetchBugsByProduct({ productId, keyword, allStatuses = false, status, limit = 20, page = 1, }) { const res = await callZenTao({ // Use /bugs with product filter; works better for assignedTo filtering. path: "bugs", query: { page, limit, product: productId, keywords: keyword, }, }); const bugs = extractArray(res.data, ["bugs"]); const accountLower = (account || "").trim().toLowerCase(); const statusLower = status ? String(status).trim().toLowerCase() : null; const filtered = bugs.filter((bug) => { const assignedCandidates = [ ...normalizeAccount(bug.assignedTo), ...normalizeAccount(bug.assignedToName), ...normalizeAccount(bug.assignedToRealname), ]; const matchAssignee = accountLower ? assignedCandidates.includes(accountLower) : true; const matchKeyword = keyword ? `${bug.title || bug.name || ""}` .toLowerCase() .includes(keyword.toLowerCase()) : true; const matchStatus = allStatuses ? true : statusLower ? String(bug.status || bug.state || "") .trim() .toLowerCase() === statusLower : true; return matchAssignee && matchKeyword && matchStatus; }); return { bugs: filtered, raw: res.data }; }
- src/zentao-mcp-server.js:282-288 (helper)Helper to fetch bug details and extract image URLs from steps HTML.async function getBugWithImages(bugId) { const res = await callZenTao({ path: `bugs/${bugId}` }); const bug = res.data || {}; const stepsHtml = bug.steps || bug.stepsHtml || ""; const stepsImages = parseImageSources(stepsHtml); return { ...bug, stepsHtml, stepsImages }; }