> ## Documentation Index
> Fetch the complete documentation index at: https://docs.contenthero.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Brand

> Brand kits and the knowledge base that grounds generations in your voice.

Brand kits and the knowledge base that grounds generations in your voice. 9 tools.

Every tool below is exposed by the hosted MCP server at `https://mcp.contenthero.ai` and by the `@contenthero/mcp` npm package. A <Badge>write</Badge> tool changes your account; a <Badge>read</Badge> tool does not.

### `list_brand_kits`

<Badge>read</Badge>

List the account's brand kits (default first). Excludes archived kits unless archived=true; set favorited=true for only favorites. Call get\_brand\_kit for one kit's full brand context (voice, visual identity, audience, sections, accounts, knowledge) to write on-brand content.

<ParamField body name="archived" type="boolean">
  Only archived brand kits (default excludes archived).
</ParamField>

<ParamField body name="cursor" type="string">
  The previous page's cursor.
</ParamField>

<ParamField body name="favorited" type="boolean">
  Only favorited brand kits.
</ParamField>

<ParamField body name="limit" type="integer">
  How many to return.
</ParamField>

### `get_brand_kit`

<Badge>read</Badge>

Get one brand kit. A brand kit is a set of named sections, each one Markdown document, plus its visual identity. THREE WAYS TO READ, chosen by what you pass: (1) detail:'summary' lists every section with its key, role, version, length and outline (its own headings) but NO body, the cheap first read, so start there and decide what the task needs; (2) any of keys, roles or tabs returns just those sections with their bodies (the filters combine with AND), and history:true adds each one's earlier versions; (3) neither returns the whole kit: every section, visual identity (logos, colors, typography), linked brand and inspiration accounts, and a knowledge-base summary. A section's key is stable and is how you address it; its role says what a starter section means and is the same in every kit, whatever the user named it. Every section carries a version: pass it back as expectedVersion when you change it with update\_brand\_kit.

<ParamField body name="brandKitId" type="string" required>
  The brand kit id from list\_brand\_kits.
</ParamField>

<ParamField body name="detail" type="`summary` \| `full`">
  'summary' lists every section without its body; 'full', the default, returns the whole kit. Cannot be combined with a filter.
</ParamField>

<ParamField body name="history" type="boolean">
  With a filter, also return each section's earlier versions, newest first.
</ParamField>

<ParamField body name="keys" type="string[]">
  Section keys, as the summary lists them.
</ParamField>

<ParamField body name="roles" type="string[]">
  Section roles, as the summary lists them.
</ParamField>

<ParamField body name="tabs" type="string[]">
  'overview', 'voice' or 'visual'.
</ParamField>

### `create_brand_kit`

<Badge>write</Badge>

