yp05327 21aa4684d9 feat(cmd): add -S/--scope to load only selected tool scopes (#219)
`-O` / `--tools` can already narrow the exposed tool set, but it needs every tool spelled out by name. `-S` / `--scope` (`GITEA_SCOPES`) complements it by selecting whole scopes, using the same names the `Scope` column of the tool tables documents.

```bash
gitea-mcp -S issue,pull_request                     # only those scopes
gitea-mcp --scope repository,branch --tools get_me   # those scopes plus one extra tool
```

## What changed

- Each scope is one `tool.Tool` registry carrying a canonical name, so `operation/repo` is split into the six scopes its files already imply: `repository` (`repo.go` + `tree.go`), `file`, `branch`, `tag`, `commit`, `release`. The other twelve packages map 1:1, giving 18 scopes.
- The two allowlists combine as a **union**: with neither set every tool loads; with only `--tools` set behaviour is unchanged; with both set, the selected scopes' tools plus the individually named tools load. `-r` / `GITEA_READONLY` still hides write tools on top.
- Scope names are normalized on input (case, spaces, hyphens), so `Pull Request`, `pull-request` and `PULL_REQUEST` all resolve to `pull_request`. Unknown names only warn and list the valid scopes, mirroring how `--tools` treats unknown tool names.
- The `Scope` column of all three READMEs now uses the canonical names verbatim, so it doubles as the reference for `--scope`, and `TestReadmeToolTables` compares that column against the registry in both directions — no translation table needed.
- Flag parsing moves from `cmd.init()` into `Execute()`. `main()` only ever calls `Execute()`, so this is behaviourally equivalent, and it makes the `cmd` package testable at all: previously the `init()` parse of `os.Args` hit `flag.CommandLine`'s `ExitOnError` on `go test`'s own `-test.*` flags.

## Verification

`make fmt`, `make lint-go` (0 issues) and `go test ./...` all pass. New tests cover the filter matrix (no filters / scope-only / tools-only regression / union / read-only interaction / unknown scope), scope-name uniqueness across `domainTools`, and the flag+env parsing and normalization.

Smoke-tested `tools/list` over stdio against the built binary:

| flags | tools exposed |
| :-- | :-- |
| _none_ | 54 (identical to `main`) |
| `-S branch` | `create_branch`, `delete_branch`, `list_branches` |
| `--scope 'Pull Request,TAG'` | the 4 `pull_request` + 4 `tag` tools |
| `-O get_me` | `get_me` (unchanged) |
| `-S commit -O get_me` | `get_commit`, `list_commits`, `get_me` |
| `-S file -r` | `get_dir_contents`, `get_file_contents` |
| `-S bogus,issue` | the 4 `issue` tools, plus a warning naming the valid scopes |

Reviewed-on: https://gitea.com/gitea/gitea-mcp/pulls/219
Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: yp05327 <576951401@qq.com>
2026-07-27 18:12:29 +00:00
2025-04-08 14:01:14 +00:00
2025-03-19 02:59:18 +00:00

Gitea MCP Server

繁體中文 | 简体中文

Gitea MCP Server connects a Gitea instance to Model Context Protocol clients, so repositories, issues, pull requests and more can be browsed and managed from an MCP-compatible chat interface.

Install with Docker in VS Code Install with Docker in VS Code Insiders

Installation

Download a binary from the releases page and put it in your PATH, use the docker.gitea.com/gitea-mcp-server image, or build from source into $GOPATH/bin with make and Go 1.26 or later:

git clone https://gitea.com/gitea/gitea-mcp.git
cd gitea-mcp
make install

Configuration

Pass the Gitea host and access token as command-line flags or environment variables, flags take precedence. Run gitea-mcp --help for the full list of flags and environment variables. Logs are written to $HOME/.gitea-mcp/gitea-mcp.log, add -d for debug logging.

Claude Code

Runs the server through go run and requires Go:

claude mcp add --transport stdio --scope user gitea \
  --env GITEA_ACCESS_TOKEN=token \
  --env GITEA_HOST=https://gitea.com \
  -- go run gitea.com/gitea/gitea-mcp@latest -t stdio

VS Code

Use the install buttons at the top of this README, or add the block below to your User Settings (JSON), reachable via Ctrl + Shift + P and Preferences: Open User Settings (JSON). It also works in a workspace .vscode/mcp.json, where the mcp key is omitted.

{
  "mcp": {
    "inputs": [
      {
        "type": "promptString",
        "id": "gitea_token",
        "description": "Gitea Personal Access Token",
        "password": true
      }
    ],
    "servers": {
      "gitea-mcp": {
        "command": "docker",
        "args": ["run", "-i", "--rm", "-e", "GITEA_ACCESS_TOKEN", "docker.gitea.com/gitea-mcp-server"],
        "env": {
          "GITEA_ACCESS_TOKEN": "${input:gitea_token}"
        }
      }
    }
  }
}

OpenCode

Add the following to the top-level mcp object of your OpenCode config:

    "gitea-mcp": {
      "enabled": true,
      "type": "local",
      "command": [
        "gitea-mcp",
        "-t", "stdio",
        "-H", "https://gitea.com",
        "-T", "<your personal access token>"
      ]
    }

Mistral Vibe

Add the following to ~/.vibe/config.toml:

[[mcp_servers]]
name = "gitea"
transport = "stdio"
command = "docker"
args = ["run", "--rm", "-i", "-e", "GITEA_ACCESS_TOKEN", "-e", "GITEA_HOST", "docker.gitea.com/gitea-mcp-server"]

[mcp_servers.env]
GITEA_ACCESS_TOKEN = "TOKEN"
GITEA_HOST = "https://gitea.com"

Other clients

Clients such as Cursor take either a stdio command:

{
  "mcpServers": {
    "gitea": {
      "command": "gitea-mcp",
      "args": ["-t", "stdio", "--host", "https://gitea.com"],
      "env": {
        "GITEA_ACCESS_TOKEN": "<your personal access token>"
      }
    }
  }
}

or an http endpoint, for a server started with gitea-mcp -t http --port 8080:

{
  "mcpServers": {
    "gitea": {
      "url": "http://localhost:8080/mcp",
      "headers": {
        "Authorization": "Bearer <your personal access token>"
      }
    }
  }
}

Once configured, try list all my repositories in the chat box.

Available Tools

Tool Scope Access Description
get_gitea_mcp_server_version version Read Get the Gitea MCP server version
get_me user Read Get the current authenticated user
get_user_orgs user Read List the current user's organizations
search_users search Read Search for users
search_org_teams search Read Search teams within an organization
search_repos search Read Search for repositories
search_issues search Read Search issues and pull requests across repositories
notification_read notification Read Read notifications: list (optionally scoped to a repo) or get a thread by ID
notification_write notification Write Mark a notification or all notifications as read
label_read label Read Read repository or organization labels
label_write label Write Write labels (repo or org): create, edit, delete
milestone_read milestone Read Read milestones: get one or list
milestone_write milestone Write Write milestones: create, update, delete
wiki_read wiki Read Read wiki: list pages, get content, revision history
wiki_write wiki Write Write wiki pages: create, update, delete
timetracking_read timetracking Read Read time tracking: issue/repo times, active stopwatches, your tracked times
timetracking_write timetracking Write Write time tracking: stopwatches and entries
package_read packages Read Read package registry: list packages, list versions, or get a version
package_write packages Write Delete a package version (irreversible)
list_issues issue Read List repository issues
attachment_read issue Read Read issue/comment attachments: list metadata, get metadata, or download content
issue_read issue Read Read issue: details, comments, or labels
issue_write issue Write Write issues: create, update, manage comments and labels
list_pull_requests pull_request Read List repository pull requests
pull_request_read pull_request Read Read pull request: details, diff, changed files, head commit status, reviews
pull_request_write pull_request Write Write pull requests: create, update, close, reopen, merge, update branch, manage reviewers
pull_request_review_write pull_request Write Write PR reviews: create, submit, delete, dismiss
actions_config_read actions Read Read Actions secrets and variables
actions_config_write actions Write Write Actions secrets and variables: upsert, create, update, delete
actions_run_read actions Read Read Actions workflows, runs, jobs, logs, and artifacts
actions_run_write actions Write Write Actions runs: dispatch, cancel, rerun
create_repo repository Write Create a new repository
fork_repo repository Write Fork a repository
list_my_repos repository Read List repositories owned by the current user
list_org_repos repository Read List repositories in an organization
get_repository_tree repository Read Get the repository file tree
get_file_contents file Read Get file content and metadata
get_dir_contents file Read Get the entries in a directory
create_or_update_file file Write Create or update a file (provide sha to update an existing file)
delete_file file Write Delete a file
create_branch branch Write Create a new branch
delete_branch branch Write Delete a branch
list_branches branch Read List repository branches
create_tag tag Write Create a tag
delete_tag tag Write Delete a tag
get_tag tag Read Get tag details
list_tags tag Read List repository tags
list_commits commit Read List repository commits
get_commit commit Read Get commit details
create_release release Write Create a release
delete_release release Write Delete a release
get_release release Read Get a release by ID
get_latest_release release Read Get the latest release
list_releases release Read List repository releases

Note: Several tools are consolidated, action-based tools, a single tool exposes multiple operations through a method parameter. Tools with Write access are hidden when the server runs in read-only mode (-r / GITEA_READONLY), and the exposed tool set can be filtered by scope with -S / --scope (GITEA_SCOPES) and/or by individual tool name with -O / --tools (GITEA_TOOLS).

With neither flag set, every tool loads. --scope limits loading to tools whose Scope column value is in the given list; --tools limits loading to the named tools; setting both loads the union of the selected scopes and the individually named tools. Unknown scope names are ignored with a startup warning.

gitea-mcp -S issue,pull_request
gitea-mcp --scope repository,branch --tools get_me

Many tools accept page and per_page for pagination. The maximum effective page size is the Gitea server's [api].MAX_RESPONSE_ITEMS setting (default 50), larger values are silently capped.

S
Description
Interactive with Gitea instances with MCP
Readme MIT
14 MiB
Languages
Go 97.5%
PowerShell 1.6%
Makefile 0.7%
Dockerfile 0.2%