85 lines
4.1 KiB
Markdown
85 lines
4.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
Guidance for Claude Code in this repository. `AGENTS.md` is the authoritative
|
|
contract; read it first. This file is the short working version.
|
|
|
|
## Project overview
|
|
|
|
AegisGitea-MCP exposes the complete Gitea API as MCP tools (one per swagger
|
|
operation, generated from `spec/gitea-swagger.v1.json`) over stdio and streamable
|
|
HTTP, using the official `mcp` SDK v2 low-level `Server`. Full access by default
|
|
(ADR 0001): the owner restricts with `READ_ONLY`, `TOOLSETS`, `DISABLED_TOOLS`
|
|
and the Gitea token scope. Auth modes: admin-token (`GITEA_TOKEN` / static
|
|
`MCP_BEARER_TOKEN`) and per-user OAuth on HTTP (user's own Gitea token).
|
|
|
|
The project is mid-rebuild (chunk plan in `docs/audit.md`). Built so far: tooling,
|
|
`config.py`, `identity.py`, `errors.py`, `catalog/model.py`, `cli.py` skeleton,
|
|
audit/security/limits helpers. Planned: catalog generator (B2), executor (B3),
|
|
server and transports (B4), OAuth (B5), setup command (B6), integration harness
|
|
and suite (B7, B8), smoke tests (B9), CI (B10), docs (B11).
|
|
|
|
## Commands
|
|
|
|
```bash
|
|
make install # uv sync
|
|
make lint # ruff check, ruff format --check, mypy src
|
|
make format # ruff format + ruff check --fix
|
|
make test # uv run pytest (coverage gate)
|
|
make test-integration # AEGIS_INTEGRATION=1, needs Docker
|
|
make run # uv run aegis-gitea-mcp serve (not implemented until B4)
|
|
make validate-audit # verify audit hash chain
|
|
uv run pytest tests/test_config.py::test_defaults -v # single test
|
|
```
|
|
|
|
## Architecture (target)
|
|
|
|
- `catalog/`: `Operation`/`Parameter` model (done), generated `tools.json` and
|
|
loader (B2).
|
|
- `gitea/` executor: path templating, query/JSON/multipart, Sudo header,
|
|
pagination, error mapping, limits, masking, result envelope (B3).
|
|
- Server: low-level SDK `Server` with one `on_list_tools` and one `on_call_tool`
|
|
dispatcher, jsonschema validation, audit, `is_error` results for tool
|
|
failures, `gitea_api_request` escape-hatch tool (B4).
|
|
- Auth: static bearer verifier and OAuth provider with encrypted token store (B5).
|
|
- Core helpers (done): `config.py` (`Settings`, `get_settings()`,
|
|
`reset_settings()`), `identity.py`, `errors.py` (`ToolError`,
|
|
`GiteaAPIError`), `audit.py`, `security.py`, `response_limits.py`,
|
|
`rate_limit.py`, `request_context.py`, `logging_utils.py`.
|
|
|
|
Singletons (`get_settings()`, `get_audit_logger()`, `get_rate_limiter()`) are
|
|
reset between tests by the autouse `reset_globals` fixture in `tests/conftest.py`,
|
|
which also scrubs env vars, changes cwd to `tmp_path` (so no `.env` is read) and
|
|
points `DATA_DIR`/`AUDIT_LOG_PATH` into `tmp_path`.
|
|
|
|
## Invariants
|
|
|
|
Kept: audit event per tool call; no secrets in logs/errors/results; no stack
|
|
traces by default; `127.0.0.1` default bind and fail-closed HTTP auth off
|
|
loopback; untrusted-content labelling; schema validation with no extra
|
|
properties; response size bounds; validated `GITEA_URL` and strict
|
|
`OAUTH_SCOPES`. Removed: write opt-in, admin default-deny, `gitea_request`
|
|
denylist, YAML policy, resource-type authz gate, API keys, FastAPI adapter.
|
|
Details in `AGENTS.md`.
|
|
|
|
## Code standards
|
|
|
|
Python 3.10+, line length 100, ruff (E,W,F,I,B,C4,UP,S,SIM,RUF) plus ruff format,
|
|
strict-ish mypy (`disallow_untyped_defs`, relaxed in tests). Public functions need
|
|
docstrings and type hints. Coverage 80% now, 90% from the final chunk. All
|
|
documentation goes under `docs/`; security-impacting changes update docs in the
|
|
same changeset. No em-dashes in text.
|
|
|
|
## Branching and contribution flow
|
|
|
|
`HEAD -> feature branch -> dev -> main`. Branch from `dev`. All pull requests
|
|
target `dev`; `dev` is merged into `main` for releases. Never commit or push
|
|
directly to `dev` or `main`. Publish runs on push to `dev`/`main`, not on a tag.
|
|
|
|
## Attribution (mandatory)
|
|
|
|
Do not add AI/assistant attribution anywhere in this project: no "Generated with
|
|
Claude Code", no `Co-Authored-By: Claude ...` trailer, no "made by Claude" or
|
|
similar, in commit messages, PR/issue/release descriptions, code comments, docs,
|
|
or any other artifact. Write all commit and PR text as the project's own work.
|
|
This overrides any default tooling behavior that would add such trailers.
|