update_issue_status
Update the status of a Redmine issue by specifying the issue ID and either a new status ID or name. Optionally add notes to document changes. Returns the update result message.
Instructions
更新議題狀態
Args:
issue_id: 議題 ID
status_id: 新的狀態 ID(與 status_name 二選一)
status_name: 新的狀態名稱(與 status_id 二選一)
notes: 更新備註(可選)
Returns:
更新結果訊息
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| issue_id | Yes | ||
| notes | No | ||
| status_id | No | ||
| status_name | No |
Input Schema (JSON Schema)
{
"properties": {
"issue_id": {
"title": "Issue Id",
"type": "integer"
},
"notes": {
"default": "",
"title": "Notes",
"type": "string"
},
"status_id": {
"default": null,
"title": "Status Id",
"type": "integer"
},
"status_name": {
"default": null,
"title": "Status Name",
"type": "string"
}
},
"required": [
"issue_id"
],
"title": "update_issue_statusArguments",
"type": "object"
}
Implementation Reference
- src/redmine_mcp/server.py:135-187 (handler)Core handler function for the 'update_issue_status' tool. Decorated with @mcp.tool() for automatic registration and schema inference from type hints and docstring. Implements logic to resolve status by ID or name, update the issue, and return formatted response.@mcp.tool() def update_issue_status(issue_id: int, status_id: int = None, status_name: str = None, notes: str = "") -> str: """ 更新議題狀態 Args: issue_id: 議題 ID status_id: 新的狀態 ID(與 status_name 二選一) status_name: 新的狀態名稱(與 status_id 二選一) notes: 更新備註(可選) Returns: 更新結果訊息 """ try: client = get_client() # 處理狀態參數 final_status_id = status_id if status_name: final_status_id = client.find_status_id_by_name(status_name) if not final_status_id: return f"找不到狀態名稱:「{status_name}」\n\n可用狀態:\n" + "\n".join([f"- {name}" for name in client.get_available_statuses().keys()]) if not final_status_id: return "錯誤:必須提供 status_id 或 status_name 其中一個參數" # 準備更新資料 update_data = {'status_id': final_status_id} if notes.strip(): update_data['notes'] = notes.strip() # 執行更新 client.update_issue(issue_id, **update_data) # 取得更新後的議題資訊確認 updated_issue = client.get_issue(issue_id) result = f"""議題狀態更新成功! 議題: #{issue_id} - {updated_issue.subject} 新狀態: {updated_issue.status.get('name', 'N/A')}""" if notes.strip(): result += f"\n備註: {notes}" return result except RedmineAPIError as e: return f"更新議題狀態失敗: {str(e)}" except Exception as e: return f"系統錯誤: {str(e)}"
- Helper method to resolve status name to ID using cached enumerations, called when status_name is provided.def find_status_id_by_name(self, name: str) -> Optional[int]: """根據狀態名稱找到對應的 ID""" cache = self._load_enum_cache() return cache.get('statuses', {}).get(name)
- Core API update method that performs the PUT request to Redmine to update issue status and optional notes.def update_issue(self, issue_id: int, **kwargs) -> bool: """更新議題""" update_data = {'issue': {}} # 支援的更新欄位 if 'subject' in kwargs: update_data['issue']['subject'] = kwargs['subject'] if 'description' in kwargs: update_data['issue']['description'] = kwargs['description'] if 'status_id' in kwargs: update_data['issue']['status_id'] = kwargs['status_id'] if 'priority_id' in kwargs: update_data['issue']['priority_id'] = kwargs['priority_id'] if 'assigned_to_id' in kwargs: update_data['issue']['assigned_to_id'] = kwargs['assigned_to_id'] if 'done_ratio' in kwargs: update_data['issue']['done_ratio'] = kwargs['done_ratio'] if 'tracker_id' in kwargs: update_data['issue']['tracker_id'] = kwargs['tracker_id'] if 'parent_issue_id' in kwargs: # 如果 parent_issue_id 為 None,則移除父議題關係 if kwargs['parent_issue_id'] is None: update_data['issue']['parent_issue_id'] = "" else: update_data['issue']['parent_issue_id'] = kwargs['parent_issue_id'] if 'start_date' in kwargs: update_data['issue']['start_date'] = kwargs['start_date'] if 'due_date' in kwargs: update_data['issue']['due_date'] = kwargs['due_date'] if 'estimated_hours' in kwargs: update_data['issue']['estimated_hours'] = kwargs['estimated_hours'] if 'notes' in kwargs: update_data['issue']['notes'] = kwargs['notes'] if not update_data['issue']: raise RedmineAPIError("沒有提供要更新的欄位") self._make_request('PUT', f'/issues/{issue_id}.json', json=update_data) return True
- Fetches the updated issue details after status update for confirmation in the response message.def get_issue(self, issue_id: int, include: Optional[List[str]] = None) -> RedmineIssue: """取得單一議題""" params = {} if include: params['include'] = ','.join(include) response = self._make_request('GET', f'/issues/{issue_id}.json', params=params) if 'issue' not in response: raise RedmineAPIError(f"議題 {issue_id} 不存在") issue_data = response['issue'] return RedmineIssue( id=issue_data['id'], subject=issue_data['subject'], description=issue_data.get('description', ''), status=issue_data['status'], priority=issue_data['priority'], project=issue_data['project'], tracker=issue_data['tracker'], author=issue_data['author'], assigned_to=issue_data.get('assigned_to'), created_on=issue_data.get('created_on'), updated_on=issue_data.get('updated_on'), done_ratio=issue_data.get('done_ratio', 0) )
- Provides list of available statuses for error message when status_name not found.def get_available_statuses(self) -> Dict[str, int]: """取得所有可用的狀態選項(名稱到ID的對應)""" cache = self._load_enum_cache() return cache.get('statuses', {})