Skip to main content
Glama

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
NameRequiredDescriptionDefault
bugIdYesBug ID

Implementation Reference

  • 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 };
      }
    }
  • 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']
        }
      },
  • 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.');
      }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and effectively discloses key behavioral traits: it's a read operation (implied by 'Get'), returns bug information including image URLs but not image content, and has a clear workflow dependency (use rdms_download_image for image analysis). It doesn't mention permissions, rate limits, or error handling, but covers the core behavior well for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly concise and front-loaded: the first sentence states the core purpose and key limitation, the second provides critical usage guidance. Every sentence earns its place with zero wasted words, making it highly efficient for an AI agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (single parameter, read-only operation), no annotations, and no output schema, the description is quite complete: it explains what the tool does, what it returns, its limitations, and how to handle those limitations. The main gap is the lack of output format details, but for a simple getter tool, this is acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100% (bugId parameter is fully documented in the schema), so the baseline is 3. The description doesn't add any parameter-specific details beyond what the schema provides (e.g., format examples or constraints), but it doesn't need to since the schema already covers it adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('Get bug details by ID') and resource ('bug'), distinguishing it from siblings by specifying it returns bug information with image URLs but not image content. It explicitly contrasts with rdms_download_image for image analysis needs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool (to get bug details with image URLs) and when not to use it (if you need to analyze image content), naming the alternative tool (rdms_download_image) and specifying the condition for using it (with returned image URLs).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/ad19900913/mcp-rdms'

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