Files
gitea-platform-mcp/skills/gitea/SKILL.md
T
a-limasov-ii 9a5750ddca feat: dual-mode — MCP server and CLI skill in one file
Expose the same 66 Gitea tools two ways from server/gitea_mcp.py:
- MCP server (no subcommand -> mcp.run()), as before
- CLI: `<tool> --flags` prints one JSON object {success, data/error}

A new @tool decorator registers each function in both FastMCP and a TOOLS
registry; a CLI dispatcher builds argparse from each function's signature and
wraps results in the repo's JSON+success contract. Adds `list-tools` for
discovery. No tool logic duplicated.

- Rewrite skills/gitea/SKILL.md for CLI-first usage (MCP kept as an option)
- Sync version to 0.3.0 across plugin.json, pyproject.toml, SKILL.md
- Add tests/unit/test_cli.py (dispatch routing, flag typing, errors, main)
- Document dual-mode in README.md and CLAUDE.md
- Ignore coverage artifacts

Tests: 119 passed, 93% coverage.
2026-06-24 10:44:46 +03:00

8.2 KiB

name, description, metadata
name description metadata
gitea Use this skill when the user asks to work with their Gitea server: "покажи мои репозитории", "создай репозиторий", "открой issue", "закрой issue", "создай pull request", "смерджи PR", "добавь вебхук", "покажи релизы", "создай ветку", "покажи коммиты", "сравни ветки", "список организаций", "переключись на work gitea", "gitea", "list repos", "create issue", "open PR", "merge pull request", "create release", "add webhook", "list branches", "gitea notifications", "check gitea connection".
version
0.3.0

Gitea Platform Assistant

Full Gitea REST API — 66 tools for repos, issues, PRs, branches, files, releases, webhooks, organizations. One source file, two ways to call it (pick whichever your runtime gives you):

  • CLI (this skill): uv run … server/gitea_mcp.py <tool> --param value → prints one JSON object on stdout. This is the default for Cline.
  • MCP server: the same tools exposed as mcp__gitea__<tool> when the file is registered via .mcp.json. Use these instead of execute_command if the tools are already available to you.

Tool names and parameters are identical in both modes — only the call syntax differs (CLI uses --dashed-flags, MCP uses named arguments).

Calling via CLI

ROOT   = <plugin folder>           # the gitea-platform-mcp directory
SCRIPT = $ROOT/server/gitea_mcp.py

Run through uv (deps come from the project; no separate install):

uv run --project "$ROOT" "$SCRIPT" --config "$ROOT/config.json" <tool> [--flags]

Convert snake_case params to --dashed flags. Booleans use --flag / --no-flag (e.g. --private / --no-private). List params take space-separated values (e.g. --topics ci backend).

Output contract: exactly one JSON object on stdout. Always check success:

{"success": true,  "data": <Gitea response>}
{"success": false, "error": "Gitea API 404: ...", "type": "RuntimeError"}

The process exits 0 even on tool-level errors — read success, not the exit code.

Discovery

uv run --project "$ROOT" "$SCRIPT" list-tools

Returns every tool with its description and parameter spec (name / type / required). Use it when unsure of a flag instead of guessing.

First Use

Always start by checking the connection:

uv run … "$SCRIPT" list_instances       → configured instances + default
uv run … "$SCRIPT" get_current_user      → verifies auth works

If these fail with a config error, tell the user to fill in config.json in the plugin folder (copy config.example.json).

Instance Selection

Every tool takes an optional --instance (default "" = use config default).

  • User says "на work" / "on the work server" → add --instance work.
  • No instance mentioned → omit --instance (uses config default).

Tool Categories

Meta & Health

  • list_instances — show all configured instances
  • get_server_info --instance <name> — Gitea version
  • get_current_user --instance <name> — authenticated user

Repositories

  • list_my_repos --limit 50 --page 1
  • search_repos --query <q>
  • get_repo --owner <o> --repo <r>
  • create_repo --name <n> --description <d> --private/--no-private --auto-init/--no-auto-init --default-branch main
  • create_org_repo --org <org> --name <n> …
  • update_repo --owner <o> --repo <r> --description … --no-private --website …
  • delete_repo --owner <o> --repo <r> ⚠️ permanent
  • fork_repo --owner <o> --repo <r> --organization … --new-repo-name …
  • set_repo_topics --owner <o> --repo <r> --topics ci backend

Branches & Tags

  • list_branches --owner <o> --repo <r>
  • get_branch --owner <o> --repo <r> --branch <b>
  • create_branch --owner <o> --repo <r> --new-branch-name <b> --old-branch-name <src>
  • delete_branch --owner <o> --repo <r> --branch <b> ⚠️
  • list_tags --owner <o> --repo <r>

