The API token read every GET endpoint. It now reads only the scopes its user allows
(search, models, dashboard, activity, collections, tags, categories, authors, images,
model files, imports, everything else), set beside the MCP tools in a sectioned Token
permissions dialog. Existing and new tokens get every scope, so integrations such as
Homarr and holm keep working; a refused request names the scope it needs.
Follow-up to the review of the MCP endpoint, after merging develop.
Backend
- Instance-wide MCP access an admin sets (Off / Read only / Read and
change, default Read and change), at GET/POST /settings/mcp and logged
as mcp_access_changed. Off turns every token away at /api/mcp; Read
only offers and answers only the tools that read, refuses turning a
write tool on, and keeps a token's earlier write choices so they come
back with Read and change. GET /profile/api-token carries mcp_access
and only the tools it offers.
- Model links come from the public URL an admin saved, not the
PUBLIC_URL env var it's only seeded from.
- An import refuses a category that isn't the user's own, for POST
/import and import_model alike.
- add_to_collection inserts and logs only the models it actually adds.
- get_import_status refuses a task the web app started instead of
failing on its result.
- The migration is now 20261030120000_api_token_mcp_tools, after every
migration on develop and on open branches.
- Tests for each access level, the category check, a web app task id
and the logged count.
Frontend
- The token's MCP tools move off the profile into a Token permissions
dialog behind a cog beside the token, with MCP as its first section
so the REST API's permissions can join it later.
- Each tool is a row: a small CSS tile picturing what it does (moving
only while its row is hovered or focused, still for reduced motion,
greyed when denied), its name and description, and a Deny / Allow
Segmented control. Tools are grouped by whether they read or change
the library.
- Admin Auth page: an AI assistants (MCP) section to set the access.
- The connect command gets a copy button and is hidden while MCP is off.
- Regenerating says the token's tools go back to the read-only ones.
- Save errors go through toasts.
- Spanish and French strings for every MCP key, and the new keys in all
four languages.
Docs
- mcp.md and api-token.md: the Token permissions dialog, the admin
setting, the regenerate reset, and what an assistant reading scraped
descriptions could be talked into.
A real library of 488 models has 4,306 tags: the whole list came to 63 KB,
more of an assistant's context than one answer should take. It now
returns the most used 200 by default, with how many models have each,
and takes a query to narrow them.
Each provider gets its own page under docs/providers/ with a short description,
what it needs (sign-in, Thingport Grab, FlareSolverr) and its setup steps, with
the provider's icon as an accent. PROVIDER_SETUP.md becomes the overview, with a
dependency and feature table. MakerWorld, Printables and Thingiverse come first
everywhere.
Imports Cults3D models, anyone's likes and the user's own printlists, and
syncs them. Metadata comes from Cults3D's GraphQL API with each user's own
nickname and API key. The API never hands out files, and the site's pages are
behind a Cloudflare check only a browser passes, so Thingport Grab sends the
browser's _session_id and cf_clearance cookies with its User-Agent; with
them the server orders a free model for nothing, as its Download button
does, and follows the download page to the signed file link (CloudFront, or
Cults3D's Scaleway bucket for older models). Paid models download once
bought. A Cloudflare block defers a sync until the next visit with Grab.
Imports Thangs models, likes and collections, and syncs them. Metadata is
public; files need the user's own sign-in, which Thingport Grab sends and
Thingport renews from the refresh token. Paid models download once owned;
print-only ones are refused before any download. Free accounts' daily
download limit stops a batch and defers the rest of a sync to its next check.
Import, collection import and synced collections from MyMiniFactory, alongside MakerWorld,
Printables and Thingiverse.
- Backend: API v2 client with an instance-wide API key for metadata, collections and
authors; files from MyMiniFactory's own download links (free models need no login).
Paid models, and free ones whose files are archives, download as the user from their
MyMiniFactory library through their session (PHPSESSID), fetching the model files
MyMiniFactory unpacked from each archive. Paid models are left out of collection
listings and syncs.
- One migration: MyMiniFactory category ids, username and session columns, plus a data
migration giving existing users' starter categories the new category ids. Category
matching now prefers the most specific site category.
- Frontend: provider everywhere the others appear (badges, Configuration and
Administration providers, sync Browse tab, user menu, link detection, System Health,
category ids), shared instance-key form for Thingiverse and MyMiniFactory, en and lt.
- Thingport Grab: new provider sites are allowed once from the popup (optional
all-sites access, content script registered at runtime), so adding one never makes
the browser disable the extension; captures the signed-in MyMiniFactory username and
session; paid-model notice.
- Docs, website, store assets and screenshots updated.
Every collection's Sync configuration now works before it's synced: a
Browse tab lists the user's own collections on MakerWorld (through
their cookie, private ones included), Printables and Thingiverse (by a
username asked once), and takes any collection's link. Each provider's
collections are drawn in its own colours and manner.
On Printables and Thingiverse the collection's current models are
imported by the sync's first check. MakerWorld rate-limits bulk
imports, so there only models added from now on come in. Settings can
be picked before turning sync on.