# Archetype OS — integration guide > A brand's design system — tokens, logos, components, templates, icon systems, > asset library and voice documents — authored by the people who own the brand > and served to AI tools so everything gets generated on-brand by default. Archetype does not infer a brand from a rendered page. A scrape can enumerate every computed value on a homepage; it cannot say which of them were decisions. Archetype serves what the brand's owners authored — which white is *the* white, which components exist, what the brand claims and how it says it — including the parts no page shows. ## The serving model RAG-style, index → detail. Orient first, then fetch only what you need by handle: 1. `get_brand` with no arguments returns the brief: all tokens and logo usage rules inline, the voice documents, and an inventory of components, artifacts, templates and library files, each carrying the handle that fetches it. `{"domain": "info"}` is the cheaper version when you only want counts. 2. `{"domain": ""}` returns that domain's index, and the same call with `"handle"` returns one item's full detail. The domains are brief, info, tokens, assets, components, icons, artifacts, templates, files, voice, schema. 3. `search_brand` locates anything by keyword when you don't know where it lives. Every hit carries the exact call that fetches its detail. This matters because the response is charged as your context. Pull the index, pick the handle, fetch that one thing — not the whole domain. One tool covers every domain rather than one tool each, because a host asks permission per tool: ten names meant ten approval dialogs before any work appeared. The v2 names (`get_brand_tokens`, `get_brand_components`, and the rest) still answer if you already learned them — they map to the matching domain — but they are no longer advertised. ## Reuse what the brand already owns Never reproduce something this brand already owns from its name, its description, or a summary of it. An index entry identifies an item; only its detail call defines it. Fetch it first with get_brand and the handle the index gave you — artifacts by handle, components by key, templates by key, assets by name, icons by slug — and use what comes back verbatim. If get_brand isn't in your tool list yet, look it up by name before deciding you can't fetch it. If you genuinely can't reuse the real thing on the surface you're building for, port it from the source it does have and say so in your output; never present an approximation as the brand's own. ## When the brand has no answer When this brand has no value for something you need — a step the scale can't express, a pairing that isn't defined, a component that doesn't exist — do not invent one silently and do not stall. Use the nearest value the brand does define, then say so in your output: what was missing, what you used instead, and where. Report the gap; never paper over it. ## Connect the MCP server Authentication is OAuth 2.1. An access token is bound to exactly one brand, and the server names that brand in `serverInfo` and in every tool description, so a model can always see whose design system it is holding. Endpoint: `https://www.heyarchetype.com/api/mcp/` — Settings → Agents shows each brand's full address. Each brand is its own server, so someone with several brands registers one per brand and chooses between them in the client: Claude's connector toggle, per chat or per Project; a project-scoped config in Claude Code or Cursor. A token for one brand is refused at another's address. The bare `https://www.heyarchetype.com/api/mcp` still works and asks which brand to connect when you sign in. **Claude** — In Claude (web or desktop), open Settings → Connectors → Add custom connector, name it after the brand, and paste: ```text https://www.heyarchetype.com/api/mcp/ ``` **Claude Code** — In a terminal, run: ```shell claude mcp add archetype- --scope user --transport http https://www.heyarchetype.com/api/mcp/ ``` **Cursor** — Add to ~/.cursor/mcp.json (or .cursor/mcp.json in your project): ```json { "mcpServers": { "archetype-": { "url": "https://www.heyarchetype.com/api/mcp/" } } } ``` **Codex** — In a terminal, run: ```shell codex mcp add archetype- --url https://www.heyarchetype.com/api/mcp/ ``` **ChatGPT** — In ChatGPT on the web, turn on Developer mode in Settings, then create a new MCP app with OAuth, name it after the brand, and paste: ```text https://www.heyarchetype.com/api/mcp/ ``` **v0** — In v0, click Add MCP (in Settings or the prompt form), choose a custom server, and paste this URL: ```text https://www.heyarchetype.com/api/mcp/ ``` **Lovable** — In Lovable, open Connectors, click + and choose MCP server, name it after the brand, keep OAuth, and paste: ```text https://www.heyarchetype.com/api/mcp/ ``` **Other** — Point any MCP client that supports remote (HTTP) servers with OAuth at: ```text https://www.heyarchetype.com/api/mcp/ ``` Three tools read. The fourth, `update_brand`, changes one item at a time — a token, a voice document, the brand's info, a logo and its usage rules, a library file, an icon system or a custom icon, a component example, an artifact, a template's copy — and only on a connection the user approved with "Allow edits" (the `brand:write` scope) while able to edit the brand. Every change is logged and returns a `changeId` that undoes it. Use it when the user asks to change the brand itself, never to make the brand match something you built. Every asset URL the tools return is a stable `embedUrl`: safe to put in generated output, and it keeps resolving, because it always redirects to the current file. ## Tools ### `get_brand` Read your brand's design system. Pick a `domain`; call it bare for that domain's index, then again with the `handle` the index gave you for the detail. The index identifies an item, only the detail defines it. No arguments returns the brief, which is where to start. Domains: - brief: Start here. Tokens and logo rules inline, the voice docs, and an inventory of everything with the handle that fetches it. - info: Name, slug and a count of everything served. - tokens: Design tokens as W3C DTCG JSON; semantic colours carry a value per mode. handle: one of color, typography, spacing, radius, shadow. - assets: Logos and favicons: SVG or a stable URL, plus usage rules. handle: asset name. - components: The UI kit. Bare: every component's properties and example names. handle: a component key, for each example's real HTML + CSS; reproduce it as given. - icons: The icon systems to use, never arbitrary icons. handle: set slug. - artifacts: Bespoke brand code: backgrounds, patterns, generative graphics, motion. handle: artifact handle, for source to use verbatim. - templates: Finished layouts the brand ships (social, email, ads, pages, slides): start from one; if several fit and the user hasn't picked, ask which. handle: template key. - files: Asset library: photos, illustrations, PDFs, filtered by tag or search. handle: file name; a PDF returns its text. - voice: Voice and messaging docs: the source for any copy. handle: slug, or "all". - schema: How to write with update_brand: each domain's value shapes, the component model (properties, tags, one instance per example) and every limit. Read it before writing. Arguments: - `domain?` (brief | info | tokens | assets | components | icons | artifacts | templates | files | voice | schema) — Which part of the brand to read. Defaults to "brief". - `handle?` (string) — The item to fetch within the domain, as the index gave it: a token category, an asset name, a component key, an icon set slug, an artifact handle, a template key, a library file name, or a voice document slug. Omit it for that domain's index. Ignored by the domains that have no detail call (brief, info). - `example?` (string) — domain=components only. Example name or id, to narrow a component to one example. - `mode?` (string) — domain=tokens, or components and templates with a handle. Where the brand has modes, the one to resolve colours in (e.g. "dark"): $value and :root become that mode's, the others still served beside them. Omit it for the default. - `include_tokens?` (boolean) — domain=components with a handle only. false leaves out the `tokens` :root block, which is the same for every component — fetch it once, then read components without it. - `variant?` (string) — Deprecated alias for `example`. - `intent?` (string) — domain=icons only. What the icon needs to mean, to pick one from a custom set (e.g. "download"). - `include_code?` (boolean) — domain=artifacts only, with no handle: include full source for every artifact (large). - `type?` (social | web | app | files) — domain=templates only, with no handle: only templates of this kind. - `frame?` (string | number | (string | number)[]) — domain=templates with a handle only. Only these frames, by name or number from 1 — the pages you picked from a page library. - `tag?` (string | string[]) — domain=files only. Match assets carrying this tag. Give several to narrow further — an asset must carry all of them. - `search?` (string) — domain=files only. Substring match over name, description, usage, and tags. - `pages?` (string) — domain=files with a handle only. Which pages of a PDF to read, e.g. "3" or "5-12". Omit it for as much of the document as fits in one response, starting at page 1. ### `search_brand` Keyword search across everything your brand has: token names/roles, logo usage, component and variant names, artifact names/descriptions/code, library file names/tags/descriptions and the text inside PDF documents, and voice document content. Returns typed hits, each with the exact tool call that fetches its full detail. Use it to locate the right item without loading whole domains. Which items are *found* is keyword matching rather than meaning: a multi-word query that matches nothing as a phrase is retried term by term, and a thin or empty result carries a hint naming the browse calls to use instead of rewording. The order they come back in is a separate judgment — when the response carries a `ranking` note, the hits are sorted by how useful each one is for the query, so the top hit is the best answer and not merely the first match. Arguments: - `query` (string) — Case-insensitive keyword or phrase. - `domains?` ((tokens | assets | components | icons | artifacts | templates | files | voice)[]) — Limit the search to these domains; omit for all. ### `check_against_brand` Grade code, CSS, markup or a style object against your brand's authored values, and get back a worst-first fix list. Two kinds of finding, and the difference matters: a **lookup** is exact — a colour or typeface your brand did not author — and names the token to use instead; a **judgment** carries a confidence and covers what no lookup can reach, chiefly a control rebuilt out of raw elements where the kit already has it. Every finding says whether it is drift (the brand has a value; fix it to that), a hardcoded literal (the brand has this exact value; reference it), or a gap (the brand has no value for this — report it, never invent one). With `kind` set to copy, each sentence is also checked against the brand's voice documents, and a contradiction is reported against the line it is on. Pass `url` instead of `subject` to check a live page — a deployed preview, a landing page — as a visitor sees it: it is drawn in a browser, its colours, type and copy are graded, and its logo, components, sections and imagery are looked at against the brand's. That takes up to a minute, spends the brand's AI credits, and returns a `reportUrl` to hand a person. Call this after producing anything the brand will be seen in, and before opening a pull request. Arguments: - `subject?` (string) — The code, CSS, markup or copy to grade. One file at a time — a whole bundle is refused rather than truncated, because a silently half-read subject would report the rest clean. - `kind?` (code | copy) — What the subject is. Defaults to "code". Pass "copy" for prose somebody will read — a landing page, an email, a brand document — and each sentence is also checked against the brand's voice documents. Do not pass it for source files: prose cannot be picked out of code reliably, and a wrong voice finding is worse than a missing one. - `url?` (string) — A live page to check instead of a subject — the whole page as drawn, not its source. Use it for a deployed preview or a published page. Pass `subject` or `url`, never both. - `gaps?` (string[]) — What you had to invent because the brand didn't define it — a component it lacks, a step its scale can't express, a colour for a state — one short sentence each. They reach the brand's team, who decide what the brand should say. Leave it out when nothing was missing. ### `update_brand` Change one thing in your brand's design system, only when the person who connected it has asked for that change — never to make the brand match something you built. Read get_brand {"domain": "schema"} before the first write: it is the contract for every domain's `value`, the component model and the limits, and none of it is repeated here. - One call changes one item, named by the `handle` get_brand gave it (a token path, a voice slug, a logo or file name, an icon set slug, a component key, an artifact handle, a template key). Read it first. - `value` is an object of only the fields to change, or a bare value (a hex, px, a ref). `find` + `replace` edit text in place and must match once. - Components: `value` {name, description, platforms, properties, nested} on the component; add `example` for one example, `value` {name, html, css, tags}. An example is ONE instance of the component, and each interaction state is its own example. `tags` place it on the declared properties and are checked against them. - `create: true` adds the item at the handle (a template takes `value.frames`; `frame` + `create` adds a frame); without it an unknown handle is refused. `delete: true` removes it. - Artwork (logos, library files, custom icons): `value` {source} (a URL the server fetches), {svg} or {data} (base64). Adopt an icon system by creating its catalog key ("lucide"). - Bulk: tokens, components and a custom icon set take `import` — {"source": ""} or {"document": …}; tokens read DTCG, Tokens Studio and Style Dictionary. Validated first, written together, one changeId. Add "dryRun": true to preview, and "duplicates" when it lists any. - Every change returns a `changeId`; `{"undo": ""}` (or "last") reverses it if nothing has changed the item since. `{"undo": {"since": ""}}` rolls back that change and everything you did after it. - Needs a connection approved with "Allow edits"; the refusal says how to enable it. Arguments: - `domain?` (tokens | voice | info | assets | files | icons | components | artifacts | templates | designs) — What kind of thing to change. Required unless `undo` is given. designs: save a document made from a template's pages (create only). - `handle?` (string) — Which item: a token path ("color.brand.500", or "modes" for the brand's light/dark modes), a voice document slug, a logo name, a library file name, an icon set slug ("lucide", or a custom set's), a component key, an artifact handle, or a template key. Not used for info. - `example?` (string) — domain=components only. The example to edit, add or delete, by name. Name it by the component's properties ("Primary · Compact · Hover") and it is placed on them. - `icon?` (string) — domain=icons only. An icon's key within a custom set, to add, edit or delete it. - `frame?` (string | number) — domain=templates only. The frame to edit or delete, by name or by its number from 1 — or, with `create`, the new frame's name. - `value?` (any) — What the item becomes — a bare value (a hex, a number of px, a ref, a family name) or an object of only the fields to change. Artwork goes in as {source}, {svg} or {data}. Each domain's shape is in get_brand {"domain": "schema"}. - `find?` (string) — The exact text to change — in a voice document, a component example's html/css, an artifact's code, or a template frame's html/css. Must occur exactly once, so copy it from what get_brand returned. - `replace?` (string) — What `find` becomes ("" removes it). - `create?` (boolean) — Add a new item at `handle` instead of changing an existing one. - `delete?` (boolean) — Remove the item at `handle`. It can be put back with `undo`. - `import?` (object) — domain=tokens, components or icons, instead of value: many items in one call (icons: `handle` names the custom set, the JSON is {"icons": [{key, name, svg}]}). {"source": ""} or {"document": }; "dryRun": true previews without writing. Tokens also take "sets" (Tokens Studio set names); components take "replaceExamples": true to remove examples the import doesn't list. Shapes are in get_brand {"domain": "schema"}. - `undo?` (string | object) — A changeId from an earlier update_brand, "last" for your most recent change, or {"since": ""} for that change and every later one you made — the checkpoint to roll an import back to. Pass it on its own. ### `get_brand` domains in full The tool description carries one line per domain, because clients cut a description at about 2,000 characters. The full version: - `brief` — The brand brief for your brand, as Markdown: all design tokens and logo usage rules inline, the written voice docs, and an inventory of components, templates, artifacts, icons and library files with the handle that fetches each one. The default, and the place to start. - `info` — your brand's name and slug plus a count inventory of everything this server serves. The cheap orientation call when all you need is what exists and how much of it. - `tokens` — your brand's design tokens — colors and gradients, typography, spacing, radius and shadows — as W3C Design Tokens (DTCG) JSON. Use these values verbatim. `handle` filters to one category (color, typography, spacing, radius, shadow); omit it for all five. Where the brand has modes (light and dark), each semantic colour's value in the others is in its $extensions, and `mode` returns the whole set resolved in one. - `assets` — your brand's logos, favicons and other identity assets: SVG source (when stored inline) or a stable file URL, plus usage rules — when to use, clearspace, min size, misuse. The URL is durable: it always redirects to the current file, so it is safe to embed in generated output. `handle` is one asset name (e.g. "Logo Dark"); omit it for all of them. - `components` — your brand's UI kit. Bare: a lightweight index — every component's key, name and the names of its examples. `handle` is a component key (e.g. "button") and returns the full detail: each example is this brand's REAL HTML + CSS, with values as var(--token) custom properties resolved by a `tokens` :root block served alongside. Reproduce the markup as given — its structure is the component's anatomy — rather than approximating it from a description. Add `example` to narrow to one. - `icons` — The icon systems your brand uses — use the brand's set(s) rather than picking icons arbitrarily. Bare: an index of adopted sets, each with its slug, name, kind (a referenced popular system, or the brand's own custom set), Iconify prefix, style variant and default size. `handle` is a set slug (e.g. "lucide"): for a referenced set you get the reference/import syntax (Iconify id + package import), license and homepage, and you use that system's own icon names; for a custom set you get the full inventory with inline SVG. Add `intent` to ask a custom set which of its icons means something. - `artifacts` — your brand's Artifacts — bespoke brand code the standard component library can't represent: animated and static backgrounds, backdrops, patterns, textures, tiles, generative and procedural graphics, canvas/SVG effects, hero and banner artwork, motion presets, custom interactive elements. Reach for this whenever a design calls for one of this brand's own graphics, and never redraw one from its description — the description names an artifact, the source defines it. Bare: an index (name, handle, description, when-to-use, parameters with the brand's tuned defaults — no source). `handle` returns one artifact's full source code, usage snippet and runtime contract, plus `authoringControls`, the contract to follow when writing or extending an artifact so Archetype can render its controls. Use the code verbatim and apply the brand defaults. `include_code` dumps the source of every artifact at once (large). - `templates` — your brand's Templates — the finished layouts it publishes over and over: social posts and stories, email and newsletter banners and headers, ads, website pages, app screens, slides, covers, one-pagers and other documents. Check here first for any fixed-size artefact this brand ships repeatedly, and prefer starting from a template over composing a layout: it is what this brand actually ships. When more than one fits and the user hasn't picked, ask them which to start from, or whether to build from scratch, before you build. Bare: an index (name, key, type, frames with their sizes and how many slots each has), narrowable with `type`. `handle` is a template key and returns that template's finished markup — every binding already resolved, so the logo, images and colours in it are the brand's real ones — plus a `slots` list saying which parts are meant to vary. - `files` — your brand's asset library — uploaded files (photos, illustrations, textures, and documents such as product handbooks, price sheets and decks as PDFs) organised by tag, each with documented tags/description/usage, dimensions, dominant colors, and a stable `embedUrl` that is safe to embed in generated pages and durable output. Every response leads with the tag vocabulary and how many files carry each tag, so call it bare once to see the vocabulary, then again with `tag` or `search` to narrow instead of pulling everything. `handle` is one file's name (or id) and returns that file alone — for a PDF, with its full text page by page, which is the brand's own material on its products, prices and facts: read it before writing about any of them, and quote it rather than paraphrasing from memory. A long document comes back in parts; `pages` picks which. - `voice` — your brand's voice & messaging documents (Positioning, Audience, Differentiation, Messaging, Voice & Tone, plus custom docs) — the source of truth for what this brand says and how it says it when writing any copy. Bare: an index with each doc's slug, status, word count and excerpt. `handle` is one slug, or "all" for the full corpus. - `schema` — How to change your brand with update_brand, as Markdown: what every domain's `value` takes, how a component is modelled — declared properties, examples placed on them by tags or by name, one instance per example, interaction states as their own examples — how an example is drawn, which token variables exist, every limit, and what the brand can't hold yet. Read it before the first write, not after the first refusal. ## Writing to your brand How `update_brand` changes your brand: what each domain takes, how a component is modelled, and every limit. Use it only when the user asks you to change the brand itself — never to make the brand match something you built. ### Every write - One call changes one item, named by the same `handle` get_brand serves it under. Read it with get_brand first, so you change what is there now. To bring in many tokens or components at once, use an import (below). - `create: true` adds a new item at the handle; without it an unknown handle is refused, so a typo can't add something. `delete: true` removes it. - Every change returns a `changeId`. `{"undo": ""}` (or `"last"`) reverses it, provided nothing has changed the item since. - A refusal says what was wrong and what the call should have been. Fix that and retry; don't work around it with a different domain. - Only works on a connection approved with "Allow edits", by someone who can edit the brand. ### Domains and their values - **tokens** — `handle` is the token's path from get_brand {"domain": "tokens"}. Paths are lowercase and dot-separated. - `color..` takes a hex. - `color.` takes {name, role, base} (base regenerates the ramp from one colour) or {shades: [{step, hex}]}. A step is a string, at most 20 characters. - `color.semantic.` takes a ref like "{color.brand.500}", or {ref, description, modes}. `ref` is its value in the default mode; `modes` sets it in the others, `{"Dark": "{color.ink.900}"}`, and only the modes you name change — `null` puts one back to the default's value. - `modes` is the brand's modes, light and dark the way Figma's variable modes are: the whole list, default first, `["Light", "Dark"]`. It also takes {modes, rename: {"Dark": "Night"}, default: "Dark"}; renaming a mode, removing one or changing the default carries every semantic colour's values with it, in one change. `delete: true` goes back to one mode, keeping the default's values. Only semantic colours change by mode — pairings and gradients follow them; a palette shade is the same in every mode. At most 8 modes, 32 characters a name; a mode is switched in CSS with `data-mode` and its name as a slug ("High Contrast" → `data-mode="high-contrast"`). - `pairing.` takes {background, foreground, usage}. The background may be a gradient ("{gradient.}"); its contrast is then graded at the gradient's worst point. - `gradient.` takes {type: "linear" | "radial" | "conic", angle, stops, description}. `stops` is at least two {color, position, alpha}: color a ref or hex, position and alpha 0–1. - `typography.` takes a family name. A new family starts with one Body style (16/24px, 400); reshape it or add the rest with the next calls. - `typography..