rdms_get_bug
Retrieve detailed bug information by ID, including image URLs, from Zentao bug tracking systems. Use the extracted URLs to analyze image content with the rdms_download_image tool.
Instructions
Get bug details by ID with image extraction. Returns bug information including image URLs but NOT image content. If you need to analyze image content, use the rdms_download_image tool with the returned image URLs.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bugId | Yes | Bug ID |
Implementation Reference
- index.js:222-454 (handler)Main handler function that fetches the RDMS bug detail page, parses HTML structure using Cheerio, extracts comprehensive bug information including metadata fields, image URLs, and change history, then returns structured JSON.async getBug(bugId) { await this.ensureLoggedIn(); try { const response = await this.client.get(`${this.baseUrl}/index.php?m=bug&f=view&bugID=${bugId}`); // 检查是否被重定向到登录页面 if (response.data.includes('login') && response.data.length < 500) { throw new Error('Session expired, please login again'); } const $ = cheerio.load(response.data); // 初始化完整的响应结构 const bugInfo = { id: bugId, title: '', status: '', priority: '', severity: '', confirmed: '', assignedTo: '', reporter: '', createdBy: '', resolvedBy: '', closedBy: '', cc: '', product: '', project: '', module: '', version: '', affectedVersion: '', resolvedVersion: '', os: '', browser: '', platformDevice: '', bugType: '', plan: '', attribution: '', attributionTeam: '', valueAttribute: '', activationCount: '', activationDate: '', probability: '', commonIssue: '', execution: '', requirement: '', task: '', relatedBugs: '', relatedCases: '', deadline: '', created: '', updated: '', lastModified: '', steps: '', description: '', keywords: '', solution: '', images: [] }; // 提取标题 - 保留完整标题,只移除BUG编号和最后的系统名称 const fullTitle = $('title').text().trim(); if (fullTitle) { // 移除开头的 "BUG #数字 " 和结尾的 " - 锐明RDMS" bugInfo.title = fullTitle .replace(/^BUG #\d+\s*/, '') .replace(/\s*-\s*锐明RDMS\s*$/, '') .replace(/\s*-\s*FT-V3\.X\s*-\s*锐明RDMS\s*$/, '') .trim(); } else { bugInfo.title = $('.page-title, h1').text().trim(); } // 提取图片 $('img').each((i, img) => { const src = $(img).attr('src'); if (src && !src.includes('data:') && !src.includes('base64')) { const fullUrl = src.startsWith('http') ? src : `${this.baseUrl}${src}`; bugInfo.images.push(fullUrl); } }); // 字段映射表 - 中文标签到英文字段的映射 const fieldMapping = { '状态': 'status', 'Bug状态': 'status', '优先级': 'priority', '严重程度': 'severity', '是否确认': 'confirmed', '指派给': 'assignedTo', '由谁创建': 'reporter', '创建者': 'createdBy', '报告人': 'reporter', '解决者': 'resolvedBy', '关闭者': 'closedBy', '抄送给': 'cc', '所属产品': 'product', '所属项目': 'project', '所属模块': 'module', '影响版本': 'version', '版本': 'affectedVersion', '解决版本': 'resolvedVersion', '操作系统': 'os', '浏览器': 'browser', '平台/设备': 'platformDevice', 'Bug类型': 'bugType', '类型': 'bugType', '计划': 'plan', '所属计划': 'plan', '归属': 'attribution', '归属团队': 'attributionTeam', '价值属性': 'valueAttribute', '激活次数': 'activationCount', '激活日期': 'activationDate', '出现概率': 'probability', '常见问题': 'commonIssue', '执行': 'execution', '需求': 'requirement', '关联需求': 'requirement', '任务': 'task', '关联任务': 'task', '相关Bug': 'relatedBugs', '相关用例': 'relatedCases', '截止日期': 'deadline', '创建时间': 'created', '更新时间': 'updated', '最后修改': 'lastModified', '重现步骤': 'steps', '详细描述': 'description', '描述': 'description', '关键词': 'keywords', '解决方案': 'solution' }; // 从表格中提取字段 $('table tr, .table tr').each((i, row) => { const $row = $(row); const cells = $row.find('td, th'); if (cells.length >= 2) { const label = cells.eq(0).text().trim(); const value = cells.eq(1).text().trim(); // 查找匹配的字段 for (const [chineseLabel, englishField] of Object.entries(fieldMapping)) { if (label.includes(chineseLabel) && value) { bugInfo[englishField] = value; break; } } } }); // 使用CSS选择器进一步提取字段 Object.entries(fieldMapping).forEach(([chineseLabel, englishField]) => { if (!bugInfo[englishField]) { // 查找包含中文标签的元素 const elements = $(`*:contains("${chineseLabel}")`); elements.each((i, el) => { const $el = $(el); const text = $el.text().trim(); // 如果元素只包含标签文本,查找相邻元素的值 if (text === chineseLabel || text === chineseLabel + ':' || text === chineseLabel + ':') { const nextSibling = $el.next(); const parent = $el.parent(); const parentSiblings = parent.next(); let value = ''; if (nextSibling.length && nextSibling.text().trim()) { value = nextSibling.text().trim(); } else if (parentSiblings.length && parentSiblings.text().trim()) { value = parentSiblings.text().trim(); } else { // 查找同一行的其他单元格 const row = $el.closest('tr'); const cells = row.find('td'); if (cells.length > 1) { value = cells.eq(1).text().trim(); } } if (value && value !== chineseLabel) { bugInfo[englishField] = value; return false; // 找到后停止查找 } } }); } }); // 特殊处理一些字段 // 提取步骤和描述(通常在较大的文本区域中) if (!bugInfo.steps) { const stepsArea = $('.steps, .reproduce-steps, [name*="steps"]').text().trim(); if (stepsArea) bugInfo.steps = stepsArea; } if (!bugInfo.description) { const descArea = $('.description, .bug-description, [name*="desc"]').text().trim(); if (descArea) bugInfo.description = descArea; } // 提取历史记录 bugInfo.history = []; $('.histories-list li').each((i, historyItem) => { const $item = $(historyItem); const historyText = $item.clone().children().remove().end().text().trim(); const comment = $item.find('.comment-content').text().trim(); if (historyText) { // 解析历史记录文本,提取时间、操作人、操作内容 const historyMatch = historyText.match(/^(\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}),\s*由\s*(.+?)\s*(.+)$/); const historyRecord = { rawText: historyText, comment: comment || null }; if (historyMatch) { historyRecord.time = historyMatch[1]; historyRecord.operator = historyMatch[2]; historyRecord.action = historyMatch[3]; } bugInfo.history.push(historyRecord); } }); return bugInfo; } catch (error) { return { error: error.message }; } }
- index.js:80-90 (schema)Defines the tool schema with name, description, and input schema requiring a 'bugId' string parameter.{ name: 'rdms_get_bug', description: 'Get bug details by ID with image extraction. Returns bug information including image URLs but NOT image content. If you need to analyze image content, use the rdms_download_image tool with the returned image URLs.', inputSchema: { type: 'object', properties: { bugId: { type: 'string', description: 'Bug ID' } }, required: ['bugId'] } },
- index.js:144-145 (registration)Registers the tool handler in the CallToolRequestSchema switch statement, mapping tool calls to the getBug method.case 'rdms_get_bug': return { content: [{ type: 'text', text: JSON.stringify(await this.getBug(args.bugId)) }] };
- index.js:79-90 (registration)Registers the tool in the ListToolsRequestSchema response, making it discoverable by MCP clients.tools: [ { name: 'rdms_get_bug', description: 'Get bug details by ID with image extraction. Returns bug information including image URLs but NOT image content. If you need to analyze image content, use the rdms_download_image tool with the returned image URLs.', inputSchema: { type: 'object', properties: { bugId: { type: 'string', description: 'Bug ID' } }, required: ['bugId'] } },
- index.js:213-219 (helper)Helper method called by getBug to ensure authentication before accessing RDMS data.async ensureLoggedIn() { if (!this.isLoggedIn && this.baseUrl && this.username && this.password) { await this.autoLogin(); } if (!this.isLoggedIn) { throw new Error('Not logged in. Please configure environment variables or use rdms_login tool.'); }