- storeMaterialFile: the one attach.Store call of the management API,
shared by the multipart route and the new inline route
- POST /api/v1/bm/materials/{id}/files/inline: JSON {name, mime?,
content_base64}, at most 3000000 bytes decoded, body.limit 4300000
- bm_manage_attach_material_file and bm_manage_detach_material_file,
both warning that material files are public to anyone with the link
- 28 typed management tools pinned in TestBMMCP
- body keys are Fillable columns, create inputs require the required
columns, material save/update require body, source and url
- no seed or me tool, deletes only where the route deletes
- every description names its scope and permission
- viaMCP, includeBody and the material views (no body unless asked)
- jz.bm.mcp-links: absolute url / *_url under MCP only
- jz.bm.manage keyed per user for dispatched calls
- bm_material and bm_materials in the pinned tool list
Compile-only stubs; the tests fail on their assertions.
- token twins of the student API under /_bm/api/v1/token (user.api_token,
per-user jz.bm.token bucket, a scope on each), from one mountStudent
- pact.HasMCP with the eleven student tools over the twins
- TestBMMCP and TestTokenMirrorRoutes