diff --git a/AGENTS.md b/AGENTS.md index ed6707d..e4b0dff 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,26 +47,33 @@ the FastAPI adapter and the "core stays web-free" boundary. ``` src/aegis_gitea_mcp/ - catalog/ generated tool catalog: model.py (done), tools.json + loader (chunk B2) - gitea/ executor: templating, HTTP, pagination, errors, envelope (chunk B3) - server.py SDK low-level Server, list/call dispatch, filters (chunk B4) - transports stdio entry, streamable HTTP app, /health, bind checks (chunk B4) - oauth/ SDK OAuth provider proxying Gitea, token store, verifier (chunk B5) - setup.py `aegis-gitea-mcp setup` command (chunk B6) - cli.py argparse entry: serve (default), setup, version (skeleton done) - config.py pydantic-settings Settings, get_settings()/reset_settings() - identity.py Identity(login, mode, token) carried through each call - errors.py ToolError, GiteaAPIError(status, kind, message) - audit.py hash-chained audit log; security.py secret masking; + catalog/ generated tool catalog: model.py (Operation, Parameter), build.py + (swagger to catalog, annotations), naming.py, schema.py, + tools.json (generated, never hand-edited), __init__.py (loader) + gitea/ executor: executor.py (HTTP, envelope, redaction, limits), + encoding.py (path, query, body, upload building), pagination.py, + redaction.py (exact-match secret redaction) + setup_cmd.py `aegis-gitea-mcp setup`: verify instance, register OAuth app, write .env + setup_snippets.py client config snippets printed by setup + setup_template.py built-in .env template used by setup + cli.py argparse entry: serve (default), setup, version + config.py pydantic-settings Settings, get_settings()/reset_settings() + identity.py Identity(login, mode, token) carried through each call + errors.py ToolError, GiteaAPIError(status, kind, message) + audit.py hash-chained audit log; security.py secret masking; response_limits.py, rate_limit.py (HTTP), request_context.py, logging_utils.py -scripts/ generate_catalog.py (B2), validate_audit_log.py, check_docs.py (B11) + server.py, transports, oauth/ planned (chunks B4, B5), not present yet +scripts/ generate_catalog.py, validate_audit_log.py, ci/, check_docs.py (B11) spec/ pinned Gitea swagger +tests/integration/ live Gitea in Docker (harness.py), opt-in ``` -Modules marked with a chunk id do not exist yet. Request flow (target): +Modules marked planned do not exist yet. Request flow (target): client -> SDK transport and auth verifier -> `Identity` -> toolset/read-only filters -> schema validation -> executor (Gitea call with the identity's token, optional `sudo`) -> limits and masking -> result envelope (ADR 0005) -> audit. +The executor and the catalog exist; the server and transports that connect them +to MCP clients do not yet. ## Commands diff --git a/CLAUDE.md b/CLAUDE.md index 221e139..33718a7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -13,10 +13,11 @@ 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). +`config.py`, `identity.py`, `errors.py`, the generated catalog (`catalog/`), the +Gitea executor (`gitea/`), the setup command (`setup_cmd.py`, `setup_snippets.py`, +`setup_template.py`), the integration harness, CI and audit/security/limits +helpers. Planned: server and transports (B4), OAuth (B5), smoke tests (B9), +docs (B11). ## Commands @@ -27,20 +28,27 @@ 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) +uv run python scripts/generate_catalog.py --check # catalog matches the spec make validate-audit # verify audit hash chain uv run pytest tests/test_config.py::test_defaults -v # single test ``` -## Architecture (target) +## Architecture -- `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). +- `catalog/` (done): `model.py` (`Operation`, `Parameter`), `build.py` (swagger to + catalog, MCP annotations), `naming.py`, `schema.py`, generated `tools.json` + (regenerate with `uv run python scripts/generate_catalog.py`, check with + `--check`) and the loader in `__init__.py`. +- `gitea/` (done): `executor.py` (HTTP call, result envelope, redaction, size + limits, `CREDENTIAL_ISSUING_OPERATIONS`), `encoding.py` (path, query, body and + upload building, `SLASH_ROUTES`), `pagination.py`, `redaction.py`. +- `setup_cmd.py`, `setup_snippets.py`, `setup_template.py` (done): the `setup` + command, its client snippets and the built-in `.env` template. +- Server (B4, planned): 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. +- Auth (B5, planned): static bearer verifier and OAuth provider with encrypted + token store. - Core helpers (done): `config.py` (`Settings`, `get_settings()`, `reset_settings()`), `identity.py`, `errors.py` (`ToolError`, `GiteaAPIError`), `audit.py`, `security.py`, `response_limits.py`,