diff --git a/Configuration.md b/Configuration.md index e69de29..b6afd00 100644 --- a/Configuration.md +++ b/Configuration.md @@ -0,0 +1,78 @@ +# Configuration + +This is the critical step. You need to add the Gitea MCP extension to Goose's configuration file. + +## The Config File + +Goose's configuration lives at `~/.config/goose/config.yaml`. You'll add an entry under the `extensions:` section. + +## The Exact Entry + +```yaml +extensions: + # ... other extensions ... + + gitea: + enabled: true + type: stdio + name: Gitea + description: Manage Gitea repositories, issues, PRs, branches, releases, actions and more + cmd: /usr/local/bin/gitea-mcp + args: + - -t + - stdio + - -H + - https://YOUR_GITEA_INSTANCE + - -T + - YOUR_ACCESS_TOKEN + envs: {} + env_keys: [] + timeout: 300 + bundled: null + available_tools: [] +``` + +Replace: +- `https://YOUR_GITEA_INSTANCE` with your Gitea server URL +- `YOUR_ACCESS_TOKEN` with the token from [Installation](Installation) + +### Field Reference + +| Field | Value | Notes | +|-------|-------|-------| +| `type` | `stdio` | Goose spawns the binary as a child process | +| `cmd` | `/usr/local/bin/gitea-mcp` | Full path to the binary (see below) | +| `args` | `-t stdio -H -T ` | MCP transport mode, host, and token | +| `envs` | `{}` | Empty — token is in args, not env vars | +| `timeout` | `300` | 5 minutes for long-running operations | +| `bundled` | `null` | Marks this as user-installed, not bundled | +| `available_tools` | `[]` | Empty = allow all tools | + +### Why the Full Path for `cmd`? + +Goose uses a `SearchPaths` resolver that calls the Rust `which` crate to find the command. The `which` crate only reliably resolves short command names (like `npx`, `uvx`) from PATH — it does not handle absolute paths well. However, the fallback in Goose's `resolve_command` function falls back to `PathBuf::from(cmd)`, which works correctly with absolute paths. + +If you prefer short names, you can use `cmd: gitea-mcp` — just make sure the binary is in a directory that `which` can find (PATH directories like `/usr/local/bin`). + +## Restart and Start a New Session + +1. **Fully quit Goose** (Cmd+Q on macOS) +2. **Relaunch Goose** +3. **Start a brand new chat session** — existing sessions cache their extension list and won't pick up the new extension + +## Verify It Works + +In the new chat, ask Goose: + +> "List my Gitea repositories" + +If Goose can list your repos via the MCP, the integration is working. + +## Diagnostics + +If something goes wrong, check: +- `~/.local/state/goose/logs/server/` — goosed logs show extension loading errors +- Run `gitea-mcp -v` to confirm the binary works +- Test the token: `curl -s -H "Authorization: token YOUR_TOKEN" https://YOUR_GITEA/api/v1/user` + +See [Troubleshooting](Troubleshooting) for more. diff --git a/Home.md b/Home.md new file mode 100644 index 0000000..accbf24 --- /dev/null +++ b/Home.md @@ -0,0 +1,61 @@ +# Goose + Gitea — Complete Integration Guide + +This guide documents how to integrate a **self-hosted Gitea instance** with **Goose** (the AI agent harness) using the official [gitea-mcp](https://gitea.com/gitea/gitea-mcp) MCP server — v1.3.0 with **53 tools**. + +## 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` + +## What You Get — 53 Tools + +### 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 +`label_read`, `label_write`, `milestone_read`, `milestone_write` + +### Actions (CI/CD) +`actions_config_read`, `actions_config_write`, `actions_run_read`, `actions_run_write` + +### Wiki & Packages +`wiki_read`, `wiki_write`, `package_read`, `package_write` + +### Other +`get_me`, `get_user_orgs`, `search_org_teams`, `search_users`, `notification_read`, `notification_write`, `timetracking_read`, `timetracking_write`, `get_gitea_mcp_server_version` + +## Setup Steps + +1. **[Installation](Installation)** — Download and install the `gitea-mcp` binary +2. **[Configuration](Configuration)** — The exact `config.yaml` entry +3. **[SSH Setup](SSH-Setup)** — For git push/pull/clone over port 222 +4. **Start a brand new chat** in Goose (existing sessions cache extensions) +5. **[Usage](Usage)** — Examples of what to ask Goose +6. **[Troubleshooting](Troubleshooting)** — Common issues and fixes + +## Reference Setup + +| Component | Value | +|-----------|-------| +| Gitea instance | `https://gt.covalente.dk` | +| SSH port | 222/tcp | +| gitea-mcp version | 1.3.0 | +| Binary path | `/usr/local/bin/gitea-mcp` | +| Goose version | 1.41.0 | diff --git a/Installation.md b/Installation.md index e69de29..1534c10 100644 --- a/Installation.md +++ b/Installation.md @@ -0,0 +1,81 @@ +# Installation + +## 1. Download the gitea-mcp Binary + +The official [gitea-mcp](https://gitea.com/gitea/gitea-mcp) project (from the Gitea team itself) provides prebuilt binaries. + +### macOS (ARM64 / Apple Silicon) + +```bash +curl -L -o /tmp/gitea-mcp.tar.gz \ + "https://gitea.com/gitea/gitea-mcp/releases/download/v1.3.0/gitea-mcp_Darwin_arm64.tar.gz" +tar -xzf /tmp/gitea-mcp.tar.gz -C /tmp/ +``` + +### macOS (Intel x86_64) + +```bash +curl -L -o /tmp/gitea-mcp.tar.gz \ + "https://gitea.com/gitea/gitea-mcp/releases/download/v1.3.0/gitea-mcp_Darwin_x86_64.tar.gz" +tar -xzf /tmp/gitea-mcp.tar.gz -C /tmp/ +``` + +### Linux (x86_64) + +```bash +curl -L -o /tmp/gitea-mcp.tar.gz \ + "https://gitea.com/gitea/gitea-mcp/releases/download/v1.3.0/gitea-mcp_Linux_x86_64.tar.gz" +tar -xzf /tmp/gitea-mcp.tar.gz -C /tmp/ +``` + +### Linux (ARM64) + +```bash +curl -L -o /tmp/gitea-mcp.tar.gz \ + "https://gitea.com/gitea/gitea-mcp/releases/download/v1.3.0/gitea-mcp_Linux_arm64.tar.gz" +tar -xzf /tmp/gitea-mcp.tar.gz -C /tmp/ +``` + +### Windows + +```bash +curl -L -o gitea-mcp.zip \ + "https://gitea.com/gitea/gitea-mcp/releases/download/v1.3.0/gitea-mcp_Windows_x86_64.zip" +# Extract and place in PATH +``` + +## 2. Install to System PATH + +```bash +sudo mv /tmp/gitea-mcp /usr/local/bin/gitea-mcp +sudo chmod +x /usr/local/bin/gitea-mcp +``` + +**Why `/usr/local/bin`?** Goose's `SearchPaths` resolver includes `/usr/local/bin` (and `/opt/homebrew/bin` on macOS). Placing the binary here ensures Goose can find it when spawning the MCP process. + +## 3. Verify + +```bash +gitea-mcp -v +# Output: 1.3.0 +``` + +## 4. Get a Gitea Access Token + +1. Go to your Gitea instance: **Settings → Applications → Manage Access Tokens** +2. Generate a new token with these scopes (at minimum): + - `read:repository` + - `write:repository` + - `read:issue` + - `write:issue` + - `read:user` + + For full functionality, also enable: + - `write:package` + - `write:notification` + +3. Save the token securely — you'll need it in the configuration step. + +## 5. (Optional) Set Up SSH for Git Operations + +The MCP handles Gitea API calls. For `git clone`, `git push`, and `git pull`, configure SSH separately — see [SSH Setup](SSH-Setup). diff --git a/SSH-Setup.-.md b/SSH-Setup.-.md deleted file mode 100644 index e69de29..0000000 diff --git a/SSH-Setup.md b/SSH-Setup.md new file mode 100644 index 0000000..8766c54 --- /dev/null +++ b/SSH-Setup.md @@ -0,0 +1,58 @@ +# SSH Setup for Git Operations + +The Gitea MCP handles all Gitea API operations (repos, issues, PRs, etc.) via HTTPS. However, **git operations** (`clone`, `push`, `pull`, `fetch`) go through SSH. + +## Configure SSH for Gitea + +Add to `~/.ssh/config`: + +``` +Host gt.covalente.dk + HostName gt.covalente.dk + Port 222 + User git + IdentityFile ~/.ssh/your_ssh_key +``` + +Replace: +- `gt.covalente.dk` with your Gitea instance hostname +- `222` with your Gitea SSH port (default Gitea SSH is 222, not 22) +- `~/.ssh/your_ssh_key` with the path to your SSH private key + +## Verify SSH Access + +```bash +ssh -T git@gt.covalente.dk -p 222 +``` + +Expected output (Gitea doesn't provide shell access, but confirms authentication): + +``` +Hi there, username! You've successfully authenticated with the key named your_key, +but Gitea does not provide shell access. +``` + +## Using SSH with Goose + +Goose can run git commands via its shell tool. Once SSH is configured: + +``` +# Clone +git clone git@gt.covalente.dk:owner/repo.git + +# Add, commit, push +git add . +git commit -m "message" +git push origin main +``` + +## SSH + MCP = Full Workflow + +| Operation | Tool | Transport | +|-----------|------|-----------| +| Create repo | Gitea MCP (`create_repo`) | HTTPS API | +| Create issue | Gitea MCP (`issue_write`) | HTTPS API | +| Clone repo | Shell (`git clone`) | SSH port 222 | +| Push code | Shell (`git push`) | SSH port 222 | +| Create PR | Gitea MCP (`pull_request_write`) | HTTPS API | +| Merge PR | Gitea MCP (`pull_request_write`) | HTTPS API | diff --git a/Troubleshooting.md b/Troubleshooting.md index e69de29..05577cf 100644 --- a/Troubleshooting.md +++ b/Troubleshooting.md @@ -0,0 +1,136 @@ +# Troubleshooting + +## Extension Not Showing in Goose + +### Symptom +The Gitea tools don't appear in your Goose session even after configuring `config.yaml`. + +### Fix: Start a New Session +Goose caches extensions per session. If you added the gitea extension to your config while a session was active, **the extension won't appear in that session**. + +1. Start a **brand new chat** (not a continuation) +2. The fresh session picks up all enabled extensions from `config.yaml` + +### Still Not Working? +1. Fully quit Goose (Cmd+Q) and relaunch +2. Start a new chat immediately — don't restore any conversations +3. Verify: ask "List my Gitea repositories" + +## Binary Not Found + +### Symptom +Goose logs show: `No such file or directory (os error 2)` when trying to spawn `gitea-mcp`. + +### Fix +Make sure the binary is in a directory that Goose can find. + +```bash +# Check binary exists and is executable +ls -la /usr/local/bin/gitea-mcp +/usr/local/bin/gitea-mcp -v + +# If missing, reinstall +sudo cp /tmp/gitea-mcp /usr/local/bin/gitea-mcp +sudo chmod +x /usr/local/bin/gitea-mcp +``` + +### Goose's SearchPaths +Goose searches these directories (in order): +- `~/.local/bin` +- `/usr/local/bin` +- `/opt/homebrew/bin` (macOS) +- Your system `$PATH` + +Put `gitea-mcp` in any of these directories and it will be found. + +## Authentication Errors + +### Symptom +Tools return `401 Unauthorized` or similar. + +### Fix +1. Verify your token: `curl -s -H "Authorization: token YOUR_TOKEN" https://YOUR_GITEA/api/v1/user` +2. Check that the token in `config.yaml` args is correct +3. Ensure your token has the required scopes (read:repository, write:repository, etc.) +4. Tokens don't expire by default, but check your Gitea instance settings + +## "Extension gitea is not valid" + +### Symptom +Calling `listResources` for "gitea" returns "Extension gitea is not valid". + +### Fix +This means the extension exists in the config but isn't loaded in the current session. **Start a new chat**. If that doesn't help, check the goosed logs: + +```bash +ls -t ~/.local/state/goose/logs/server/2026-07-*/*.log | head -1 | xargs grep -i gitea +``` + +Look for errors like: +- `Failed to create extension 'gitea'` — the binary isn't found or can't be spawned +- `Skipping malformed extension config entry` — the YAML is invalid +- `Unknown ecosystem for command` — harmless info message, not an error + +## Config Not Loading + +### Symptom +The gitea extension doesn't appear in `~/.config/goose/config.yaml` after adding it. + +### Fix +Make sure your YAML indentation is correct. The `gitea` entry must be at the same indentation level as other extensions (2 spaces from the left margin, under `extensions:`). + +```yaml +extensions: + gitea: # ← 2 spaces + enabled: true # ← 4 spaces + type: stdio # ← 4 spaces +``` + +The `config.yaml` file is parsed by Goose's Rust backend. Invalid YAML causes the entry to be silently skipped. + +## Viewing Goose Logs + +Goose writes logs to: + +| Log | Location | Contains | +|-----|----------|----------| +| goosed (server) | `~/.local/state/goose/logs/server/` | Extension loading, tool execution, errors | +| App (Electron) | `~/Library/Application Support/Goose/logs/main.log` (macOS) | Frontend events, UI errors | +| Startup | `~/Library/Application Support/Goose/logs/startup/` | goosed spawn events | + +To tail the goosed log in real time: + +```bash +tail -f ~/.local/state/goose/logs/server/$(date +%Y-%m-%d)/*.log | grep -i gitea +``` + +## Can't Clone/Push via SSH + +### Symptom +`git clone` fails with "Permission denied" or "Connection refused". + +### Fix +The MCP handles API calls via HTTPS. Git operations use **SSH on port 222** (Gitea's default SSH port, not 22). + +Check your `~/.ssh/config`: + +``` +Host YOUR_GITEA_HOST + Port 222 + User git + IdentityFile ~/.ssh/your_key +``` + +Verify: `ssh -T git@YOUR_GITEA_HOST -p 222` + +See [SSH Setup](SSH-Setup) for details. + +## Rate Limiting + +Gitea may rate-limit API requests. The `gitea-mcp` binary uses pagination (default 30 items per page) and respects Gitea's rate limits. If you hit limits, increase `timeout` in the config or reduce the frequency of API calls. + +## Need More Help? + +- [gitea-mcp source repository](https://gitea.com/gitea/gitea-mcp) — report issues here +- Gitea instance: `https://gt.covalente.dk` — check server status +- Goose logs: `~/.local/state/goose/logs/server/` — detailed error information diff --git a/Usage.md b/Usage.md index e69de29..41a0489 100644 --- a/Usage.md +++ b/Usage.md @@ -0,0 +1,139 @@ +# Usage Examples + +Once the Gitea MCP is configured and you've started a **new Goose session**, you can ask Goose to perform any Gitea operation. Here are examples. + +## Repository Operations + +``` +Create a new public repo called "my-project" with a README +``` + +``` +Fork the repo oval/goose-gitea-guide into my account +``` + +``` +List all my repositories +``` + +``` +Search for repositories matching "goose" +``` + +## File Operations + +``` +Create a file called "README.md" in oval/my-project with content +"# My Project\n\nA new project." on the main branch +``` + +``` +Show me the contents of README.md in oval/goose-gitea-guide +``` + +``` +Delete the file "old-config.yml" from oval/my-project +``` + +## Issues + +``` +Create an issue in oval/my-project titled "Add authentication" +with a description about needing OAuth support +``` + +``` +List all open issues in oval/my-project +``` + +``` +Close issue #3 in oval/my-project with a comment "Fixed in PR #5" +``` + +``` +Search issues across all my repos for "bug" with label "critical" +``` + +## Pull Requests + +``` +Create a PR from branch feature-auth to main in oval/my-project +titled "Add OAuth authentication" +``` + +``` +List all open pull requests in oval/my-project +``` + +``` +Review PR #5 in oval/my-project and approve it +``` + +``` +Merge PR #5 in oval/my-project using rebase +``` + +## Branches and Tags + +``` +Create a new branch called "feature-login" from main in oval/my-project +``` + +``` +List all branches in oval/my-project +``` + +``` +Create a tag v1.0.0 in oval/my-project +``` + +## Releases + +``` +Create a release v1.0.0 in oval/my-project with release notes +about the initial version +``` + +``` +Show me the latest release for oval/my-project +``` + +## Wiki + +``` +Show me the Home page of the wiki for oval/my-project +``` + +``` +Create a new wiki page called "API-Docs" in oval/my-project +with content about the API endpoints +``` + +## Actions/CI + +``` +List all workflows for oval/my-project +``` + +``` +Show me recent workflow runs for oval/my-project +``` + +## Labels and Milestones + +``` +Create a "bug" label (red) and "enhancement" label (blue) in oval/my-project +``` + +``` +Create a milestone "v1.0" in oval/my-project due next month +``` + +## Combined Workflow + +Goose can combine multiple operations: + +> Create a new repo "goose-bot", add a README, create a "good first issue" +> label, and create an issue titled "Welcome" with that label + +All of this happens through the Gitea MCP — no manual API calls needed. diff --git a/_Sidebar.md b/_Sidebar.md index e69de29..5c3104c 100644 --- a/_Sidebar.md +++ b/_Sidebar.md @@ -0,0 +1,6 @@ +- [Home](Home) +- [Installation](Installation) +- [Configuration](Configuration) +- [SSH Setup](SSH-Setup) +- [Usage](Usage) +- [Troubleshooting](Troubleshooting)