docs: retarget setup to Claude connectors
test / test (push) Has been cancelled
lint / lint (push) Has been cancelled
docker / test (pull_request) Successful in 13s
docker / lint (pull_request) Successful in 2m3s
lint / lint (pull_request) Successful in 16s
test / test (pull_request) Successful in 14s
docker / docker-test (pull_request) Successful in 42s
docker / docker-publish (pull_request) Has been skipped

This commit is contained in:
2026-06-13 21:05:21 +02:00
parent 541124e92a
commit b275f5c0c2
10 changed files with 135 additions and 193 deletions
+21 -14
View File
@@ -2,20 +2,22 @@
## Overview
AegisGitea MCP is a Python 3.10+ application built on **FastAPI**. It acts as a bridge between an AI client (such as ChatGPT) and a self-hosted Gitea instance, implementing the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
AegisGitea MCP is a Python 3.10+ application built on **FastAPI**. It acts as a bridge between an AI client (such as Claude, Claude Code, or Cowork) and a self-hosted Gitea instance, implementing the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
```
AI Client (ChatGPT)
AI Client (Claude / Claude Code / Cowork)
│ HTTP (Authorization: Bearer <key>)
┌────────────────────────────────────────────┐
│ FastAPI Server │
│ server.py │
│ - Route: GET/POST /mcp │
│ - Route: POST /mcp/tool/call │
│ - Route: GET /mcp/tools │
│ - Route: GET /health │
│ - SSE support (GET/POST /mcp/sse)
│ - Streamable HTTP transport
│ - Legacy SSE alias (GET/POST /mcp/sse) │
└───────┬───────────────────┬────────────────┘
│ │
┌────▼────┐ ┌────▼──────────────┐
@@ -91,7 +93,7 @@ Key methods:
| Method | Gitea endpoint |
|---|---|
| `get_current_user()` | `GET /api/v1/user` |
| `list_repositories()` | `GET /api/v1/repos/search` |
| `list_repositories()` | `GET /api/v1/user/repos` |
| `get_repository()` | `GET /api/v1/repos/{owner}/{repo}` |
| `get_file_contents()` | `GET /api/v1/repos/{owner}/{repo}/contents/{path}` |
| `get_tree()` | `GET /api/v1/repos/{owner}/{repo}/git/trees/{ref}` |
@@ -134,7 +136,7 @@ All handlers return a plain string. `server.py` wraps this in an `MCPToolCallRes
2. FastAPI routes the request to the tool-call handler in server.py
3. auth.validate_api_key() checks the Authorization header
3. OAuth middleware validates the Bearer token via Gitea OIDC/JWKS or userinfo
├── Fail → AuditLogger.log_access_denied() → HTTP 401 / 429
└── Pass → continue
@@ -142,27 +144,32 @@ All handlers return a plain string. `server.py` wraps this in an `MCPToolCallRes
5. Tool dispatcher looks up the tool by name (mcp_protocol.get_tool_by_name)
6. Tool handler function (tools/repository.py) is called
6. Policy engine checks read/write mode and repository/path policy
7. GiteaClient makes an async HTTP call to the Gitea API
7. If GITEA_TOKEN is configured, service-PAT authz checks
GET /repos/{owner}/{repo}/collaborators/{user}/permission
8. Result (or error) is returned to server.py
8. Tool handler function (tools/repository.py) is called
9. AuditLogger.log_tool_invocation(status="success" | "error")
9. GiteaClient makes an async HTTP call to the Gitea API
10. MCPToolCallResponse is returned to the client
10. Result (or error) is returned to server.py
11. AuditLogger.log_tool_invocation(status="success" | "error")
12. MCPToolCallResponse is returned to the client
```
---
## Key Design Decisions
**Read-only by design.** The MCP tools only read data from Gitea. No write operations are implemented.
**Read by default, writes opt-in.** Read tools are available by default. Write-capable tools require `WRITE_MODE=true`, repository write policy/whitelist approval, and `write:repository` authorization.
**Gitea controls access.** The server does not maintain its own repository ACL. The Gitea bot user's permissions are the source of truth. If the bot cannot access a repo, the server cannot either.
**Gitea controls repository access.** Without `GITEA_TOKEN`, Gitea enforces repository permissions on API calls made with the user's token. With `GITEA_TOKEN`, the service PAT can only execute after the server verifies the requesting user's actual repository permission through Gitea and writes an audit denial if the check fails.
**Public tool discovery.** `GET /mcp/tools` requires no authentication so that ChatGPT's plugin system can discover the available tools without credentials. All other endpoints require authentication.
**Public tool discovery.** `GET /mcp/tools` requires no authentication so that MCP clients can discover the available tools without credentials. All other endpoints require authentication.
**Stateless server.** No database or persistent state beyond the audit log file. Rate limit counters are in-memory and reset on restart.
**Minimal persisted state.** The audit log is persisted for tamper-evident review. Dynamic OAuth client registrations are persisted when DCR is enabled. Rate limit counters and short-lived authz caches are in-memory and reset on restart.
**Async throughout.** FastAPI + `httpx.AsyncClient` means all Gitea API calls are non-blocking, allowing the server to handle concurrent requests efficiently.