Files
holocron/plugins/gitea/skills/gitea-issues/references/issues.md
Defame1297 dd1981db80 fix(gitea-issues): list_issues does have type and milestones on v1.7.0
SKILL.md's headline Gotcha said `list_issues` "has no `type` filter", and
references/issues.md stated in bold that neither `type` nor `milestones`
exists, "despite both appearing in api-reference.md". Both parameters are
present on the deployed gitea-mcp v1.7.0 and both work: `type: "issues"`
returns only issues, `type: "pulls"` only PRs, and `milestones` filters by
name. Unfiltered, the same window returns them interleaved, so the mixing
the Gotcha describes is real — only the stated remedy was wrong.

This mattered most in gitea-workflow's no-args check-in, which lists open
issues through this skill and so reported PRs under "Open Issues" while
the skill forbade the one-parameter fix. The list flow now passes
`type: "issues"`.

references/sources.md recorded the absence as a live-verification win over
stale research docs; it now records that the earlier check was superseded
by v1.7.0, since drift runs in both directions. gitea-prs cited the same
parameter as its canonical drift example and no longer does — no
replacement example was substituted, because the obvious candidate was not
verified in this pass.

Also defaults label writes to `add_labels`: `replace_labels` clears every
label not in the array, and per-label exclusivity makes blanket replacement
destructive for a non-exclusive scope.

Verified live against gitea-mcp v1.7.0, read-only calls.

Refs #99
2026-08-30 20:51:02 +00:00

6.1 KiB

topic, source_keys
topic source_keys
issues
gitea-mcp-repo
gitea-mcp-slim-go

Issue operations

Call signatures below were verified live against the deployed gitea-mcp server via ToolSearch, not copied from api-reference.md — this is deliberate: research docs are generated from source at a point in time and can drift from the server actually deployed. Last verified against gitea-mcp v1.7.0, as reported by get_gitea_mcp_server_version. Drift runs in both directions: this file previously recorded list_issues as having neither a type nor a milestones parameter, and v1.7.0 has both. Re-verify against the live schema if these tools appear to behave differently than documented here.

list_issues

Parameters (live schema):

  • owner (string, required)
  • repo (string, required)
  • state (string, optional, default "all") — conventional values "open"/"closed"/"all", not schema-enforced as an enum
  • labels (array of strings, optional) — filter by label name (not ID)
  • milestones (array of strings, optional) — filter by milestone name or numeric ID, both passed as strings
  • type (string, enum "issues" | "pulls", optional) — omit it and the response mixes both
  • since (string, optional) — ISO 8601, issues updated after this time
  • before (string, optional) — ISO 8601, issues updated before this time
  • page (number, optional, default 1)
  • per_page (number, optional, default 30)

Pass type: "issues" on any listing meant to show issues. Issues and PRs share one repo number space and the unfiltered response interleaves them; the only thing distinguishing them on a list item is the html_url path segment (/issues/ vs /pulls/), since is_pull is not returned on list items — see the Gotchas section of SKILL.md.

Call:

list_issues owner: <owner> repo: <repo> state: "open" type: "issues"

Response (list item): number, title, state, html_url, user, comments, created_at, updated_at, and optionally labels ([]string), milestone ({id, title}), ref, deadline. Body and closed_at are omitted from list responses — call issue_read method: "get" for those.

Paginate with page/per_page until the returned count is less than per_page.

issue_read

Parameters (live schema, matches api-reference.md):

  • method (string, required, enum) — "get" | "get_comments" | "get_labels"
  • owner (string, required)
  • repo (string, required)
  • issue_number (number, required)

get — full issue: number, title, body, state, html_url, user, labels ([]string), comments, created_at, updated_at, closed_at, and optionally assignees ([]string), milestone ({id, title}), ref, deadline, is_pull (present only when this number is backed by a pull request — absent, not false, on true issues).

get_comments — array of {id, body, user, html_url, created_at, updated_at}.

get_labels — array of full label objects (id, name, color, description — not slimmed to name strings, unlike the labels array on get).

Call:

issue_read method: "get" owner: <owner> repo: <repo> issue_number: <N>

Always check is_pull before treating a number as a plain issue — see the shared number-space gotcha in SKILL.md.

issue_write

Parameters (live schema, matches api-reference.md):

  • method (string, required, enum) — "create" | "update" | "add_comment" | "edit_comment" | "add_labels" | "remove_label" | "replace_labels" | "clear_labels"
  • owner (string, required)
  • repo (string, required)
  • issue_number (number, required for every method except "create")
  • title (string, required for "create")
  • body (string, required for "create", "add_comment", "edit_comment")
  • assignees (array of strings, optional) — login names (see references/enrichments.md for why this is usually omitted)
  • milestone (number, optional) — milestone ID, never a title
  • state (string, enum "open"/"closed"/"all", optional) — for "update"
  • commentID (number, optional, required for "edit_comment")
  • labels (array of numbers, optional) — label IDs, never names — for add_labels/replace_labels
  • label_id (number, optional, required for "remove_label") — singular, not the array form
  • ref (string, optional) — branch association, informational only
  • deadline (string, optional) — ISO 8601
  • remove_deadline (boolean, optional)

Create:

issue_write method: "create"
  owner: <owner> repo: <repo>
  title: <title> body: <body>
  labels: [<resolved IDs>]        ← omit if none confidently inferred
  milestone: <resolved ID>        ← omit if none clearly fits
  assignees: ["<login>"]          ← omit if no default configured

Close:

issue_write method: "update" owner: <owner> repo: <repo> issue_number: <N> state: "closed"

There is no method: "close" — using one will error.

Comment:

issue_write method: "add_comment" owner: <owner> repo: <repo> issue_number: <N> body: <text>

Apply resolved label IDs directly (bypassing references/enrichments.md's inference step, e.g. when the caller already named exact labels):

issue_write method: "add_labels" owner: <owner> repo: <repo> issue_number: <N> labels: [<IDs>]

To replace all labels atomically instead of adding: method: "replace_labels". To remove one: method: "remove_label" label_id: <single ID>.

Default to add_labels. replace_labels clears every label not in the array, so it drops labels the caller never mentioned. Reach for it only when the caller asked for the issue's label set to become exactly what they listed. In particular, do not use it to enforce one-label-per-scope: exclusivity is a per-label property — the server drops the sibling itself for a label whose exclusive field is true, and a label whose exclusive is false (every Kind/* on this instance) is legitimately stackable. See gitea-labels-milestones for how to read that field.

Token scope

All of list_issues, issue_read, and issue_write are verified working under a token holding write:issue + write:repository.