Skip to main content
Glama
snowild

Redmine MCP Server

by snowild

search_issues

Find Redmine issues by searching keywords in titles or descriptions, with optional filtering by project and result limits.

Instructions

搜尋議題 (在標題或描述中搜尋關鍵字)

Args:
    query: 搜尋關鍵字
    project_id: 限制在特定專案中搜尋 (可選)
    limit: 最大回傳數量 (預設 10,最大 50)

Returns:
    符合搜尋條件的議題列表

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
project_idNo
limitNo

Implementation Reference

  • The core implementation of the 'search_issues' MCP tool. This function is decorated with @mcp.tool(), handles the tool execution by querying Redmine issues via the API, performing local keyword filtering on title and description, and returning a formatted table of matching issues.
    @mcp.tool()
    def search_issues(query: str, project_id: int = None, limit: int = 10) -> str:
        """
        搜尋議題 (在標題或描述中搜尋關鍵字)
        
        Args:
            query: 搜尋關鍵字
            project_id: 限制在特定專案中搜尋 (可選)
            limit: 最大回傳數量 (預設 10,最大 50)
        
        Returns:
            符合搜尋條件的議題列表
        """
        try:
            if not query.strip():
                return "請提供搜尋關鍵字"
            
            client = get_client()
            limit = min(max(limit, 1), 50)
            
            # 設定搜尋參數
            params = {
                'limit': limit * 3,  # 取得更多結果以便篩選
                'sort': 'updated_on:desc'
            }
            
            if project_id:
                params['project_id'] = project_id
            
            # 取得議題列表
            all_issues = client.list_issues(**params)
            
            # 在本地端進行關鍵字篩選 (因為 Redmine API 沒有內建搜尋)
            query_lower = query.lower()
            matching_issues = []
            
            for issue in all_issues:
                if (query_lower in issue.subject.lower() or 
                    (issue.description and query_lower in issue.description.lower())):
                    matching_issues.append(issue)
                    if len(matching_issues) >= limit:
                        break
            
            if not matching_issues:
                search_scope = f"專案 {project_id}" if project_id else "所有可存取的專案"
                return f"在 {search_scope} 中沒有找到包含 '{query}' 的議題"
            
            # 格式化結果
            result = f"搜尋關鍵字: '{query}'\n"
            if project_id:
                result += f"搜尋範圍: 專案 {project_id}\n"
            result += f"找到 {len(matching_issues)} 個相關議題:\n\n"
            
            result += f"{'ID':<8} {'標題':<35} {'狀態':<12} {'專案':<15}\n"
            result += f"{'-'*8} {'-'*35} {'-'*12} {'-'*15}\n"
            
            for issue in matching_issues:
                title = issue.subject[:32] + "..." if len(issue.subject) > 35 else issue.subject
                status = issue.status.get('name', 'N/A')[:10]
                project_name = issue.project.get('name', 'N/A')[:13]
                
                result += f"{issue.id:<8} {title:<35} {status:<12} {project_name:<15}\n"
            
            return result
            
        except RedmineAPIError as e:
            return f"搜尋議題失敗: {str(e)}"
        except Exception as e:
            return f"系統錯誤: {str(e)}"
  • The @mcp.tool() decorator registers the search_issues function as an MCP tool, automatically exposing it to the MCP server with the name derived from the function name.
    @mcp.tool()
  • Input schema defined by type annotations (query: str required, project_id: int optional default None, limit: int optional default 10) and output str. Docstring provides detailed parameter descriptions.
    def search_issues(query: str, project_id: int = None, limit: int = 10) -> str:
        """
        搜尋議題 (在標題或描述中搜尋關鍵字)
        
        Args:
            query: 搜尋關鍵字
            project_id: 限制在特定專案中搜尋 (可選)
            limit: 最大回傳數量 (預設 10,最大 50)
        
        Returns:
            符合搜尋條件的議題列表
        """

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/snowild/redmine-mcp'

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