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:
@@ -123,6 +123,58 @@ The server is a standard MCP stdio server. Point your client at:
|
||||
No environment variables needed — auth is handled via macOS keychain.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Runtime profiles (multiple env-configured entries)</strong></summary>
|
||||
|
||||
The same server can run as **separate MCP entries**, each authenticating as its
|
||||
own Gitea token and carrying its own profile name. This keeps roles task-scoped:
|
||||
*the profile is the role, not the LLM.* Point each entry at a different
|
||||
gitignored env file.
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"gitea-tools-reviewer": {
|
||||
"command": "/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python3",
|
||||
"args": ["/Users/jasonwalker/Development/Gitea-Tools/mcp_server.py"],
|
||||
"env": {
|
||||
"GITEA_PROFILE_NAME": "gitea-reviewer",
|
||||
"GITEA_ALLOWED_OPERATIONS": "read,review,approve"
|
||||
}
|
||||
},
|
||||
"gitea-tools-merger": {
|
||||
"command": "/Users/jasonwalker/Development/Gitea-Tools/venv/bin/python3",
|
||||
"args": ["/Users/jasonwalker/Development/Gitea-Tools/mcp_server.py"],
|
||||
"env": {
|
||||
"GITEA_PROFILE_NAME": "gitea-merger",
|
||||
"GITEA_ALLOWED_OPERATIONS": "read,merge"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Recognized environment fields (see [`.env.example`](.env.example) for placeholders):
|
||||
|
||||
| Variable | Purpose |
|
||||
|----------|---------|
|
||||
| `GITEA_TOKEN` | API token for this runtime. Read only by the auth layer; **never** returned, logged, or committed. |
|
||||
| `GITEA_PROFILE_NAME` | Non-secret label for the running profile (e.g. `gitea-reviewer`). Surfaced by `gitea_whoami`. |
|
||||
| `GITEA_ALLOWED_OPERATIONS` | Optional, comma-separated operation categories (descriptive metadata only for now). |
|
||||
| `GITEA_BASE_URL` | Optional informational base URL. |
|
||||
|
||||
Notes:
|
||||
|
||||
- This provides **one token + one profile per process**. It does not implement
|
||||
multi-token switching inside a single runtime, nor any approve/merge/eligibility
|
||||
gating — those are later roadmap items (#13–#18).
|
||||
- Profile name and allowed operations are **metadata only**; the token value is
|
||||
never part of any tool output. `gitea_whoami` returns the profile name so a
|
||||
workflow can see which runtime it is talking to.
|
||||
- See [`docs/gitea-execution-profiles.md`](docs/gitea-execution-profiles.md) for
|
||||
the full profile model.
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><strong>Codex / non-MCP tools</strong></summary>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user