2.2 KiB
2.2 KiB
ADR 0003: tools generated from the pinned swagger
Status: accepted (2026-10-14)
Context
Coverage target: every operation in the instance swagger gets a tool. Gitea 28.1.0 has 537 operations. Hand-writing them is error-prone and drifts.
Decision
- Pin the instance swagger at
spec/gitea-swagger.v1.json(sha256 matches the live instance at time of pinning). scripts/generate_catalog.pyturns it into a committedsrc/aegis_gitea_mcp/catalog/tools.json.--checkfails when the committed file is stale. Runtime only reads the JSON.- Tool name:
gitea_<domain>_<action>, lowercase snake_case, at most 64 characters, unique. Domain comes from the path (admin, repo, issue, pull, release, wiki, org, team, user, actions, hook, package, notification, misc), action from the operationId with redundant domain words stripped. A small override map handles collisions and awkward names. - Input schema: path and query parameters as top-level properties, the JSON
body under
body, multipart files as base64 strings.additionalProperties: falseeverywhere we control. Owner, repo and username path parameters get name patterns. - Annotations:
readOnlyHintfor GET,destructiveHintfor DELETE and for PUT/PATCH that replace state,idempotentHintfor GET/PUT/DELETE. A small explicit override set incatalog/build.pycorrects POST operations: the render endpoints (/markdown,/markdown/raw,/markup) and the read-onlyfile-contentsPOST are read-only and idempotent; irreversible or wide-reaching POSTs (PR merge, merge upstream, repo transfer and its accept/reject, user and org rename, cron run, mirror sync, adopt unadopted repository) are destructive. - Every tool also accepts optional
sudo(admin acts as another user). - One extra hand-written tool,
gitea_api_request, reaches endpoints added in newer Gitea versions than the pinned spec. - Filters:
TOOLSETS(comma-separated domains, default all),READ_ONLY(default false),DISABLED_TOOLS.
Consequences
Upgrading Gitea means re-pinning the swagger and regenerating. Tool names are stable for a given spec. The docs inventory is generated from the same catalog and checked in CI.