Description 835 -> 214 chars, body 669 -> 426 words, Gotchas 8 entries/63% of body -> 3/20.4%. Clears the description FAIL, all three Vale CompositionNote errors and both Gotchas suggestions. 63% was the worst Gotchas ratio in the corpus. Cut the composition sentence to README -- it changes no routing decision and an agent picks this skill because the user asked about labels, not because two other skills call it. Cut the capability enumeration; 'list, create, edit, delete' decompose 'reading or writing' and add no trigger. Boundary clauses are now one arrow per target. The resolver extracts only the first name per arrow clause, so the previous '-> gitea-issues / gitea-prs' left gitea-prs neither dangling nor checked while validate.sh reported 1 of 1. Now 2 of 2. Makes org-scoped label resolution executable. The org label pool was reachable in principle -- four *_org_label* methods, and a claim to own name-to-ID resolution -- but list_org_labels takes org, and Step 1 derived only owner and repo, so both resolution procedures stalled at the fallback. Fixed once at the identity step rather than per-procedure. get_user_orgs is outside allowed-tools, so the failing call is the discriminator: a failure means the owner is a user account with no org pool, which is an answer, not an error. Corrects a Gotcha that was false for create_repo_label/create_org_label and collided with the literal tool name label_write. Same false claim removed from README. Refs #99
3.2 KiB
name, description, compatibility, metadata, allowed-tools
| name | description | compatibility | metadata | allowed-tools | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| gitea-labels-milestones | Use when reading or writing Gitea labels or milestones — resolve names to IDs, or infer labels — even when the user does not say "Gitea". Not applying them to an issue -> `gitea-issues`. Not to a PR -> `gitea-prs`. | Requires Gitea MCP server configured with write:issue and write:repository token scopes. |
|
Bash mcp__gitea__label_read mcp__gitea__label_write mcp__gitea__milestone_read mcp__gitea__milestone_write |
Gotchas
- Applying a label takes a numeric ID, but issue/PR responses slim labels down to name strings. An issue's existing labels yield no IDs — resolve name → ID with
label_read. pull_request_readreturnsmilestoneas a bare title string whereissue_readreturns{id, title}— recover the milestone's ID by listing milestones and matching the title.Kind/*/Priority/*/Status/*exclusivity is a client-side convention.exclusiveis an org-labels-only flag, so applying a label in such a scope must replace the one already there, not stack on it.
Step 1 — Resolve owner, repo and org
Before any tool call, extract owner and repo from the git remote (skip this if an orchestrating caller already passed them in):
git remote get-url origin
If origin is not set or the URL is not a Gitea URL, stop and report: "No Gitea remote found — set origin to your Gitea instance URL."
The *_org_label* methods take org, not owner/repo. Pass that same owner as org — it is the org name whenever the owner is an organisation, and the remote URL does not say whether it is one. So let the call itself decide: a failure means the owner is a user account with no org label pool, which is an answer, not an error to report.
Step 2 — Dispatch
| Task | Tool | method |
|---|---|---|
| Resolve a label name to its ID | label_read |
"list_repo_labels", then "list_org_labels" |
| List repo labels | label_read |
"list_repo_labels" |
| Get one repo label by ID | label_read |
"get_repo_label" |
| List org labels | label_read |
"list_org_labels" |
| Create a repo/org label | label_write |
"create_repo_label" / "create_org_label" |
| Edit a repo/org label | label_write |
"edit_repo_label" / "edit_org_label" |
| Delete a repo/org label | label_write |
"delete_repo_label" / "delete_org_label" |
| List milestones | milestone_read |
"list" |
| Get one milestone by ID | milestone_read |
"get" |
| Create a milestone | milestone_write |
"create" |
| Update / close a milestone | milestone_write |
"update" |
| Delete a milestone | milestone_write |
"delete" |
Every list method paginates manually — per_page defaults to 30, so iterate page: 1, 2, ... until a page returns fewer results than per_page. A truncated list silently breaks name → ID resolution.
If the task is a label operation, read references/labels.md; if a milestone operation, read references/milestones.md. If the label to apply has to be derived from conversation context rather than named, read references/label-inference.md.