# Goose + Gitea MCP Extension Integrate the [Goose](https://github.com/AAIF/goose) AI agent with your self-hosted [Gitea](https://gitea.com) instance via the official [gitea-mcp](https://gitea.com/gitea/gitea-mcp) MCP server. **53 tools** covering repos, issues, PRs, branches, releases, CI/CD, wiki, and more — all controllable through natural language in Goose. ## What's in This Repo | File | Purpose | |------|---------| | `install.sh` | Cross-platform installer — downloads and installs the `gitea-mcp` binary | | `goose-config.yaml` | The exact config entry to add to `~/.config/goose/config.yaml` | | `README.md` | This file | | [Wiki](https://gt.covalente.dk/oval/goose-gitea-guide/wiki) | Full documentation: setup, usage, troubleshooting | ## Quick Start ```bash # 1. Install the gitea-mcp binary bash install.sh # 2. Get a Gitea access token # → Your Gitea → Settings → Applications → Generate Token # → Scopes: read:repository, write:repository, read:issue, write:issue # 3. Edit ~/.config/goose/config.yaml # Copy the entry from goose-config.yaml into the `extensions:` section # Replace YOUR_GITEA_INSTANCE and YOUR_ACCESS_TOKEN # 4. Restart Goose and start a BRAND NEW chat ``` ## Architecture ``` ┌──────────┐ stdio MCP ┌──────────────┐ REST API ┌──────────┐ │ Goose │ ◄────────────────► │ gitea-mcp │ ◄────────────────► │ Gitea │ │ (agent) │ (stdin/stdout) │ (Go binary) │ (HTTPS, token) │ Server │ └──────────┘ └──────────────┘ └──────────┘ ``` - Goose spawns `gitea-mcp` as a child process on demand (no background servers) - `gitea-mcp` translates MCP tool calls into Gitea REST API calls - SSH (port 222) is configured separately for `git clone/push/pull` ## Available Tools (53) ### Repositories & Files `create_repo`, `fork_repo`, `list_my_repos`, `list_org_repos`, `search_repos`, `create_or_update_file`, `delete_file`, `get_file_contents`, `get_dir_contents`, `get_repository_tree` ### Branches & Tags `create_branch`, `delete_branch`, `list_branches`, `create_tag`, `delete_tag`, `list_tags`, `get_tag` ### Commits & Releases `list_commits`, `get_commit`, `create_release`, `delete_release`, `get_release`, `get_latest_release`, `list_releases` ### Issues & Pull Requests `issue_read`, `issue_write`, `list_issues`, `search_issues`, `pull_request_read`, `pull_request_write`, `pull_request_review_write`, `list_pull_requests` ### Labels, Milestones, Actions, Wiki, Packages `label_read`, `label_write`, `milestone_read`, `milestone_write`, `actions_config_read`, `actions_config_write`, `actions_run_read`, `actions_run_write`, `wiki_read`, `wiki_write`, `package_read`, `package_write` ### Users & Notifications `get_me`, `get_user_orgs`, `search_org_teams`, `search_users`, `notification_read`, `notification_write`, `timetracking_read`, `timetracking_write`, `get_gitea_mcp_server_version` ## Configuration Reference ```yaml gitea: enabled: true type: stdio # Goose spawns the binary as a child process name: Gitea cmd: /usr/local/bin/gitea-mcp # Full path to the binary args: - -t - stdio # MCP transport: stdio (not http) - -H - https://YOUR_GITEA # Your Gitea instance URL - -T - YOUR_TOKEN # Personal access token envs: {} # Token in args, not env vars timeout: 300 # 5-minute timeout for long operations bundled: null # User-installed, not bundled available_tools: [] # Empty = allow all 53 tools ``` ### Why `/usr/local/bin/gitea-mcp`? Goose's `resolve_command` uses the Rust `which` crate which reliably resolves short command names (like `npx`, `uvx`) from PATH. For absolute paths, the fallback `PathBuf::from(cmd)` is used, which works correctly. Both short names (`gitea-mcp`) and absolute paths work — we recommend absolute paths for clarity. ## SSH Setup (for git operations) The MCP handles API calls. For `git clone/push/pull`, add to `~/.ssh/config`: ``` Host YOUR_GITEA_HOST Port 222 User git IdentityFile ~/.ssh/your_key ``` ## Critical: Start a New Session After adding the extension to `config.yaml`, **you must start a brand new chat session** in Goose. Existing sessions cache their extension list and won't pick up newly added extensions. ## Troubleshooting | Symptom | Fix | |---------|-----| | Gitea tools don't appear | Start a new chat session | | "No such file or directory" | Check binary path: `ls -la /usr/local/bin/gitea-mcp` | | "401 Unauthorized" | Verify token: `curl -H "Authorization: token TOKEN" https://GITEA/api/v1/user` | | "Extension not valid" | New session needed — extension cached in old session | | Config entry skipped silently | Check YAML indentation (2 spaces for gitea, 4 for fields) | See the [Troubleshooting wiki](https://gt.covalente.dk/oval/goose-gitea-guide/wiki/Troubleshooting) for detailed diagnostics. ## Links - [Full Documentation (Wiki)](https://gt.covalente.dk/oval/goose-gitea-guide/wiki) - [Goose](https://github.com/AAIF/goose) - [gitea-mcp Server](https://gitea.com/gitea/gitea-mcp)