One file, 29 tools, every one acting with the caller's own Gitea token. Parameters are typed (patterns, ranges, enums), so FastMCP refuses a bad argument before Gitea is asked anything and publishes the limits in each tool's schema. New: tea_pull_get/create/review/merge, tea_labels and tea_label, tea_commit (up to 50 files, text or base64), tea_branch_create, tea_repo_edit (including archived), tea_hook_create (one per URL), tea_secret_set and tea_variable_set. Fixed: - unknown labels are refused instead of silently dropped - a file update is chosen from a 404 on the path, not from matching "404" in an error message; paths with spaces are percent-encoded - tea_org_add_member names its team; there is no default - org repositories are private by default, like user repositories - "more" and "truncated" come from X-Total-Count, so they are true - tea_issue_comments pages client-side: Gitea's endpoint is unpaged - tea_actions reads /actions/tasks: 1.24 has no /actions/runs, so the old tool always got a 404 - a Gitea that does not answer is named as such instead of a masked error Tests run against a fake Gitea (27). The same code was run against teahub.xyz with a temporary token in scratch repositories that were then deleted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CYHXFvWMCs1GUmRmpySqQ6
17 lines
1.9 KiB
Markdown
17 lines
1.9 KiB
Markdown
# Teahub MCP
|
|
|
|
Teahub's MCP (Fly app `green-tea-mcp`, `https://mcp.teahub.xyz/mcp`) against the Gitea at `GITEA_URL`. Sign-in is Gitea's OAuth (Gitea signs people in with GitHub or nostr), and every tool acts with the caller's own Gitea token: no service token, no allowlist, nothing that outruns the caller's own permissions. Reads and writes are bounded, and no tool deletes a repository, branch, file, issue or comment.
|
|
|
|
Env: `GITEA_URL`, `PUBLIC_URL`, `ALLOWED_HOSTS`; secrets `GITEA_OAUTH_CLIENT_ID`, `GITEA_OAUTH_CLIENT_SECRET` (an OAuth2 application on the Gitea with redirect `PUBLIC_URL/auth/callback`), `JWT_SIGNING_KEY`. State: `/data` (FastMCP's OAuth store).
|
|
|
|
Tools (29), all acting as you. Their parameters are typed, so a bad argument is refused before Gitea is asked anything.
|
|
|
|
- Issues and pull requests: `tea_issues`, `tea_issue_get/create/edit`, `tea_issue_comments/comment`, `tea_labels`, `tea_label` (add or remove by name), `tea_pull_get` (branches, mergeability, checks, diff), `tea_pull_create`, `tea_pull_review`, `tea_pull_merge` (keeps the head branch).
|
|
- Repositories and organisations: `tea_whoami`, `tea_repo`, `tea_repo_edit` (description, website, visibility, default branch, archived), `tea_repo_create`, `tea_org_create`, `tea_org_repo_create`, `tea_org_add_member` (name the team), `tea_hook_create` (one hook per URL).
|
|
- Files: `tea_tree`, `tea_file_get`, `tea_file_change`, `tea_commit` (up to 50 files, text or base64, 3 MB in all), `tea_branch_create`.
|
|
- Actions: `tea_actions` (recent jobs, each linking its run), `tea_workflow_dispatch`, `tea_secret_set` (never echoed), `tea_variable_set`.
|
|
|
|
New repositories are private unless asked otherwise, and labels must already exist. Gitea 1.24 has no API that lists a run's jobs, so there is no log tool; `tea_actions` links each run's page, where the logs are.
|
|
|
|
Tests: from `mcp/`, `python -m unittest discover -s tests` (a fake Gitea; needs `requirements.txt`).
|