Initial commit

This commit is contained in:
QiuSW
2026-08-07 22:18:16 +08:00
commit 0e7e83fe8b
28 changed files with 2793 additions and 0 deletions
@@ -0,0 +1,213 @@
Metadata-Version: 2.4
Name: gitea-mcp
Version: 0.5.2.dev4
Summary: Model Context Protocol server for Gitea (and Forgejo, Codeberg).
Author-email: Sam Ware <samuel@waretech.services>
License: MIT
Project-URL: Homepage, https://github.com/werebear73/gitea-mcp
Project-URL: Issues, https://github.com/werebear73/gitea-mcp/issues
Project-URL: Source, https://github.com/werebear73/gitea-mcp
Keywords: mcp,gitea,forgejo,codeberg,model-context-protocol,llm,ai
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Version Control :: Git
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastmcp<3.0,>=2.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pydantic>=2.0.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: pytest-httpx>=0.30; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Requires-Dist: pre-commit>=3.5; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file
# gitea-mcp
<!-- mcp-name: io.github.werebear73/gitea-mcp -->
A [Model Context Protocol](https://modelcontextprotocol.io) server for [Gitea](https://gitea.io) — lets AI assistants (Claude, ChatGPT, Copilot, and anything else that speaks MCP) read, create, and manage issues, repositories, and releases on any Gitea instance you can reach.
Also works against **[Forgejo](https://forgejo.org)** and **[Codeberg](https://codeberg.org)** (API-compatible).
## Why
Self-hosted Gitea is a popular GitHub alternative for solo developers, small teams, and privacy-conscious organizations. With this MCP server installed, your AI assistant can:
- File audit findings or refactor notes as Gitea issues without you leaving the chat
- Triage a repo's open issues in natural language
- Cut a release at the end of a coding session
- Comment on issues across multiple repos in one pass
## Features
| Resource | Tools |
| --- | --- |
| Issues | `create_issue`, `list_issues`, `get_issue`, `update_issue`, `add_comment` |
| Repos | `list_repos`, `list_labels`, `list_milestones`, `list_branches` |
| Pulls | `list_pull_requests`, `get_pull_request`, `add_comment_on_pr`, `create_pr`, `merge_pr` |
| Files | `read_file`, `commit_changes`, `create_branch` |
| Releases | `list_releases`, `create_release` |
| Wiki | `list_wiki_pages`, `get_wiki_page`, `list_wiki_revisions`, `create_wiki_page`, `update_wiki_page`, `delete_wiki_page` |
| Meta | `get_server_info`, `get_server_version` |
- Bearer authentication via Personal Access Token (PAT)
- Async HTTP via `httpx` and `FastMCP`
- Works with self-hosted Gitea, Forgejo, and Codeberg
## Quick Start
### 1. Install
```bash
pip install gitea-mcp
```
Or with [`uv`](https://docs.astral.sh/uv/):
```bash
uv pip install gitea-mcp
```
### 2. Generate a Personal Access Token
In your Gitea instance, go to **Settings → Applications → Generate New Token** and grant at least:
- `read:repository`
- `write:issue`
- `read:user`
Add `write:repository` if you also want to create releases or write wiki pages.
### 3. Configure your MCP client
**Claude Desktop (interactive):** run
```bash
gitea-mcp init
```
It prompts for the Gitea URL and Personal Access Token, verifies the connection, and writes (or merges into) the right `claude_desktop_config.json` for your OS. Restart Claude Desktop and you're done.
To check that the server can reach your Gitea instance at any time:
```bash
gitea-mcp doctor
```
`doctor` reads `GITEA_URL` and `GITEA_TOKEN` from the environment, runs a `GET /api/v1/user`, and reports the authenticated username plus the state of the MCP tool surface. Exit `0` = ready; exit `1` = connection/load failure; exit `2` = missing config.
**Any MCP client (manual):** add `gitea-mcp` to the client's MCP config. The recommended form uses `uvx` so the client launches the latest published wheel in an isolated env without needing `gitea-mcp` on its own PATH (this is what `gitea-mcp init` writes):
```json
{
"mcpServers": {
"gitea": {
"command": "uvx",
"args": ["gitea-mcp"],
"env": {
"GITEA_URL": "https://your-gitea-instance.example.com",
"GITEA_TOKEN": "your-personal-access-token"
}
}
}
}
```
If you'd rather use a globally pip-installed `gitea-mcp` binary, drop `args` and set `command` to `"gitea-mcp"` directly — works as long as the binary is on the MCP client's PATH at launch time.
See [`mcp.json`](mcp.json) for a complete example. The same shape works for Claude Desktop, VS Code, Cowork, Claude Code, and any other MCP-compatible client.
## Configuration
Configuration is read from environment variables.
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `GITEA_URL` | Yes | — | Base URL of your Gitea instance (e.g., `https://gitea.example.com`) |
| `GITEA_TOKEN` | Yes | — | Personal Access Token from your Gitea user settings |
| `GITEA_TIMEOUT` | No | `30` | HTTP request timeout in seconds |
| `GITEA_MAX_RETRIES` | No | `3` | Max retries for transient failures on idempotent methods (`GET`/`PUT`/`DELETE`). Set to `0` to disable retries. `POST` and `PATCH` are never auto-retried — they could create duplicate issues, comments, or releases. `429 Too Many Requests` is retried for **any** method, honoring `Retry-After` when present. |
| `GITEA_RETRY_BASE_DELAY` | No | `0.5` | Base delay (seconds) for exponential backoff between retries. Effective delay grows as `base * 2^attempt` with jitter, capped at 4 seconds. |
## Self-hosting / HTTP transport
By default `gitea-mcp` runs in stdio mode — each MCP client (Claude Desktop, Cowork, etc.) launches its own subprocess on demand. For self-hosting one instance that multiple clients connect to over the network, use the streamable-HTTP transport:
```bash
gitea-mcp serve --transport http --host 0.0.0.0 --port 8000 --path /mcp
```
All four flags can also be provided via environment variables (handy for Docker / systemd units):
| Variable | Default | Flag |
| ------------------------- | ------------ | -------------- |
| `GITEA_MCP_TRANSPORT` | `stdio` | `--transport` |
| `GITEA_MCP_HOST` | `127.0.0.1` | `--host` |
| `GITEA_MCP_PORT` | `8000` | `--port` |
| `GITEA_MCP_PATH` | `/mcp` | `--path` |
MCP clients connect to the resulting URL (e.g. `https://gitea-mcp.example.com/mcp`) just like they would to a local stdio server, except they share the one running instance.
**Auth model (this release).** The server reads `GITEA_TOKEN` from its own environment, so any client that reaches the URL acts as that one Gitea user. Run it for yourself behind your own access controls (firewall, reverse-proxy auth, VPN, Tailscale). Multi-tenant bring-your-own-token is on the roadmap.
The no-args invocation (`gitea-mcp` with no subcommand) still runs in stdio mode, so existing Claude Desktop / Cowork / Claude Code integrations are unaffected by this addition.
## Compatibility
| Server | Status |
| --- | --- |
| Gitea (self-hosted) | ✅ Primary target |
| Forgejo | ✅ Expected to work (API-compatible) |
| Codeberg | ✅ Expected to work (Codeberg runs Forgejo) |
## Development
```bash
git clone https://github.com/werebear73/gitea-mcp.git
cd gitea-mcp
pip install -e ".[dev]"
pre-commit install # commit-stage hooks (ruff + mypy)
pre-commit install --hook-type pre-push # push-stage hooks (pytest + build check)
pytest
```
The two-stage pre-commit policy keeps the commit loop snappy (lint + type only) while making `git push` block on the slow stuff that's actually caught CI/release bugs in the past — the full test suite and `python -m build && twine check dist/*`, which surfaces `setuptools_scm` version surprises before they reach a tag push.
## Roadmap
See [`docs/ROADMAP.md`](docs/ROADMAP.md) for what's shipped, what's next, and what's out of scope.
## Publishing
- MCP Registry metadata is tracked in [`server.json`](server.json).
- Smithery + MCP Registry publication steps are documented in [`docs/PUBLISHING.md`](docs/PUBLISHING.md).
## Versioning
Semantic versioning, derived from git tags via `setuptools_scm`. See [`VERSIONING.md`](VERSIONING.md) for the release process.
## Contributing
Issues and pull requests welcome. For substantial changes, please open an issue first to discuss the approach.
## License
[MIT](LICENSE) — use it however you like, including commercial products.
---
Built by [Waretech Services](https://waretech.services).
@@ -0,0 +1,23 @@
gitea_mcp/__init__.py,sha256=9KYUxsefJXdcgx13lOdMKDTwtqW39J0oxAcNl4xM7n8,304
gitea_mcp/_app.py,sha256=mNYrUKQi-o9DpkFJQLwUmM421Kj0EZBBdmOREFxifOU,1852
gitea_mcp/_version.py,sha256=2JFIzAqJlZTk7JhAGeHGs4qJryKff5sFiNkbAeDnhEI,28
gitea_mcp/client.py,sha256=eqSJFOFIPX6DlTVLzG0phHeAP41EorbfMMnGbDy0WL8,12123
gitea_mcp/config.py,sha256=2QrZ7A5ZEI2QckWpc8HL8rJ5cAHx8k9L8QRD-24IlVw,2218
gitea_mcp/doctor.py,sha256=5FGCyGwP6it-u3tsH0IV87T1lOzkg0BwGLefJgRmhOs,3707
gitea_mcp/init.py,sha256=7X5vE84Q-H-CUE189zZXy3ru7BDUDWwM1_-URw0XjBQ,11373
gitea_mcp/serve.py,sha256=0Un3iDYHnetwNKcXAQzABuCKtJRNqx2muEuZ7zToFmw,4920
gitea_mcp/server.py,sha256=v63QSvmMyCefR9pjdYnrivGm-I1Tc1KZHsFHvUkjk0I,4711
gitea_mcp/tools/__init__.py,sha256=XyQ5iUrz5alYHvWUH03LcGQ1dFJ_1aZ5lhof8XU8_K0,166
gitea_mcp/tools/files.py,sha256=jV0RRlRCdNMi1DiOW2L2zp_i989bi3XTZCVger8rR-8,8612
gitea_mcp/tools/issues.py,sha256=gVSFSzELoXh0-F8ceZGcvoLAI1vr21meFhowcI10APQ,9656
gitea_mcp/tools/pulls.py,sha256=bZvySbFta7QiykMvVwOFWN71XFbKFKtwns2EpOHxgp4,7137
gitea_mcp/tools/releases.py,sha256=i37PQ_AUz8zMmj4NvDK1eIbQQMqZUE-xvbA9fR0y8w0,3306
gitea_mcp/tools/repos.py,sha256=od_xe3RHxgRN3bexRWUOW27OnQXIegIbGGXODt3GcN0,3423
gitea_mcp/tools/server_info.py,sha256=PO8RmNwE7ENHcFon5ijvvZQV3pd-xjggXKLtWgrhAx0,3279
gitea_mcp/tools/wiki.py,sha256=7h2CqK6E-FrJUGc1SG2QQbBxBY8hsMG2OBInWfP9EH0,9759
gitea_mcp-0.5.2.dev4.dist-info/licenses/LICENSE,sha256=d23Qx0gy7rKXSx1QjoTq_i7-OBXtQNdQCzShSPgqiAI,1086
gitea_mcp-0.5.2.dev4.dist-info/METADATA,sha256=wHZq5T9yVUCb9nLInn-kmOVr_NBHw6K1ozbSRW31XKs,9329
gitea_mcp-0.5.2.dev4.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
gitea_mcp-0.5.2.dev4.dist-info/entry_points.txt,sha256=PjRHlfQDMINFlBt4maFz_PWZ0p8t38Rw3br6-w-hZis,52
gitea_mcp-0.5.2.dev4.dist-info/top_level.txt,sha256=anwGYTKslQDgerLVaH7Ded7ivajJbXfUAjcnmZeslWk,10
gitea_mcp-0.5.2.dev4.dist-info/RECORD,,
@@ -0,0 +1,5 @@
Wheel-Version: 1.0
Generator: setuptools (83.0.0)
Root-Is-Purelib: true
Tag: py3-none-any
@@ -0,0 +1,2 @@
[console_scripts]
gitea-mcp = gitea_mcp.server:main
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Sam Ware
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1 @@
gitea_mcp