The claude.ai connector ran the OAuth flow against a server in static-token mode, which has no OAuth endpoints: the login ended on a 404. The proper form is gitea-mcp's -oauth mode, where each user authorizes with their own Gitea account; it needs both origins public over HTTPS and Gitea's ROOT_URL to be that origin. - gitea-ingress.yaml: git.bikoret.ch → temple-council/gitea, TLS - gitea-public-patch.yaml: ROOT_URL/DOMAIN/SSH_DOMAIN = git.bikoret.ch (were a name that never resolved and a released NLB IP) - gitea-mcp-deployment.yaml: -oauth -oauth-public-url https://mcp.bikoret.ch -H https://git.bikoret.ch, no static token, probes on /healthz - gitea-mcp-ingress.yaml: host mcp.bikoret.ch (mcp.shorashim.ch retired) - gitea-public-apply.sh / gitea-public-verify.sh: the operator's DNS-gated apply and read-only verification (also in ~/.local/bin) - KOHEN.md, deploy/ARCHITECTURE.md: the new doors and the Gitea OAuth2 app ("Claude", PKCE, claude.ai + Claude Code redirect URIs) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
97 lines
3.0 KiB
YAML
97 lines
3.0 KiB
YAML
# Gitea MCP Server — public connector for claude.ai and Claude Code
|
|
#
|
|
# Deploys the official Gitea MCP server (gitea.com/gitea/gitea-mcp)
|
|
# in HTTP mode with MCP OAuth (-oauth): every client authorizes against
|
|
# Gitea with its OWN account (PKCE, no client secret), and the server
|
|
# forwards that bearer token to Gitea per request. No shared static
|
|
# token is used any more (gitea-mcp-secrets is kept only for a rollback
|
|
# to the pre-2026-10-19 static-token mode).
|
|
#
|
|
# The server serves /.well-known/oauth-protected-resource naming Gitea
|
|
# as the authorization server, so BOTH origins must be public HTTPS:
|
|
# -oauth-public-url https://mcp.bikoret.ch (gitea-mcp-ingress.yaml)
|
|
# -H https://git.bikoret.ch (gitea-ingress.yaml;
|
|
# Gitea ROOT_URL must be the same, gitea-public-patch.yaml)
|
|
# /mcp accepts only the Host from -oauth-public-url, and reverse proxies
|
|
# must pass Mcp-Protocol-Version, Mcp-Method and Mcp-Name through
|
|
# (ingress-nginx does).
|
|
#
|
|
# One-time in Gitea (Settings → Applications → Manage OAuth2 Applications):
|
|
# name Claude
|
|
# redirect URIs https://claude.ai/api/mcp/auth_callback
|
|
# http://127.0.0.1/callback (Claude Code; any port)
|
|
# confidential UNCHECKED (PKCE)
|
|
# The client ID goes into the claude.ai connector's Advanced settings,
|
|
# with the connector URL https://mcp.bikoret.ch/mcp.
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: gitea-mcp
|
|
namespace: shorashim
|
|
labels:
|
|
app.kubernetes.io/name: gitea-mcp
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app.kubernetes.io/name: gitea-mcp
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app.kubernetes.io/name: gitea-mcp
|
|
spec:
|
|
containers:
|
|
- name: gitea-mcp
|
|
image: docker.io/gitea/gitea-mcp-server@sha256:5fad9c4a1148071fd58ed617f779115f65a13c517c20427a3b39f80cac43e600 # pinned 2026-10-06: a floating tag upgrades on any restart
|
|
command: ["/app/gitea-mcp"]
|
|
args:
|
|
- "-t"
|
|
- "http"
|
|
- "-oauth"
|
|
- "-oauth-public-url"
|
|
- "https://mcp.bikoret.ch"
|
|
- "--host"
|
|
- "https://git.bikoret.ch"
|
|
- "--port"
|
|
- "8080"
|
|
ports:
|
|
- containerPort: 8080
|
|
name: http
|
|
resources:
|
|
requests:
|
|
memory: "64Mi"
|
|
cpu: "50m"
|
|
limits:
|
|
memory: "256Mi"
|
|
cpu: "250m"
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 8080
|
|
initialDelaySeconds: 10
|
|
periodSeconds: 30
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: 8080
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: gitea-mcp
|
|
namespace: shorashim
|
|
labels:
|
|
app.kubernetes.io/name: gitea-mcp
|
|
spec:
|
|
type: ClusterIP
|
|
selector:
|
|
app.kubernetes.io/name: gitea-mcp
|
|
ports:
|
|
- port: 8080
|
|
targetPort: 8080
|
|
protocol: TCP
|
|
name: http
|