Create a brand kit. THREE SOURCES, chosen by what you pass: (1) EMPTY, just a name, then fill it in with update\_brand\_kit; or FROM A SOCIAL PROFILE, pass its url in brandAccounts (your own) or inspirationAccounts (a creator you watch) with no name at all, and the kit is named after the handle and starts ingesting that account's posts if it is YouTube or Instagram; (2) IMPORTED, pass websiteUrls (primary first) and/or the brand's own YouTube or Instagram in brandAccounts, with extract:true, and ContentHero takes the colors, typography, logos and assets from the first website and analyzes every website and those accounts' posts to write the kit's empty sections, which is by far the fastest way to get a real kit; (3) A COPY, pass duplicateFrom with an existing kit id, which copies its sections and brand media (assets re-link rather than duplicate, so a copy costs no storage). Every new kit starts with its starter sections, empty. A brand with NO WEBSITE (so nothing to extract) is built by passing its content directly: sections, written by key into those starter sections, and logos, whose entries may name outputId to bring in a generation you just made rather than a url. With extract it RETURNS IMMEDIATELY, before the kit has any content: that empty kit is the handle, and the sections fill in over the next few minutes (longer while a newly linked account's posts arrive), so poll analysisStatus and extractionStatus with get\_brand\_kit rather than assuming it failed. name is OPTIONAL when websiteUrls or a social profile url is given: it defaults to the first site's hostname or the @handle, a placeholder extraction or you overwrite later. Brand kits are capped by plan, so this fails with a limit error near the cap, and a duplicate counts against it like any other kit. Requires the brand:write scope.

<ParamField body name="assets" type="object[]">
  The kit's brand assets, each \{ url | outputId, name? }.
</ParamField>

<ParamField body name="brandAccounts" type="value[]">
  The account owner's OWN profiles. A tracked-account id, or \{ platform?, handleOrUrl } to ADD one and start ingesting it.
</ParamField>

<ParamField body name="brandColors" type="object[]">
  The kit's palette, each \{ hex, name?, role? }.
</ParamField>

<ParamField body name="duplicateFrom" type="string">
  Copy an existing brand kit id instead of starting empty.
</ParamField>

<ParamField body name="extract" type="boolean">
  Import the kit from websiteUrls and its own accounts in brandAccounts. Returns at once; poll analysisStatus and extractionStatus.
</ParamField>

<ParamField body name="inspirationAccounts" type="value[]">
  Competitor/creator profiles they watch. Same entry shape as brandAccounts.
</ParamField>

<ParamField body name="logos" type="object[]">
  The kit's logos, each \{ url | outputId, name?, isPrimary?, isDisplay?, layout?, colorMode? }. Use outputId to bring in a generation.
</ParamField>

<ParamField body name="name" type="string">
  The kit's name. Optional when websiteUrls or a social profile is given.
</ParamField>

<ParamField body name="sections" type="object[]">
  Section content, each \{ key, body } to fill a starter section, or \{ sectionName, tab, body? } to add your own.
</ParamField>

<ParamField body name="typography" type="object">
  The kit's fonts, \{ titleFont?, bodyFont? }.
</ParamField>

<ParamField body name="websiteUrls" type="string[]">
  The brand's websites, primary first. The first gives the logos, colors and fonts; every one feeds the analysis.
</ParamField>

### `update_brand_kit`

<Badge>write</Badge>

Update a brand kit: its section content, colors and fonts, brand media, which kit is the DEFAULT, and which tracked accounts it is LINKED to. Only what you pass changes. Get the current kit first with get\_brand\_kit. SECTION CONTENT is written with sections, naming only the sections you change, all or nothing. An entry with a key edits that section: body (Markdown) replaces the whole section, revertTo restores an earlier version as a new one, sectionName renames it, width sets its card to full or half. An entry without a key adds a section of your own, with sectionName and tab. Pass each edited section's version as expectedVersion: if any of them changed since you read it, NOTHING is written and the error lists each stale section's current version and body, so re-read, reapply your change, and retry. To remove a section, archive it with archive (assetType brand\_kit\_section). A section entry's afterId, beforeId or position moves that section within its tab; its neighbors are section ids. Requires the brand:write scope. afterId, beforeId or position moves the kit itself among the caller's kits. extract:true RE-RUNS the import: the visuals from its first website and the analysis of its websites and own accounts, which writes only into sections still empty and returns immediately (poll analysisStatus and extractionStatus via get\_brand\_kit). logos/assets/brandAccounts/inspirationAccounts are DECLARATIVE: a patch REPLACES the whole list, so pass the full set and use \[] to clear. THIS IS ALSO HOW YOU ADD NEW MEDIA TO A KIT: a logo or asset entry names either a url it already has, or outputId to bring in a generation that is not in the kit yet ('\<id>', or '\<id>-2' for variation 2 of a batch), whose bytes get COPIED into the kit so trashing that generation later cannot empty it. To add a logo, read the kit, append one entry, and send the whole list back; sending an outputId twice adds it twice. brandAccounts are the account owner's OWN profiles (performance), inspirationAccounts are competitors and creators they watch; they are separate lists because they mean opposite things. AN ENTRY IS EITHER a tracked-account id you already have, OR \{ platform?, handleOrUrl } to ADD a profile that is not tracked yet, which is what STARTS ingesting its posts (a full profile url carries its own platform, so platform is only needed for a bare handle). isDefault only accepts true (passing false would leave the account with no default at all, so to move the default, name the kit that should hold it).

<ParamField body name="brandKitId" type="string" required>
  The brand kit id.
</ParamField>

<ParamField body name="afterId" type="string">
  Place it immediately after this item of the same list.
</ParamField>

<ParamField body name="assets" type="object[]">
  The kit's brand assets, each \{ url | outputId, name? }. REPLACES the list; \[] clears it.
</ParamField>

<ParamField body name="beforeId" type="string">
  Place it immediately before this item of the same list.
</ParamField>

<ParamField body name="brandAccounts" type="value[]">
  The account owner's OWN profiles. Each entry is a tracked-account id, or \{ platform?, handleOrUrl } to ADD one and start ingesting it. REPLACES the list; \[] clears it.
</ParamField>

<ParamField body name="brandColors" type="object[]">
  The kit's palette, each \{ hex, name?, role? }. REPLACES the list; \[] clears it.
</ParamField>

<ParamField body name="extract" type="boolean">
  Re-run this kit's import from its websites and own accounts. Returns immediately; poll analysisStatus and extractionStatus.
</ParamField>

<ParamField body name="inspirationAccounts" type="value[]">
  Competitor/creator profiles they watch. Same entry shape as brandAccounts. REPLACES the list; \[] clears it.
</ParamField>

<ParamField body name="isDefault" type="boolean">
  Make this the default kit, un-defaulting every other.
</ParamField>

<ParamField body name="logos" type="object[]">
  The kit's logos, each \{ url | outputId, name?, isPrimary?, isDisplay?, layout?: horizontal|stacked|icon|wordmark, colorMode?: full\_color|light|dark|grayscale }. REPLACES the list; \[] clears it. Exactly one ends up primary (the kit's cover); name none and the first wins.
