5 Commits

Author SHA1 Message Date
sysadmin 7e8256cfaf docs: standardize isolated LLM worktrees (#38) 2026-07-02 02:42:52 -04:00
sysadmin 3aaba73127 feat: JSON multi-profile runtime config for Gitea MCP (roadmap #10)
Let one MCP server select among named Gitea runtime profiles from a JSON file
instead of editing code or juggling many .env files:

    GITEA_MCP_CONFIG=/path/to/gitea-mcp.json
    GITEA_MCP_PROFILE=dev

- New gitea_config.py: load/validate the JSON, select the named profile, and
  resolve its token by env-var reference. Profiles supply base_url,
  profile_name, token_env, owner/repo, allowed/forbidden operations, and audit
  label.
- gitea_auth.get_profile() now overlays env over the selected JSON profile:
  explicit env vars win, the JSON profile fills only what env leaves unset.
- gitea_auth.get_auth_header() gains a JSON token_env fallback after explicit
  env tokens (env still wins).

Security / safety:
- Tokens are referenced by env-var NAME (token_env); an inline "token" is
  rejected and never echoed. The value is never stored in or returned as
  profile metadata.
- Fail-safe errors: missing file / invalid JSON / unknown or unset selected
  profile raise a clear ConfigError that never prints file contents or tokens
  (JSONDecodeError context is suppressed so the raw file text can't surface).
- No network calls during config parsing.
- Real config files are gitignored (gitea-mcp*.json), example kept.

Backwards compatible: with GITEA_MCP_CONFIG unset, behaviour is exactly the
prior env-only behaviour (all existing get_profile/get_auth_header tests pass
unchanged).

Docs: README JSON-profiles section + env table rows, .env.example placeholders,
gitea-mcp.example.json.
Tests: tests/test_config.py (22 cases) — env-only, selection, multiple
profiles, env-override precedence, missing file, invalid JSON, missing/unset
profile, inline-token rejection + redaction, and no-network-during-parse.

Refs #10. Note: issue #19 (env-based profiles) was already implemented and
closed; this JSON-file capability is adjacent new scope tracked under the
roadmap rather than reopening #19.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 22:44:31 -04:00
sysadmin e31612027d 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>
2026-07-01 13:21:59 -04:00
sysadmin 51296c88a3 refactor: rename auth.py to gitea_auth.py and ignore env files 2026-06-21 22:27:40 -04:00
sysadmin 7404f768d3 chore: improve tooling quality and docs
- close_issue.sh: add set -euo pipefail, argument validation, confirmation output
- mark_issue.sh: track previously untracked claim/release script
- create_pr.sh: remove hardcoded one-off (use create_pr.py instead)
- README.md: reflect current toolset with usage examples
- .gitignore: ignore venv/ and __pycache__/
2026-06-21 17:11:44 -04:00