feat: support separate Gitea MCP runtime profiles via env config (#19)

Allow the same MCP server to run as separate MCP entries, each with its
own token and profile name, so roles stay task-scoped (the profile is
the role, not the LLM).

- gitea_auth.get_profile(): reads GITEA_PROFILE_NAME,
  GITEA_ALLOWED_OPERATIONS, GITEA_BASE_URL as non-secret metadata.
  Never reads/returns/logs the token.
- gitea_whoami now surfaces the safe profile metadata (name + allowed
  operations) alongside identity; token still never exposed.
- .env.example: placeholder-only template for a runtime profile.
- .gitignore: track .env.example while keeping real .env* ignored.
- README: document multiple env-configured MCP entries.
- tests: profile defaults/parsing, token-never-included, whoami surfaces
  profile without leaking token.

One token + one profile per process. No multi-token switching in a
single runtime. No approve/merge/eligibility workflow. No
Jenkins/Ops/GlitchTip/Release/deploy behavior. No real secrets.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-01 13:21:59 -04:00
parent 28feef3c11
commit e31612027d
6 changed files with 175 additions and 1 deletions
+32
View File
@@ -170,3 +170,35 @@ def api_request(method, url, auth_header, payload=None):
def repo_api_url(host, org, repo):
"""Return the base API URL for a repo: https://host/api/v1/repos/org/repo"""
return f"https://{host}/api/v1/repos/{org}/{repo}"
def get_profile():
"""Return safe runtime *profile* metadata for this MCP process.
A runtime profile is how the same server code is launched as separate MCP
entries (e.g. ``gitea-tools-author`` vs ``gitea-tools-reviewer``): each
process is configured with its own token *and* its own profile name via
environment variables. This function reads only the non-secret profile
metadata:
- ``GITEA_PROFILE_NAME`` — a human label for the running profile.
- ``GITEA_ALLOWED_OPERATIONS`` — optional comma-separated operation
categories (descriptive only; not enforced here).
- ``GITEA_BASE_URL`` — optional informational base URL.
It never reads, returns, or logs ``GITEA_TOKEN`` or any credential. The
token continues to be resolved separately by ``get_auth_header`` and is
never part of this metadata. Callers may surface the result safely.
Returns:
dict with 'profile_name', 'allowed_operations' (list), and 'base_url'.
"""
name = (os.environ.get("GITEA_PROFILE_NAME") or "gitea-default").strip()
raw_ops = os.environ.get("GITEA_ALLOWED_OPERATIONS") or ""
ops = [o.strip() for o in raw_ops.split(",") if o.strip()]
base_url = os.environ.get("GITEA_BASE_URL") or None
return {
"profile_name": name,
"allowed_operations": ops,
"base_url": base_url,
}