feat(gitea): add gitea-branches skill (branches + commits)
Adds plugins/gitea/skills/gitea-branches/ per ADR 0011, covering list_branches/create_branch/delete_branch (migrated from the flat plugins/bin/skills/gitea/ dispatch) plus list_commits/get_commit (new read-only commit-history domain). Call signatures were re-verified live via ToolSearch against the deployed gitea-mcp server rather than copied from api-reference.md, per issue #6 comment #849's root-cause fix. Bumps the gitea plugin to 1.1.0 in both manifests for the new skill.
This commit is contained in:
@@ -10,9 +10,10 @@
|
|||||||
"issues",
|
"issues",
|
||||||
"prs",
|
"prs",
|
||||||
"milestones",
|
"milestones",
|
||||||
"releases"
|
"releases",
|
||||||
|
"branches"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"name": "gitea",
|
"name": "gitea",
|
||||||
"version": "1.0.0"
|
"version": "1.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@
|
|||||||
"issues",
|
"issues",
|
||||||
"prs",
|
"prs",
|
||||||
"milestones",
|
"milestones",
|
||||||
"releases"
|
"releases",
|
||||||
|
"branches"
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"mcpServers": ".mcp.json",
|
"mcpServers": ".mcp.json",
|
||||||
@@ -19,5 +20,5 @@
|
|||||||
"skills": [
|
"skills": [
|
||||||
"skills/"
|
"skills/"
|
||||||
],
|
],
|
||||||
"version": "1.0.0"
|
"version": "1.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
35
plugins/gitea/skills/gitea-branches/README.md
Normal file
35
plugins/gitea/skills/gitea-branches/README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# gitea-branches
|
||||||
|
|
||||||
|
Manage Gitea repository branches and inspect commit history via the Gitea MCP server.
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
This skill handles branch lifecycle operations (list, create, delete) and read-only commit
|
||||||
|
history (list commits, get a single commit's full detail) against a Gitea repository. It resolves
|
||||||
|
`owner`/`repo` from the git remote, dispatches to the right MCP tool, and applies safety and
|
||||||
|
pagination conventions specific to Gitea's API (e.g. refusing to delete a protected branch without
|
||||||
|
explicit confirmation, and treating unexpected 404s as possible masked 403s).
|
||||||
|
|
||||||
|
## Before you start
|
||||||
|
|
||||||
|
Requires a Gitea MCP server configured with a token. `list_branches`, `list_commits`, and
|
||||||
|
`get_commit` work with `write:issue` alone; `create_branch` and `delete_branch` need
|
||||||
|
`write:repository`. Requires a git remote named `origin` pointing at the Gitea instance.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
/gitea-branches
|
||||||
|
```
|
||||||
|
|
||||||
|
Describe your task: list/create/delete a branch, or list/inspect commits. See `SKILL.md`'s
|
||||||
|
dispatch table for the full set of recognized invocations.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `SKILL.md` | Skill instructions for agents — dispatch table, gotchas |
|
||||||
|
| `references/branches.md` | Verified call signatures and mechanics for list/create/delete branch |
|
||||||
|
| `references/commits.md` | Verified call signatures and mechanics for list/get commit |
|
||||||
|
| `references/sources.md` | Research sources backing the branch/commit guidance |
|
||||||
65
plugins/gitea/skills/gitea-branches/SKILL.md
Normal file
65
plugins/gitea/skills/gitea-branches/SKILL.md
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
name: gitea-branches
|
||||||
|
|
||||||
|
description: >
|
||||||
|
Use when managing Gitea repository branches — listing, creating, or deleting
|
||||||
|
branches — or inspecting commit history within a Gitea repo: listing commits
|
||||||
|
(optionally filtered by branch or file path) or getting full detail for a
|
||||||
|
single commit by SHA. Triggers on "list branches", "create a branch",
|
||||||
|
"delete a branch", "what commits are on this branch", "show commit <sha>",
|
||||||
|
"what changed in that commit" — even if the user doesn't say "Gitea"
|
||||||
|
explicitly, as long as the repo's remote is a Gitea instance. Do not use for
|
||||||
|
local git branch/commit operations on your working copy (use git-branches or
|
||||||
|
git-history) or for PR-side branch references like cross-repo fork PR heads
|
||||||
|
(use gitea-prs).
|
||||||
|
|
||||||
|
compatibility: Requires Gitea MCP server configured with a token; list_branches, list_commits, and get_commit work with write:issue alone, create_branch and delete_branch require write:repository. Requires git remote "origin" pointing to the Gitea instance.
|
||||||
|
|
||||||
|
metadata:
|
||||||
|
category: integration
|
||||||
|
version: "0.1.0"
|
||||||
|
source_keys:
|
||||||
|
- gitea-mcp-repo
|
||||||
|
- gitea-mcp-slim-go
|
||||||
|
|
||||||
|
allowed-tools: Bash mcp__gitea__list_branches mcp__gitea__create_branch mcp__gitea__delete_branch mcp__gitea__list_commits mcp__gitea__get_commit
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gotchas
|
||||||
|
|
||||||
|
- **Never delete a protected branch (`main`/`master` by name, or `protected: true` from `list_branches`) without explicit confirmation.** `delete_branch` is a direct API call, not a local `git push` — there is no client-side force-push guard protecting it. Name-matching `main`/`master` is a convenient default but not authoritative — a repo can protect a differently-named default branch. When in doubt, call `list_branches` first and check `protected` on the target; treat deletion of any protected branch as a hard refusal unless the user explicitly confirms in the conversation.
|
||||||
|
- **404 may actually mean 403.** Gitea hides permission errors as not-found to avoid leaking resource existence. If any of these five tools returns 404 unexpectedly, check token scope (see `references/branches.md` / `references/commits.md`) before concluding the branch or commit doesn't exist.
|
||||||
|
- **Pagination is manual.** `list_branches` and `list_commits` return one page at a time — no auto-pagination in the MCP layer. When you need a complete list, iterate `page: 1, 2, ...` until the returned count is less than `per_page`.
|
||||||
|
- **Owner/repo always come from the git remote, never from `get_me`.** Resolve them via `git remote get-url origin` (Step 1 below). `get_me`/`list_my_repos` are blocked under the token scopes this skill assumes.
|
||||||
|
- **`create_branch`'s source is `old_branch`, not "wherever gitea-mcp feels like."** Omitting `old_branch` forks from the repo's server-side default branch — not necessarily the branch you're currently working on locally. If you want to branch from your current checkout, pass `old_branch` explicitly.
|
||||||
|
|
||||||
|
## Step 1 — Resolve owner and repo
|
||||||
|
|
||||||
|
Before any tool call, extract `owner` and `repo` from the git remote:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
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."
|
||||||
|
|
||||||
|
## Step 2 — Dispatch
|
||||||
|
|
||||||
|
| Invocation | Action |
|
||||||
|
|---|---|
|
||||||
|
| `/gitea-branches` or `/gitea-branches list` | List branches |
|
||||||
|
| `/gitea-branches create <name> [from <base>]` | Create branch |
|
||||||
|
| `/gitea-branches delete <name>` | Delete branch |
|
||||||
|
| `/gitea-branches commits [on <branch>] [touching <path>]` | List commit history |
|
||||||
|
| `/gitea-branches commit <sha>` | Get full detail for one commit |
|
||||||
|
|
||||||
|
For branch operations (list/create/delete), read `references/branches.md`.
|
||||||
|
For commit operations (list/get), read `references/commits.md`.
|
||||||
|
|
||||||
|
## Step 3 — Report
|
||||||
|
|
||||||
|
For reads: display branches as name + protected flag; display commits as SHA (short), message summary, author, date.
|
||||||
|
|
||||||
|
For writes (create/delete): confirm the action taken, the branch name, and (for create) the base it forked from.
|
||||||
|
|
||||||
|
For errors: surface the HTTP code and message. If a 404 is unexpected, re-check token scope per the Gotchas above before reporting "not found" to the user.
|
||||||
78
plugins/gitea/skills/gitea-branches/references/branches.md
Normal file
78
plugins/gitea/skills/gitea-branches/references/branches.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
topic: branches
|
||||||
|
source_keys:
|
||||||
|
- gitea-mcp-repo
|
||||||
|
- gitea-mcp-slim-go
|
||||||
|
---
|
||||||
|
|
||||||
|
# Branch operations
|
||||||
|
|
||||||
|
Call signatures below were verified live against the deployed `gitea-mcp` server via `ToolSearch`
|
||||||
|
at authoring time, not copied from research docs — this is deliberate: research docs are generated
|
||||||
|
from source code at a point in time and can drift from the server actually deployed. Re-verify
|
||||||
|
against the live schema if these tools appear to behave differently than documented here.
|
||||||
|
|
||||||
|
## `list_branches`
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `owner` (string, required)
|
||||||
|
- `repo` (string, required)
|
||||||
|
- `page` (number, optional, default: `1`)
|
||||||
|
- `per_page` (number, optional, default: `30`)
|
||||||
|
|
||||||
|
**Call:**
|
||||||
|
```
|
||||||
|
list_branches owner: <owner> repo: <repo>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:** one object per branch: `name`, `protected` (bool), `commit_sha` (present when the
|
||||||
|
underlying commit data is available).
|
||||||
|
|
||||||
|
Paginate if you need the full list (see Gotchas in SKILL.md) — iterate `page` until the returned
|
||||||
|
count is less than `per_page`.
|
||||||
|
|
||||||
|
## `create_branch`
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `owner` (string, required)
|
||||||
|
- `repo` (string, required)
|
||||||
|
- `branch` (string, required) — new branch name
|
||||||
|
- `old_branch` (string, optional) — source branch; if omitted, defaults to the repo's default
|
||||||
|
branch server-side (not necessarily your current local checkout)
|
||||||
|
|
||||||
|
**Call:**
|
||||||
|
```
|
||||||
|
create_branch owner: <owner> repo: <repo> branch: <new-name> old_branch: <source-branch>
|
||||||
|
```
|
||||||
|
|
||||||
|
Default dispatch: if the user gives a base ("branch off of X", "from X"), pass it as `old_branch`.
|
||||||
|
If they don't specify a base and you're mid-task on a local branch, pass your current branch
|
||||||
|
(`git branch --show-current`) as `old_branch` so the new branch forks from where you're actually
|
||||||
|
working, rather than silently falling back to the repo default. If neither applies (e.g. a fresh
|
||||||
|
top-level request with no working branch context), omit `old_branch` and let it default server-side.
|
||||||
|
|
||||||
|
A branch name collision returns `409 Conflict`.
|
||||||
|
|
||||||
|
## `delete_branch`
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `owner` (string, required)
|
||||||
|
- `repo` (string, required)
|
||||||
|
- `branch` (string, required)
|
||||||
|
|
||||||
|
**Call:**
|
||||||
|
```
|
||||||
|
delete_branch owner: <owner> repo: <repo> branch: <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Before calling this, see the hard-refusal Gotcha in SKILL.md. If the target branch's name isn't
|
||||||
|
obviously a scratch/feature branch, call `list_branches` first and check `protected` on the
|
||||||
|
matching entry — name-matching `main`/`master` alone isn't authoritative, since a repo can protect
|
||||||
|
a differently-named default branch. Confirm explicitly with the user before deleting anything
|
||||||
|
protected, every time, regardless of how the request is phrased.
|
||||||
|
|
||||||
|
## Token scope
|
||||||
|
|
||||||
|
`list_branches` works with `write:issue` alone. `create_branch` and `delete_branch` need
|
||||||
|
`write:repository`. All three are verified working empirically under a token with both scopes
|
||||||
|
(`write:issue` + `write:repository`).
|
||||||
67
plugins/gitea/skills/gitea-branches/references/commits.md
Normal file
67
plugins/gitea/skills/gitea-branches/references/commits.md
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
topic: commits
|
||||||
|
source_keys:
|
||||||
|
- gitea-mcp-repo
|
||||||
|
- gitea-mcp-slim-go
|
||||||
|
---
|
||||||
|
|
||||||
|
# Commit operations
|
||||||
|
|
||||||
|
Read-only commit history, scoped to a repo (optionally to one branch or one path). Call signatures
|
||||||
|
below were verified live against the deployed `gitea-mcp` server via `ToolSearch` at authoring time,
|
||||||
|
not copied from research docs, for the same drift-avoidance reason noted in `references/branches.md`.
|
||||||
|
|
||||||
|
This domain has no prior skill precedent — it's new coverage added alongside branches because commit
|
||||||
|
history is naturally scoped to a branch (a "what happened on this branch" question), not because it
|
||||||
|
shares any tool family with branch create/delete.
|
||||||
|
|
||||||
|
## `list_commits`
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `owner` (string, required)
|
||||||
|
- `repo` (string, required)
|
||||||
|
- `sha` (string, optional) — starting SHA or branch name; if omitted, gitea-mcp uses the repo's
|
||||||
|
default branch
|
||||||
|
- `path` (string, optional) — restrict results to commits that touched this file/path
|
||||||
|
- `page` (number, optional, default: `1`, minimum: `1`)
|
||||||
|
- `per_page` (number, optional, default: `30`, minimum: `1`)
|
||||||
|
|
||||||
|
**Call:**
|
||||||
|
```
|
||||||
|
list_commits owner: <owner> repo: <repo> sha: <branch-or-sha> path: <optional-path>
|
||||||
|
```
|
||||||
|
|
||||||
|
Dispatch defaults:
|
||||||
|
- "commits on `<branch>`" → pass `<branch>` as `sha`.
|
||||||
|
- "commits touching `<path>`" (no branch mentioned) → pass `path` alone, `sha` omitted (defaults to
|
||||||
|
the repo's default branch).
|
||||||
|
- Both given → pass both; the result is history for that path, walked from that branch/SHA.
|
||||||
|
- Neither given → omit both; this returns default-branch history, which is a reasonable default for
|
||||||
|
an open-ended "what's the recent history here" question.
|
||||||
|
|
||||||
|
**Response:** one object per commit: `sha`, `html_url`, `created`, `message` (when available),
|
||||||
|
`author` (`{name, email, date}`, when available).
|
||||||
|
|
||||||
|
Paginate per the manual-pagination Gotcha in SKILL.md if you need more than one page of history.
|
||||||
|
|
||||||
|
## `get_commit`
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `owner` (string, required)
|
||||||
|
- `repo` (string, required)
|
||||||
|
- `sha` (string, required)
|
||||||
|
|
||||||
|
**Call:**
|
||||||
|
```
|
||||||
|
get_commit owner: <owner> repo: <repo> sha: <commit-sha>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:** same shape as a `list_commits` entry, but always fully populated (`message` and
|
||||||
|
`author` are guaranteed present, not conditional). Use this when the user asks about one specific
|
||||||
|
commit by SHA rather than browsing history — `list_commits` entries may omit `message`/`author` in
|
||||||
|
edge cases, `get_commit` will not.
|
||||||
|
|
||||||
|
## Token scope
|
||||||
|
|
||||||
|
Both tools are read-only and work with `write:issue` alone (no `write:repository` needed), verified
|
||||||
|
empirically against the deployed server.
|
||||||
25
plugins/gitea/skills/gitea-branches/references/sources.md
Normal file
25
plugins/gitea/skills/gitea-branches/references/sources.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Sources
|
||||||
|
|
||||||
|
**Note on call signatures:** per `docs/adr/0011-gitea-skill-deep-modules.md`, the tool parameter
|
||||||
|
signatures in `references/branches.md` and `references/commits.md` were re-verified live via
|
||||||
|
`ToolSearch` against the deployed `gitea-mcp` server at authoring time — they are not copied
|
||||||
|
verbatim from `api-reference.md` below. This resolves issue #6 comment #849's root-cause finding
|
||||||
|
that a prior skill was authored from API docs that had drifted from the actual MCP tool schema.
|
||||||
|
The research docs cited here informed gotchas, response shapes, and workflow context, not the
|
||||||
|
parameter lists themselves.
|
||||||
|
|
||||||
|
## gitea-mcp-repo
|
||||||
|
|
||||||
|
- **URL:** https://gitea.com/gitea/gitea-mcp
|
||||||
|
- **Description:** Official gitea-mcp repository (v1.3.0); operation/*.go source files documenting all 55 MCP tools, their parameters, and CLI flags. Informed the dispatch table and pagination / 404-may-mean-403 gotchas in SKILL.md, and the list/create/delete branch and list/get commit mechanics (including 409 conflict and default-branch fallback behavior) in references/branches.md and references/commits.md.
|
||||||
|
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||||
|
- **Contributing files:** SKILL.md, references/branches.md, references/commits.md
|
||||||
|
- **Status:** `extracted`
|
||||||
|
|
||||||
|
## gitea-mcp-slim-go
|
||||||
|
|
||||||
|
- **URL:** https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/repo/slim.go
|
||||||
|
- **Description:** Slim response shape structs from gitea-mcp source; defines exactly which fields the MCP server returns for branches (name, protected, commit_sha) and commits (sha, html_url, created, message, author), and informed get_commit's always-populated guarantee vs. list_commits' conditional fields.
|
||||||
|
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||||
|
- **Contributing files:** references/branches.md, references/commits.md
|
||||||
|
- **Status:** `extracted`
|
||||||
Reference in New Issue
Block a user