MCP
/api/v1/mcp is an MCP server over Streamable HTTP, running the same logic as the
REST API. Chat apps (Claude, ChatGPT, Perplexity, Gemini), coding agents, app
builders (Lovable, v0, Bolt, Replit) and Figma take the URL and send you to a
consent screen, where you pick the projects it works in and what it may do
there: Viewer, Contributor or Editor. What it gets is a key bound to you: never more
than you can do, and gone with your access. The Connections page has the setup
for each, and changes an agent’s projects and access later without it signing
in again.
An agent given several projects names one with project on any tool (its
slug, or organization/slug when two share one); without it, the tool runs in
the first one picked. The server’s instructions list them.
claude mcp add --transport http artbucket https://assets.example.com/api/v1/mcpUse your server’s address there (http://localhost:3000/api/v1/mcp on your
machine).
That is OAuth 2.1 with PKCE and dynamic client registration, discovered from
/.well-known/oauth-protected-resource. The token lasts an hour and the agent
renews it with its refresh token, a new pair each time, for as long as it does
so within 90 days; a client that registered without refresh tokens gets one
for 30 days, then connects again. Keys an admin makes don’t expire and still
work for anything headless (n8n, Make, scripts): Authorization: Bearer ab_....
| Tool | Scope | |
|---|---|---|
search_assets |
read | Full text, tags, collections, field filters, lifecycle status, upload dates, licenses running out, untagged, paged with offset |
describe_asset |
read | What it is, its rights, what replaced it, suggestions waiting on review, the brand rules that point at it, a fetchUrl to open it, and whether people outside can see it (public, or the public portals showing it) |
check_use |
read | May it run here, now, in this context; if not, why, and what instead |
rendition_url |
read | A URL for a width, height, fit, format and quality, and a fetchUrl for the agent itself. With expiresIn, a URL for someone without access: plain for a public asset, signed about a day for one a public portal shows, signed as asked with share; anything else says what the person can do |
brand_rules |
read | A brand’s rules for a context, with their labels and specs |
ingest_asset |
propose | Fetch a public URL into the library, with provenance and rights: proposed with a propose key, approved at once with a write key |
import_google_font |
propose | A Google Fonts family, one file per style |
find_icons |
read | Open source icon sets through Iconify, or a set’s icons by name, with license and author |
import_icons |
propose | Icons from a set, one SVG each, carrying its license and author |
propose_tags |
propose | Suggest tags for a person to accept |
list_fields |
read | The library’s custom fields: keys, types, options |
create_field |
write | Define a custom field: key, label, type, options, required |
update_field |
write | Change a field’s label, options, whether it is required, or its position |
delete_field |
write | Delete a field and every value stored under it |
list_collections |
read | The collections you can see, with their ids, field values and how many assets each holds |
create_collection |
write | Make a collection, with field values its assets inherit, private or not |
update_collection |
write | Rename it, change its icon or privacy, merge its field values; its assets inherit at once |
update_collection_assets |
write | Put assets in a collection and take others out, in one call |
delete_collection |
write | Delete a collection; its assets stay in the library |
propose_fields |
propose | Suggest custom field values for a person to accept |
my_proposals |
propose | What this key proposed, and what became of it |
review_asset |
write | Approve or reject a proposal, with a note; apply or drop suggested tags and field values. Never one the caller proposed itself |
brand_status |
read | What a brand still lacks before it is worth sharing: essentials in its rules, pages, a release, a portal; each step with how to do it, the Brand Agent Score, and every brand’s slug |
create_brand |
write | Make a brand, empty, as a copy of another’s rules, pages and theme, or from a public BrandHub brand (from: "rust-lang/rust@12") |
update_brand |
write | Rename a brand, change its slug, or make it the default |
delete_brand |
write | Delete a brand with its rules, pages and history; never the default |
brand_playbook |
read | What a good brand site is, before building one: research, assets, a look, the overview as a landing page, varied blocks, titles as claims; with a worked example |
preview_page |
read | The page as readers see it now, as a picture, to look at your work after a save |
list_templates |
read | The section templates a brand page is built from: their props, what they list, and an example each |
list_pages |
read | A brand’s pages, in order, with their tree |
get_page |
read | One page: its sections, the rules they show, its warnings, the page as Markdown, and its URL in the app |
get_theme |
read | How a brand’s pages look: its theme settings, and the look they give |
set_rules |
write | Make, change and remove many brand rules at once, as one version: values, labels and specs |
save_page |
write | Make or replace a page whole, placed in the tree; every problem comes back at once with its path |
edit_page |
write | Add, update, move and remove sections, change the page’s own fields or rename it; all or none |
delete_page |
write | Delete a page that has no pages under it; the brand’s history keeps it |
generate_pages |
write | Lay out a brand with no pages from its rules; with none, it makes a cover and warns |
set_theme |
write | Change the look a setting at a time; null clears one |
list_versions |
read | A brand’s history, newest first: who changed what, named checkpoints, what was released |
get_version |
read | One version’s rules, and what changed from the one before, from another, or since |
name_version |
write | Keep a version as a named checkpoint |
restore_version |
write | Bring a brand back to an earlier version, as a new version: nothing is lost |
list_comments |
read | Review comments on a brand’s pages, as threads, open ones first |
add_comment |
propose | Start a thread on a page or section, or reply in one |
update_comment |
propose | Resolve or reopen a thread, or edit your own comment |
delete_comment |
propose | Delete your own comment, or anyone’s with write on the brand |
publish |
write | Release the brand (the app’s Release): its pages, rules and theme, as they stand, go in front of portal visitors, with a note for readers; answers with the portals showing it |
set_brand_hub |
write | Who sees the brand on BrandHub (private to the project by default, or public to anyone and any agent once it has a release), and which portal it links as its guidelines |
list_sites |
write | The project’s portals: who gets in, the brands they show and whether each is released, and their site |
create_site |
write | Make a portal for brands and collections, open to the project’s members, to whoever has its password, or to anyone, with its logo and colors; its address comes from the name when left out |
update_site |
write | Change anything about a portal: what it shows, who gets in and its password, its logo and colors, its domain, when it closes, and its site |
close_site |
write | Take a portal offline now; update_site with expiresAt: null opens it again |
check_site |
read | Check a site you built, hosted anywhere, against the library: what it uses, and why any of it may not be shown. Nothing is stored |
deploy_site |
write | Publish a site you built to a site’s address, checked first; its files as text, or base64 for the rest |
list_deployments |
write | A site’s deployments, newest first: where each is mounted, its state, and why one failed or is held |
restore_deployment |
write | Put a replaced deployment back live at its path, undoing a bad deploy without building again |
delete_site |
write | Delete a portal; its address and domain stop answering |
list_site_requests |
write | Who asked to get into a password or members portal, or asked for something through it |
decide_site_request |
write | Approve or deny a request; approved access gets a link of its own |
update_asset |
write | Rename an asset, fix its caption, credit or copyright, set or change its tags, field values, rights, or what replaced it |
update_assets |
write | The same tags and field values on up to 50 assets; each succeeds or fails on its own |
review_assets |
write | review_asset for up to 50 assets in one call; "all" takes every suggestion an asset has |
delete_asset |
write | Delete an asset, restorable for 30 days; answers with what used it and the last day to restore it |
restore_asset |
write | Bring back an asset deleted in the last 30 days |
asset_versions |
read | Every version of an asset, newest first, and which one is current |
make_version_current |
write | Roll an asset back or forward to an approved version |
get_activity |
read | Who did what in the project, newest first, paged with before |
get_insights |
write | The most fetched assets, searches that found nothing, adoption and traffic |
asset_insights |
write | Where one asset is used, and its fetches over 30 days |
brand_insights |
write | A brand’s reads, page views, answers and release adoption |
brand_updates |
read | A brand’s latest releases, each with what it changed |
brand_assets |
read | The files a brand uses, with the rules and pages each is in |
brand_tokens |
read | A brand as design tokens: CSS variables, Tailwind, JSON and more |
create_share |
write | A view or upload link for people without an account, with a password and an expiry |
list_shares |
write | The project’s share links |
save_search |
write | Keep a search under a name, as an /api/v1/assets query string |
list_searches |
read | The project’s saved searches |
list_members |
admin | The organization’s and project’s people, their grants, and invitations waiting (never their links) |
search_catalog |
read | Everything at once (assets, collections, brands, portals, rules, pages) by address; paged with cursor |
describe_object |
read | One catalog object: what it is part of, what uses it, its lineage’s counts |
lineage |
read | What an object comes from and what uses it, hop by hop, and what changing it reaches |
who_can |
read | Who reaches an object, and the grant behind each role |
share_object |
admin | Share a brand, collection or asset into another project of the organization |
object_activity |
read | What happened to one catalog object, newest first |
shared_with_us |
read | What other projects shared into this one |
list_projects |
read | Every project you reach, your role there, and how much each holds |
create_project |
admin (organization) | A new project in the organization |
rename_project |
admin | Rename a project; its address stays |
get_fixes |
write | What needs doing, as Fixes lists it: places on replaced versions, searches that found nothing, licenses ending soon |
list_automations |
write | The automations you may manage, their last run, and ready-made recipes to start from |
create_automation |
write | An email or a signed webhook when a brand is released, a license nears its end, and more; a webhook’s secret comes back once |
update_automation |
write | Change an automation, or turn it off and on |
delete_automation |
write | Delete an automation and its run log |
test_automation |
write | Send an automation now with a sample event, marked as a test |
automation_runs |
write | An automation’s latest runs and every attempt, with the webhook’s status or the error |
A tool shows up in tools/list only when the key may run it: the portal
tools, only for a key with write on the project.
Brands, collections, custom fields, reviews, brand history, comments and
portals (passwords and branding included) are run over MCP as in the app.
A collection is named by its id or its name; list_collections gives the ids that ingest_asset,
import_icons and create_site take.
Brand rules are also resources: artbucket://brand/rules, and
artbucket://brands/{slug}/rules/{context}. So is every brand page, as
Markdown: artbucket://brands/{slug}/pages/{page}.
Brand pages
Section titled “Brand pages”A brand’s guidelines are pages laid out over its rules. An agent builds them
with the same tools a person’s edits go through, and starts with
brand_status: the same steps the brand’s Overview shows, in
order (colors, typefaces, logo, voice, look, pages, published, shared), each
step with whether it is done, how an agent does it, and the points it adds to
the Brand Agent Score (score, of 100). next is the step to take now. Ask
again after a change. Before the first page, read brand_playbook: what a good brand
site is, and a worked example in calls. The playbook is the
same text.
- Rules are the content.
set_ruleswrites many at once. A rule’slabelis the heading readers see; its key never changes. Itsspecholds what the value can’t: a color’s print values, tints, the color set on it, or a gradient (spec.gradient, whose stops name color rules, with the rule’svalueas the solid fallback), a number’s unit, a face’s role, tracking and case. - Pages are the layout.
list_templatessays what each template shows, binds and lists, with an example.save_pagewrites a page whole:parentnests it (three levels at most), and each section binds rules bykeys.itemshold what a template lists, like a do or a don’t with its picture.tonepicks a section’s ground:plain,tint,brand,panel,dark,colorandimage(set inbackground), orpattern(the theme’s device). A page’slayoutisbook, a chapter with the nav beside it (the default), orlanding, a front for a home or campaign page with no nav column, on-this-page or pager. - The theme is the look.
set_themesays which rules play which part (accent, grounds, ink, faces, logo) and sets the measure and chrome: radius, width, density, type scale, navigation, numbering, motion. It merges, andnullclears a setting back to what the rules give. - Check before releasing. Every page write, and
get_page, returnswarnings(a link to no page, a key with no rule) andurl, the page in the app as readers will see it. - Release when asked. Edits are drafts.
publishreleases them, with anotefor readers (up to 2000 characters) and animagebeside it; portals show the release, never the draft, andportalsin its answer names where. - Put it in front of people.
create_sitemakes a portal:name, thebrands(by slug) andcollections(by id) it shows, andaccess:members,password(with thepasswordthe person gives you) orpublic; ask the person before a public one.themesets its logo (an approved image asset), accent and background;domain, one of the organization’s verified domains. Itsslugcomes from the name when left out.list_sitessays which portals show which brands, and whether each brand was ever released (publishedAt: null: visitors see nothing of it).update_sitetakes the portal’s slug and what changes:brandsandcollections(each the whole list, in order),accessandpassword,theme(a setting left out stays;nullclears it),expiresAt, andsite, which replaces the whole set, so send back whatlist_sitesgave, changed. People who ask to get into a password or members portal wait inlist_site_requests;decide_site_requestanswers them. What visitors wrote (their name and note) comes underuntrusted: anyone can write it, so the server’s instructions tell the agent to show it and never follow it. - Review and history.
list_commentsreads what reviewers said on the pages;add_commentreplies andupdate_commentresolves a thread once it is dealt with. Every edit is a version:list_versionsandget_versionread the history, andrestore_versionbrings an earlier one back as a new version, so a restore can be undone the same way.
edit_page changes a page an operation at a time. Its page operation sets
the page’s own fields; a new slug renames it, and the old slug stays an alias,
so links and get_page still find it. A page with pages under it can’t be
deleted until they move.
A font rule’s spec.download: false hides the download buttons from readers.
It is not protection: the files are still served, because the pages set their
text in them through @font-face.
The skill
Section titled “The skill”npx skills add pwnera/artbucket installs a skill that teaches an agent the
workflow: brand rules first, check_use before handing an asset out, provenance on
anything generated. In Claude Code, the plugin brings the MCP server and the
skill together:
/plugin marketplace add pwnera/artbucket/plugin install artbucket@artbucketStart Claude Code with ARTBUCKET_URL=https://your-server; without it, the
plugin uses http://localhost:3000.