chore: update README.md with mcp setup instructions behind Caddy

This commit is contained in:
Björn Fromme committed 2026-10-19 09:00:17 +02:00
1 parent 5c07dd4885
commit 89c365bf7c
1 file changed
+63
+63
View File
@@ -240,6 +240,69 @@ itself.
The container still needs to resolve and reach the Git host (and the MCP host, if used). The container still needs to resolve and reach the Git host (and the MCP host, if used).
### Hosting the gitea MCP server
`@mcp` expects an MCP endpoint over HTTP that takes the bot token as `Authorization: Bearer` on
every request. The official [gitea-mcp](https://gitea.com/gitea/gitea-mcp) server does this in
HTTP mode: it serves `POST /mcp` and forwards the per-request token to Gitea, so it needs no token
of its own and every call runs with exactly the bot's access. A setup next to a docker-compose
Gitea behind Caddy:
1. Add the service to Gitea's `docker-compose.yml`. Point `GITEA_HOST` at Gitea's internal
address so MCP traffic doesn't loop back out through Caddy, and leave `GITEA_ACCESS_TOKEN`
unset on purpose:
```yaml
services:
gitea-mcp:
image: docker.gitea.com/gitea-mcp-server:latest # better: pin a release tag
restart: unless-stopped
command: ["/app/gitea-mcp", "-t", "http", "-p", "8080"]
environment:
GITEA_HOST: http://gitea:3000 # Gitea's service name and internal port
GITEA_READONLY: "true" # hides every write tool
depends_on:
- gitea
# Only if Caddy runs on the host rather than in Docker:
# ports:
# - "127.0.0.1:8080:8080"
```
2. Add a Caddy site. Without a token, requests would reach Gitea anonymously, so refuse them at
the proxy:
```caddy
mcp.example.com {
@noauth not header Authorization *
respond @noauth 401
reverse_proxy gitea-mcp:8080 # Caddy in Docker, on gitea-mcp's network
# reverse_proxy 127.0.0.1:8080 # Caddy on the host
}
```
Make sure `mcp.example.com` resolves from the DDEV container, the same way the Git host does.
3. Give the bot token at least `read:repository` and `read:issue` (PRs count as issues), plus
`read:user` and `read:organization` if those tools should work.
4. Check from inside the container (`ddev ssh`):
```bash
curl -sS -X POST https://mcp.example.com/mcp \
-H "Authorization: Bearer $(tr -d '[:space:]' < ~/.gitea-ro-token)" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}'
```
A JSON-RPC result with `serverInfo` means it works. Then `/mcp` inside `ddev claude` should list
the server as connected.
The server is registered once and the token is copied into `~/.claude.json` at that point. After
changing the URL or rotating the token, run `claude mcp remove <name> -s user` and then
`.ddev/claude-code/refs-sync.sh --setup-only` (or just `ddev claude`) to register it again.
## Installed managed files ## Installed managed files
.ddev/config.codex-claude.yaml .ddev/config.codex-claude.yaml