list_brandsRead only
The brands this key can read, with their slugs, versions and consistency scores.
No arguments.
Agents and tools read your brand, check their work against it and keep it up to date. Connect over MCP, or call the REST API from anything.
Start
bb_live_ and is shown once. A key reads and changes every brand in its workspace, so keep it out of code you share.Authorization: Bearer bb_live_…curl https://brandbook.app/api/v1/brands \
-H "Authorization: Bearer $BRANDBOOK_KEY"MCP
The MCP server speaks JSON-RPC over Streamable HTTP at https://brandbook.app/api/mcp and authenticates with the same bearer key. Any client that can send a header to a remote server can use it directly.
In ~/.cursor/mcp.json, or .cursor/mcp.json in a project:
{
"mcpServers": {
"brandbook": {
"url": "https://brandbook.app/api/mcp",
"headers": {
"Authorization": "Bearer bb_live_…"
}
}
}
}claude mcp add --transport http brandbook https://brandbook.app/api/mcp \
--header "Authorization: Bearer bb_live_…"Or check it into .mcp.json and keep the key in your environment:
{
"mcpServers": {
"brandbook": {
"type": "http",
"url": "https://brandbook.app/api/mcp",
"headers": {
"Authorization": "Bearer ${BRANDBOOK_KEY}"
}
}
}
}In .vscode/mcp.json:
{
"servers": {
"brandbook": {
"type": "http",
"url": "https://brandbook.app/api/mcp",
"headers": {
"Authorization": "Bearer bb_live_…"
}
}
}
}Claude Desktop adds remote servers as connectors, which sign in with OAuth rather than a key. Until Brandbook offers OAuth, run the server through the mcp-remote bridge in claude_desktop_config.json (needs Node):
{
"mcpServers": {
"brandbook": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://brandbook.app/api/mcp",
"--header",
"Authorization:${BRANDBOOK_AUTH}"
],
"env": {
"BRANDBOOK_AUTH": "Bearer bb_live_…"
}
}
}
}MCP
Every tool is scoped to the key's workspace. brand is a slug from list_brands, and can be left out when the workspace has one brand. Tools that change the brand bump its version and write a line to its changelog, the same as a change made in the app. This list is read from the server itself.
The brands this key can read, with their slugs, versions and consistency scores.
No arguments.
Call before writing anything for this brand. Returns the rules to follow as data (colours with roles, logo rules, fonts, voice traits, words to use and never use, voice and imagery rules, tone, the rules checks test, print colour values, messaging, partner rules and contacts when the brand book shows them, and the channel's rules when you name one) plus the full brand.md. Follow it exactly; don't invent colours, fonts or claims it doesn't give you.
Arguments
Just the rules you need, as a list: every rule the brand has (voice, visual, legal, channel), filtered to a channel, an audience, a category or a search. Each has an id (V-07), how strict it is (must or should), what it applies to, and whether check_output tests it.
Arguments
Call on anything you wrote or designed for the brand before you hand it over. Returns a 0–100 score, a verdict (pass, needs_fix, fail), findings with fixes, and an on-brand rewrite when the voice is off. Send text, an image URL, or both; add the non-neutral colours a design uses to check the palette. Fix every error and check again.
Arguments
A short, direct answer to a question about the brand: "Can I put yellow text on green?", "What do we call the people we help?".
Arguments
Change one section of the brand system. Only when the person asks you to change the brand itself, not to follow it. Object sections (logo, type, voice, imagery) merge with what is there, so { "rules": [...] } leaves the voice traits alone; arrays inside them (voice.rules, logo.donts, colours) replace the whole list, so read the current list with get_brand_context first and send it back with your change. Bumps the version and writes a changelog line.
Arguments
Add one rule to the brand without touching the rest. Send exactly one of: rule (a voice rule, e.g. "No exclamation marks in headlines"), say + avoid (a word swap, e.g. say "the crew", avoid "customers"), or imagery_rule (e.g. "Credit the photographer on every photo"). Only when the person asks you to add it. A rule the brand already has changes nothing.
Arguments
REST API
Base URL https://brandbook.app/api/v1. Send and receive JSON; every request carries Authorization: Bearer bb_live_…. A {slug} must be a brand in the key's workspace, or the answer is a 404. CORS is open, but a key in browser code is a key anyone can read: call the API from a server.
The brands in the key's workspace, oldest first.
curl https://brandbook.app/api/v1/brands \
-H "Authorization: Bearer $BRANDBOOK_KEY"{
"data": [
{
"slug": "late-club",
"name": "Late Club",
"domain": "lateclub.co",
"version": "1.3",
"health": 89,
"status": "live",
"guidelines": "https://brandbook.app/b/late-club"
}
]
}health is the brand's consistency score, 0–100, or null before its first check. guidelines is its microsite.
The whole brand system: the structured spec every Brandbook feature reads, and the same thing as brand.md.
Query
markdown returns brand.md as text/markdown; tokens returns tokens.json. Default json.curl https://brandbook.app/api/v1/brands/late-club \
-H "Authorization: Bearer $BRANDBOOK_KEY"{
"slug": "late-club",
"name": "Late Club",
"version": "1.3",
"guidelines": "https://brandbook.app/b/late-club",
"spec": {
"name": "Late Club",
"tagline": "Dressed for after dark.",
"description": "…",
"logo": { "monogram": "LC", "minSize": "…", "donts": ["…"] },
"colours": [
{ "name": "Club Violet", "hex": "#6B3BFF", "role": "primary", "share": 30 }
],
"type": { "display": { "family": "…" }, "body": { "family": "…" } },
"voice": { "traits": [], "sayAvoid": [], "rules": [], "examples": [], "headlines": [] },
"imagery": { "description": "…", "photos": [], "rules": [] },
"channels": {}
},
"markdown": "# Late Club brand\nVersion 1.3 · …"
}Change one section of the brand. The value is checked against that section's schema; the change bumps the version and is logged in the changelog as “via API: …”.
Body
tagline, description, logo, colours, type, voice, imagery.tagline and description; the whole palette for colours. Object sections merge with what is there, so { "headlines": [...] } leaves the voice traits alone. Lists inside them replace the whole list.curl -X PATCH https://brandbook.app/api/v1/brands/late-club \
-H "Authorization: Bearer $BRANDBOOK_KEY" \
-H "Content-Type: application/json" \
-d '{"section": "tagline", "value": "Made for the night, built to last."}'{
"brand": "late-club",
"version": "1.4",
"changed": true,
"summary": "via API: Tagline: “Made for the night, built to last.”"
}A value that matches what is there returns "changed": false and keeps the version.
Add one rule without touching the rest of the brand. Send exactly one kind.
Body
curl -X POST https://brandbook.app/api/v1/brands/late-club/rules \
-H "Authorization: Bearer $BRANDBOOK_KEY" \
-H "Content-Type: application/json" \
-d '{"say": "pieces", "avoid": "product"}'{
"brand": "late-club",
"version": "1.4",
"added": true,
"summary": "via API: Voice: say “pieces”, not “product”"
}A rule the brand already has returns "added": false and keeps the version.
Check copy, a design or a palette against the brand before it ships. The rule engine runs first; with AI on, a model review adds findings and reads images. Each check is logged on the brand's Check page.
Body
curl -X POST https://brandbook.app/api/v1/check \
-H "Authorization: Bearer $BRANDBOOK_KEY" \
-H "Content-Type: application/json" \
-d '{"brand": "late-club", "text": "Only 2 left!!! Drop 05 is selling fast", "colours": ["#6B3BFF", "#E4002B"]}'{
"brand": "late-club",
"score": 54,
"verdict": "needs_fix",
"findings": [
{
"severity": "error",
"category": "voice",
"title": "Language: “only 2 left”",
"detail": "No fake scarcity, ever"
},
{
"severity": "error",
"category": "voice",
"title": "Language: “selling fast”",
"detail": "No fake scarcity, ever"
},
{
"severity": "error",
"category": "voice",
"title": "Tone: “!!!”",
"detail": "Late Club headlines never use exclamation marks.",
"fix": { "type": "strip_exclamations" }
},
{
"severity": "warning",
"category": "colour",
"title": "Colour: #E4002B isn't a brand colour",
"detail": "Use one of Club Violet, Acid Lime, Bone, After Black."
}
],
"suggestion": "Drop 05 is out now. Made once, never restocked.",
"check_id": "dac0d0d2-…",
"notes": []
}verdict is pass (85 and up), needs_fix (50–84) or fail. suggestion is an on-brand rewrite when the voice is off, else null. notes says when part of the input wasn't read.
A short, direct answer to a question about the brand. Without AI, colour pairings, words and logo rules are still answered from the rules.
Body
curl -X POST https://brandbook.app/api/v1/ask \
-H "Authorization: Bearer $BRANDBOOK_KEY" \
-H "Content-Type: application/json" \
-d '{"brand": "late-club", "question": "Can I put lime text on black?"}'{
"brand": "late-club",
"question": "Can I put lime text on black?",
"answer": "Yes, for any size of text. Acid Lime and After Black are 16.3:1."
}Reference
Every error has the same shape, with a message written to be shown or acted on:
{
"error": {
"code": "brand_not_found",
"message": "No brand \"nope\" in this workspace. List brands for the slugs."
}
}| Status | code | When |
|---|---|---|
| 400 | invalid_json | The body isn't JSON, or isn't an object. |
| 400 | invalid_request | A field is missing or doesn't fit its schema. The message names it. |
| 401 | unauthorized | No key, or a revoked one. The WWW-Authenticate header says which. |
| 404 | brand_not_found | No brand with that slug in the key's workspace. |
| 405 | method_not_allowed | That path doesn't take that method. See the Allow header. |
| 429 | rate_limited | Too many requests. Wait for Retry-After seconds. |
| 500 | internal | Our side failed. Try again in a moment. |
Over MCP, a problem with the arguments comes back as a tool result with isError: true and the same message, so the agent can fix the call and try again.
Reference
Limits are per key, over a rolling minute: 120 requests across the REST API and the MCP server, of which 30 may be /check or /ask calls. Past the limit you get a 429 with Retry-After: 60 (over MCP, a JSON-RPC error with the same status). Need more? Use a key per integration.
Reference
Two files any tool can read without an SDK. brand.md is the brand as Markdown, written for a model's context window: colours with roles, type, voice, words to use and avoid, logo and imagery rules. tokens.json is the colours and type as Design Tokens (the W3C DTCG format), for Figma and code.
curl https://brandbook.app/api/brands/late-club/brand.md
curl https://brandbook.app/api/brands/late-club/tokens.json?downloadThey are public when the brand's microsite is public; otherwise send a key for the brand's workspace. Add ?download to save as a file. The same files come from GET /api/v1/brands/{slug}?format=markdown and ?format=tokens, and are on Settings › API & connections.