Add missing ref and deadline fields to issue responses (#169)

## Summary

### Read (issue responses)
- Add `ref` (branch) field to issue responses when non-empty
- Add `deadline` (due_date) field to issue responses when non-nil
- Applied to `slimIssue()`, `slimIssues()` in `operation/issue/slim.go` and `slimIssues()` in `operation/search/slim.go`

### Write (issue_write)
- Add `ref` parameter to `issue_write` tool for both `create` and `update` methods
- Allows setting the branch reference on issues via the MCP, consistent with the SDK's `CreateIssueOption.Ref` and `EditIssueOption.Ref` fields

Fixes #168

## Test plan
- [ ] `go test ./...` passes
- [ ] Verify `issue_read` returns `ref` when a branch is assigned to an issue
- [ ] Verify `issue_read` returns `deadline` when a due date is set
- [ ] Verify `list_issues` and `search_issues` include these fields
- [ ] Verify `issue_write` with method `update` can set `ref` on an issue
- [ ] Verify `issue_write` with method `create` can set `ref` on a new issue

Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/169
Reviewed-by: silverwind <2021+silverwind@noreply.gitea.com>
Co-authored-by: pengu <jeremy@wenjy.fr>
Co-committed-by: pengu <jeremy@wenjy.fr>
This commit is contained in:
pengu
2026-03-26 18:37:57 +00:00
committed by silverwind
parent 05682e2afa
commit 133fe487cd
3 changed files with 25 additions and 0 deletions

View File

@@ -61,6 +61,7 @@ var (
mcp.WithNumber("commentID", mcp.Description("id of issue comment (required for 'edit_comment')")), mcp.WithNumber("commentID", mcp.Description("id of issue comment (required for 'edit_comment')")),
mcp.WithArray("labels", mcp.Description("array of label IDs (for 'create', 'add_labels', 'replace_labels')"), mcp.Items(map[string]any{"type": "number"})), mcp.WithArray("labels", mcp.Description("array of label IDs (for 'create', 'add_labels', 'replace_labels')"), mcp.Items(map[string]any{"type": "number"})),
mcp.WithNumber("label_id", mcp.Description("label ID to remove (required for 'remove_label')")), mcp.WithNumber("label_id", mcp.Description("label ID to remove (required for 'remove_label')")),
mcp.WithString("ref", mcp.Description("branch name to associate with the issue (for 'create', 'update')")),
mcp.WithString("deadline", mcp.Description("due date in ISO 8601 format (for 'create', 'update')")), mcp.WithString("deadline", mcp.Description("due date in ISO 8601 format (for 'create', 'update')")),
mcp.WithBoolean("remove_deadline", mcp.Description("unset due date (for 'update')")), mcp.WithBoolean("remove_deadline", mcp.Description("unset due date (for 'update')")),
) )
@@ -229,6 +230,9 @@ func createIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolR
if labelIDs, err := params.GetInt64Slice(req.GetArguments(), "labels"); err == nil { if labelIDs, err := params.GetInt64Slice(req.GetArguments(), "labels"); err == nil {
opt.Labels = labelIDs opt.Labels = labelIDs
} }
if ref, ok := req.GetArguments()["ref"].(string); ok {
opt.Ref = ref
}
opt.Deadline = params.GetOptionalTime(req.GetArguments(), "deadline") opt.Deadline = params.GetOptionalTime(req.GetArguments(), "deadline")
issue, _, err := client.CreateIssue(owner, repo, opt) issue, _, err := client.CreateIssue(owner, repo, opt)
if err != nil { if err != nil {
@@ -306,6 +310,9 @@ func editIssueFn(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolRes
if ok { if ok {
opt.State = new(gitea_sdk.StateType(state)) opt.State = new(gitea_sdk.StateType(state))
} }
if ref, ok := req.GetArguments()["ref"].(string); ok {
opt.Ref = &ref
}
opt.Deadline = params.GetOptionalTime(req.GetArguments(), "deadline") opt.Deadline = params.GetOptionalTime(req.GetArguments(), "deadline")
if removeDeadline, ok := req.GetArguments()["remove_deadline"].(bool); ok { if removeDeadline, ok := req.GetArguments()["remove_deadline"].(bool); ok {
opt.RemoveDeadline = &removeDeadline opt.RemoveDeadline = &removeDeadline

View File

@@ -63,6 +63,12 @@ func slimIssue(i *gitea_sdk.Issue) map[string]any {
"title": i.Milestone.Title, "title": i.Milestone.Title,
} }
} }
if i.Ref != "" {
m["ref"] = i.Ref
}
if i.Deadline != nil {
m["deadline"] = i.Deadline
}
if i.PullRequest != nil { if i.PullRequest != nil {
m["is_pull"] = true m["is_pull"] = true
} }
@@ -88,6 +94,12 @@ func slimIssues(issues []*gitea_sdk.Issue) []map[string]any {
if len(i.Labels) > 0 { if len(i.Labels) > 0 {
m["labels"] = labelNames(i.Labels) m["labels"] = labelNames(i.Labels)
} }
if i.Ref != "" {
m["ref"] = i.Ref
}
if i.Deadline != nil {
m["deadline"] = i.Deadline
}
out = append(out, m) out = append(out, m)
} }
return out return out

View File

@@ -129,6 +129,12 @@ func slimIssues(issues []*gitea_sdk.Issue) []map[string]any {
if i.Repository != nil { if i.Repository != nil {
m["repository"] = i.Repository.FullName m["repository"] = i.Repository.FullName
} }
if i.Ref != "" {
m["ref"] = i.Ref
}
if i.Deadline != nil {
m["deadline"] = i.Deadline
}
if i.PullRequest != nil { if i.PullRequest != nil {
m["is_pull"] = true m["is_pull"] = true
} }