Files
holocron/plugins/gitea/skills/gitea-issues/references/issues.md
Defame1297 6cfc3577e2 docs: trim repeated boilerplate in git, gitea, and bin skills
Finding 13: five blocks of near-identical wording were repeated across
skills within a plugin — the gitea "resolve owner and repo" step (5
skills), the 404-masks-403 note (6 files), the manual pagination
explanation (8 files), the git plugin's main/master force-push refusal
(7 files, some with multiple internal restatements), and the bin
skills' domain-glossary/ADR paragraph (5 skills). Tightened each
instance in place — same meaning, fewer words — rather than extracting
to a shared file, which ADR-0014's one-file-per-skill install
constraint rules out. Left the three git skills' structured-result
JSON shapes alone (coupled to the separate, out-of-scope git-orchestrate
merge candidate, finding 19).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YR2CjVumUbEGWcMikcoXBD
2026-09-12 19:48:31 +00:00

137 lines
6.1 KiB
Markdown

---
topic: issues
source_keys:
- 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:**
```text
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: `page`/`per_page`, stop once the count is below `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:**
```text
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:**
```text
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:**
```text
issue_write method: "update" owner: <owner> repo: <repo> issue_number: <N> state: "closed"
```
No `method: "close"` exists — using one errors.
**Comment:**
```text
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):
```text
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`.