</ParamField>

<ParamField body name="name" type="string">
  Rename the kit. This is the label in the UI, not the business name.
</ParamField>

<ParamField body name="position" type="`top` \| `bottom`">
  Place it at an end of the list instead of beside an item. Name neighbors or a position, not both.
</ParamField>

<ParamField body name="sections" type="object[]">
  Section writes: only the sections you change, all or nothing. \{ key, body, expectedVersion } edits one; \{ sectionName, tab, body? } adds one.
</ParamField>

<ParamField body name="typography" type="object or null">
  The kit's fonts, \{ titleFont?, bodyFont? }. MERGES: a font left out keeps its value; null clears both.
</ParamField>

<ParamField body name="websiteUrls" type="string[]">
  The brand's websites, primary first. REPLACES the list; \[] clears it. Stored only: pass extract to import from them.
</ParamField>

### `list_brand_knowledge`

<Badge>read</Badge>

The complete, paginated index of a brand kit's knowledge items (titles and metadata, no bodies). Use it to browse what exists, or to find an item's id before get\_brand\_knowledge or remove\_brand\_knowledge. For relevance retrieval, use search\_brand\_knowledge instead. Requires the brand:read scope.

<ParamField body name="brandKitId" type="string" required>
  The brand kit id.
</ParamField>

<ParamField body name="cursor" type="string">
  The previous page's cursor.
</ParamField>

<ParamField body name="limit" type="integer">
  How many to return.
</ParamField>

### `get_brand_knowledge`

<Badge>read</Badge>

Get one knowledge item's stored body by id (the capped anchor text; the full document is embedded for search, not stored verbatim). Use search\_brand\_knowledge for the deep content. Requires the brand:read scope.

<ParamField body name="brandKitId" type="string" required>
  The brand kit id.
</ParamField>

<ParamField body name="knowledgeId" type="string" required>
  The knowledge item id (from list\_brand\_knowledge or search\_brand\_knowledge).
</ParamField>

### `add_brand_knowledge`

<Badge>write</Badge>

Add an item to a brand kit's knowledge base so it can be searched later. This is how the brand's knowledge grows over time: capture a lesson learned, a brand decision, an asset description, an article, or a video. Source can be text (a note), url (a page to scrape), youtube (a video transcript), or file. For a file, pass either fileData (base64, best for small documents and images) or fileUrl (a hosted URL the server fetches, needed for large files and video/audio). Requires the brand:write scope. SPENDS CREDITS for images, video and audio (text, links, YouTube and documents are free): pass getCost to preview the price first, which runs nothing and charges nothing.

<ParamField body name="brandKitId" type="string" required>
  The brand kit id.
</ParamField>

<ParamField body name="sourceType" type="`text` \| `url` \| `youtube` \| `file`" required>
  How the content is provided.
</ParamField>

<ParamField body name="fileData" type="string">
  For sourceType "file": base64-encoded file bytes (small documents and images).
</ParamField>

<ParamField body name="fileExt" type="string">
  For sourceType "file": the extension without a dot, e.g. "pdf". Inferred from fileUrl when omitted.
</ParamField>

<ParamField body name="fileUrl" type="string">
  For sourceType "file": a hosted URL the server fetches (large files, video, audio).
</ParamField>

<ParamField body name="getCost" type="boolean">
  Return the credit cost estimate instead of adding (video and audio are measured, not processed; nothing is charged).
</ParamField>

<ParamField body name="text" type="string">
  For sourceType "text": the note body.
</ParamField>

<ParamField body name="title" type="string">
  Optional title (otherwise derived from the content).
</ParamField>

<ParamField body name="url" type="string">
  For sourceType "url" or "youtube": the link.
</ParamField>

### `remove_brand_knowledge`

<Badge>write</Badge>

Remove a knowledge item and its embedding chunks from a brand kit's knowledge base. Requires the brand:write scope.

<ParamField body name="brandKitId" type="string" required>
  The brand kit id.
</ParamField>

<ParamField body name="knowledgeId" type="string" required>
  The knowledge item id to remove.
</ParamField>

### `search_brand_knowledge`

<Badge>read</Badge>

Semantic search over a brand kit's knowledge base (everything the owner has uploaded: notes, docs, articles, video transcripts). Returns the most relevant passages, ranked. This is the deep-grounding read: use it to pull what the brand has said about a topic before drafting or deciding. Requires the brand:read scope.

<ParamField body name="brandKitId" type="string" required>
  The brand kit id (from list\_brand\_kits / get\_brand\_kit).
</ParamField>

<ParamField body name="query" type="string" required>
  What to search for, in natural language.
</ParamField>

<ParamField body name="limit" type="integer">
  Max matches (default 8).
</ParamField>

<ParamField body name="threshold" type="number">
  Minimum similarity 0-1 (default 0.45).
</ParamField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.