Files

  • list_directory --owner <o> --repo <r> --path <p> --ref <branch> — browse tree
  • get_file --owner <o> --repo <r> --filepath <p> --ref <branch> — content + sha
  • create_file --owner <o> --repo <r> --filepath <p> --content "<text>" --message <msg> --branch <b> — plain text, auto-encoded
  • update_file … --content "<text>" --message <msg> --sha <sha> --branch <b> — sha from get_file
  • delete_file … --message <msg> --sha <sha> --branch <b> — sha required

Issues

  • list_issues --owner <o> --repo <r> --state open|closed|all --issue-type issues|pulls --labels … --assignee … --limit 20
  • get_issue --owner <o> --repo <r> --index <n>
  • create_issue --owner <o> --repo <r> --title <t> --body <b> --assignees alice bob --labels 1 2
  • update_issue --owner <o> --repo <r> --index <n> --title … --body … --state open|closed
  • close_issue / reopen_issue --owner <o> --repo <r> --index <n>
  • list_issue_comments / add_issue_comment --body <b> / edit_issue_comment --comment-id <id> --body <b> / delete_issue_comment --comment-id <id>

Labels & Milestones

  • list_labels / create_label --name <n> --color "#rrggbb" / add_issue_labels --index <n> --label-ids 1 2
  • list_milestones --state open|closed|all / create_milestone --title <t> --due-on 2024-12-31T00:00:00Z

Pull Requests

  • list_pull_requests --owner <o> --repo <r> --state open|closed|all
  • get_pull_request --owner <o> --repo <r> --index <n>
  • create_pull_request --owner <o> --repo <r> --title <t> --head <src-branch> --base <target-branch> --body <b>
  • update_pull_request --owner <o> --repo <r> --index <n> --title … --body … --state …
  • merge_pull_request --owner <o> --repo <r> --index <n> --merge-style merge|rebase|squash|fast-forward-only --delete-branch-after-merge
  • get_pr_diff --owner <o> --repo <r> --index <n> — returns diff text
  • list_pr_files --owner <o> --repo <r> --index <n>
  • list_pr_reviews / create_pr_review --index <n> --state APPROVED|COMMENT|REQUEST_CHANGES --body <b>

Releases

  • list_releases / get_latest_release / create_release --tag-name <t> --name <n> --body … --draft --prerelease / delete_release --release-id <id>

Webhooks

  • list_repo_webhooks / create_repo_webhook --url <u> --events push issues pull_request --secret … / delete_repo_webhook --hook-id <id>

Users & Organizations

  • get_current_user / get_user --username <u> / search_users --query <q>
  • list_my_orgs / get_org --org <org> / list_org_repos --org <org> / list_org_members --org <org> / list_org_teams --org <org>

Commits & Activity

  • list_commits --owner <o> --repo <r> --sha <ref> --path <p> --limit 20
  • get_commit --owner <o> --repo <r> --sha <sha>--no-stat / --no-files to slim output
  • compare_branches --owner <o> --repo <r> --base <b> --head <h> — diff + commit list
  • list_repo_contributors --owner <o> --repo <r>

Notifications

  • list_notifications --include-read --limit 20 / mark_all_notifications_read

Typical Examples

# Open an issue
uv run --project "$ROOT" "$SCRIPT" create_issue \
  --owner andrey --repo infra --title "CI flaky on main" --body "Fails ~1/5 runs"

# Edit then commit a file (two steps — get sha first)
uv run … "$SCRIPT" get_file --owner andrey --repo infra --filepath README.md
uv run … "$SCRIPT" update_file --owner andrey --repo infra --filepath README.md \
  --content "new text" --message "docs: tweak" --sha <sha-from-get_file>

# Create and merge a PR on the work instance
uv run … "$SCRIPT" create_pull_request --owner team --repo svc \
  --title "Feature X" --head feature/x --base main --instance work
uv run … "$SCRIPT" merge_pull_request --owner team --repo svc --index 42 \
  --merge-style squash --delete-branch-after-merge --instance work

Notes / Gotchas

  • File edits are two-step: get_file → use its sha in update_file / delete_file. Without the current sha Gitea rejects the write.
  • Destructive ops (delete_repo, delete_branch, delete_release) are permanent — confirm with the user before running.
  • list_issues --issue-type pulls returns PRs (Gitea treats PRs as issues).
  • Multi-value flags (--topics, --events, --assignees, --label-ids) take space-separated values, not a comma string.