feat: add user-related API endpoints and enhance issue participant retrieval

This commit is contained in:
sha
2026-03-25 11:52:28 +02:00
parent b60bf841f4
commit 9d343b64db
4 changed files with 241 additions and 2 deletions
+65
View File
@@ -39,3 +39,68 @@ def assign_issue(issue_id: int, assigned_to_id: int, comment: str = "") -> str:
body["issue"]["notes"] = comment
_put(f"/issues/{issue_id}.json", body)
return f"Issue #{issue_id} assigned to user_id={assigned_to_id}."
@mcp.tool()
def unassign_issue(issue_id: int, comment: str = "") -> str:
"""
Remove the assignee from a Redmine issue (set to unassigned).
Args:
issue_id: Redmine issue ID
comment: Optional comment to add with the change
"""
body: dict = {"issue": {"assigned_to_id": ""}}
if comment:
body["issue"]["notes"] = comment
_put(f"/issues/{issue_id}.json", body)
return f"Issue #{issue_id} unassigned."
@mcp.tool()
def get_issue_participants(issue_id: int) -> str:
"""
Get all users who have participated in a Redmine issue:
author, current assignee, watchers, commenters, and editors.
Useful for understanding who works with a task and who wrote comments.
Each participant includes their roles (author, assignee, watcher,
commenter, editor) based on actual actions recorded in the issue history.
Args:
issue_id: Redmine issue ID
"""
data = _get(f"/issues/{issue_id}.json", params={"include": "journals,watchers"})
issue = data["issue"]
participants: dict[int, dict] = {}
def _add(uid: int, uname: str, role: str) -> None:
if uid not in participants:
participants[uid] = {"id": uid, "name": uname, "roles": []}
if role not in participants[uid]["roles"]:
participants[uid]["roles"].append(role)
author = issue.get("author", {})
if author.get("id"):
_add(author["id"], author["name"], "author")
assignee = issue.get("assigned_to", {})
if assignee.get("id"):
_add(assignee["id"], assignee["name"], "assignee")
for w in issue.get("watchers", []):
if w.get("id"):
_add(w["id"], w["name"], "watcher")
for j in issue.get("journals", []):
user = j.get("user", {})
uid = user.get("id")
uname = user.get("name", "?")
if uid:
if j.get("notes"):
_add(uid, uname, "commenter")
if j.get("details"):
_add(uid, uname, "editor")
return json.dumps(list(participants.values()), ensure_ascii=False, indent=2)