0017. API v2: v1's resources with the 4.0 identity, an MCP that takes numbers
- Status: accepted
- Date: 2026-10-27, last amended 2026-11-08
- Decided by: the brick-work session under the maintainer's delegation of 2026-10-26 (renewed 2026-10-27), inside design § 7, which the maintainer approved on 2026-10-23. The decisions are on #113 ("Scope and decisions (2026-10-27)") and recorded with the wiki-agent (Session Decisions seq 168, 170, 175)
Context
Schema 4.0 (0016) gives every item a Brick Work id, so v1's addressing by BrickLink (item_type, item_no) no longer names an item. A BrickLink number can name several items: n:m mappings, colour-scoped legs, merged items. v1 had two clients, Toni through the House API and the lego-add skill, plus the MCP server that is generated from the contract. All of them speak BrickLink numbers. Design § 7 sets the frame (paths by Brick Work id, number lookups, v1 answers 410) and leaves the conventions open.
Options considered
- A redesigned v2. New resources, envelopes and error codes, shaped around 4.0. Every client is rewritten, and the work is a milestone of its own.
- v1's resource set with the 4.0 identity. Envelopes, pagination, filters, ETag and If-Match, idempotency, error codes, scopes and tokens stay as in
api-v1.md§ 2. Only the way an item is named changes, so a client changes only that. - Keep v1 by translating numbers to ids at the edge. Ambiguous numbers have no correct answer, and a merged id would silently move a write.
Recommendation: 2. Two clients, both already on the v1 conventions, and the § 7 table lists every change.
Decision
v2 is v1's resource set with the 4.0 identity.
- Addressing:
/items/{id}is canonical./sets|parts|minifigures/by-number/{no}andGET /lookup?provider=&kind=&key=answer 200 with the same body, so a client needs one round trip. - Numbers: the default provider for numbers is
bricklink. A number that names several items answers409 ambiguouswith the candidates; one that names none answers404, or422 unidentifiedon create. - Colours: a colour in a request is in the provider's space. On
/items/{id}paths it is a Brick Work colour id. - Merged items: a merged id answers
307to the survivor on GET (amended from 301 during M.11; the amendment is inapi-v2.md§ 2.10), and409 mergednaming the survivor on writes. - Wishes: wish ids are uuids.
- v1: answers 410
api_retired, except/api/v1/health, which still answers for the release tracker. - MCP: generated from
openapi-v2.yaml, and it keeps its tool names. No tool takes a Brick Work id. Item tools takeprovider,kindandno(markedx-mcp-itemin the contract), and the adapter resolves them through/lookup, with the tool's colour taking part, since BrickLink links can be colour-scoped.record_pricemaps its colour the same way. Collection records (copies, stock, wishes, wishlists, storages, lots, events, jobs, orders, plans) keep their ids, taken from list tools. A 3xx is the tool's error, because neither MCP client follows a redirect.
Amendment of 2026-11-08: the wishlist tool names
The rule "it keeps its tool names" is broken once, on purpose, before v1.0.0. The five wishlist tools carried names generated from their method and path; every other tool has a name that says what it does. The maintainer decided on 2026-11-08: "Clean rename before v1.0.0" (#152), with no aliases.
| Before (0.9.0) | From the next release |
|---|---|
post_wishlists |
create_wishlist |
patch_wishlists_id |
edit_wishlist |
delete_wishlists_id |
archive_wishlist |
post_wishlists_id_restore |
restore_wishlist |
post_wishlists_id_transfer |
transfer_wishes |
Their descriptions (the operations' summary) changed with them. The REST API, its operation ids and every other tool are unchanged. This breaks an MCP client that calls a wishlist tool by its 0.9.0 name: it gets "unknown tool" and must use the new name. The release notes say so. From v1.0.0 on, the rule stands again: a tool name changes only with a new major version.
Consequences
- The House API pass-through, the Toni App Lego tab and
lego-addswitched by changing how they name items. They landed inside the cutover window, because v1 answers 410 after the switch and v2 fails against 3.3 before it. - The House API passes a merged item's 307 on with
Locationrewritten to/lego/…, and still never follows a redirect. - A BrickLink number with several Rebrickable targets (
3001names RB3001and3556until a preferred link is set) answersambiguous, and the caller must choose. Clients show the candidates and never guess. - Additive fields need no new version: the catalogue entry's
themewas added on 2026-10-28. A breaking change after the first deploy needs v3, and so does a change of the idempotency fingerprint (it carriesv: 1).
Links
#113, docs/brickwork/api-v2.md § 2 (§ 2.10 holds every correction), docs/brickwork/openapi-v2.yaml, docs/brickwork/mcp.md; 0006, 0007, 0016.
