Every caller (claude.ai connector, LLMs primed on gitea/GitHub) sends the repo
identifier as `repo`, but the 33 per-repo identifier tools advertised `name`.
The v0.2.8 shim aliased repo->name so it worked, yet the advertised inputSchema
still said `name` — a misleading contract, with the shim load-bearing.
- Flip all 33 identifier tools: schema property + required + struct field/tag
from `name` to `repo`. A compliant `repo` caller now matches the struct
directly; the shim is pure back-compat.
- normalizeAliases is now bidirectional (name<->repo), so legacy `name` callers
still resolve, and repo_create / create_project_from_template — whose `name`
means "name of the NEW repo", not an existing-repo id — keep `name` and still
accept `repo`.
- `number`/`index` left as-is (out of scope; separate pre-existing quirk where
pr_merge advertises `index` rather than `number`).
- Tests: schema-canonical assertion + flipped alias round-trip (explicit `repo`
wins over `name`).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per-repo MCP tools 404'd while owner-level tools worked (#36). Root cause was
a parameter-name contract mismatch, not a routing fault: every per-repo tool
declares the repo identifier as 'name' (and issue/PR index as 'number'), but
every caller — the claude.ai connector, LLMs primed on gitea's own API — sends
'repo' and 'index'. The unmatched fields zero-valued the upstream path segment,
producing '/api/v1/repos/{owner}//...', which gitea answers with its generic
api-404 whose body points at /api/swagger. That swagger pointer is gitea boiler-
plate, not a misroute — the MCP dispatch was correct all along.
Two layers of defence:
- parseArgs aliases repo->name and index->number (explicit canonical wins;
alias key left intact so pr_merge's real 'index' field is unaffected). Kills
the recurrence by accepting the idiomatic argument names.
- the gitea client rejects any path with an empty segment before the HTTP call,
returning ErrValidation instead of forwarding a malformed path and surfacing
gitea's opaque swagger-404. Kills the silent-misleading-error class.
Closes#36
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>