Files
teahub/mcp
teahubxyzandClaude Opus 5.5 fb8acb0af9 mcp: Teahub MCP 2.0, typed and with the tools agents kept asking for
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
2026-10-14 18:04:07 -07:00
..
2026-10-14 05:12:31 +00:00
2026-10-14 05:28:40 +00:00
2026-10-14 05:28:46 +00:00

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).