package tools import ( "context" "encoding/json" "gitea.d-ma.be/mathias/gitea-mcp/internal/allowlist" "gitea.d-ma.be/mathias/gitea-mcp/internal/gitea" "gitea.d-ma.be/mathias/gitea-mcp/internal/registry" ) type IssueList struct { c *gitea.Client a *allowlist.Allowlist } func NewIssueList(c *gitea.Client, a *allowlist.Allowlist) *IssueList { return &IssueList{c: c, a: a} } func (t *IssueList) Descriptor() registry.ToolDescriptor { return registry.ToolDescriptor{ Name: "issue_list", Description: "List issues in a repo with optional filters. PRs are excluded (use pr_list for those).", InputSchema: json.RawMessage(`{ "type":"object", "properties":{ "owner":{"type":"string"}, "name":{"type":"string"}, "state":{"type":"string","enum":["open","closed","all"]}, "labels":{"type":"string"}, "since":{"type":"string"}, "page":{"type":"integer","minimum":1}, "limit":{"type":"integer","minimum":1,"maximum":50} }, "required":["owner","name"] }`), } } type issueListArgs struct { Owner string `json:"owner"` Name string `json:"name"` State string `json:"state"` Labels string `json:"labels"` Since string `json:"since"` Page int `json:"page"` Limit int `json:"limit"` } func (t *IssueList) Call(ctx context.Context, raw json.RawMessage) (json.RawMessage, error) { var args issueListArgs if err := parseArgs(raw, &args); err != nil { return nil, err } if err := t.a.Check(args.Owner); err != nil { return nil, err } if args.State == "" { args.State = "open" } args.Limit = capLimit(args.Limit, 30) if args.Page < 1 { args.Page = 1 } issues, err := t.c.ListIssues(ctx, args.Owner, args.Name, gitea.ListIssuesArgs{ State: args.State, Labels: args.Labels, Since: args.Since, Page: args.Page, Limit: args.Limit, }) if err != nil { return nil, err } out := map[string]any{ "issues": issues, } if len(issues) == args.Limit { out["next_page"] = args.Page + 1 } return textOK(out) }