MCP Tools

Handoff exposes a Model Context Protocol server at https://demo.handoff.com/api/mcp. Connect Cursor, Claude, or Windsurf to read design tokens, search components, look up icons, and generate components from design artifacts.

Setup — Cursor & Claude

Connect AI assistants to this Handoff deployment for reference materials, components, sync, design library, and design-to-component generation. MCP uses the same OAuth token as the CLI — run handoff-app login first (step 1).

MCP endpoint on this deployment: https://demo.handoff.com/api/mcp

Get your access token

After handoff-app login, run handoff-app mcp-token to print your token, and paste it in place of PASTE_ACCESS_TOKEN_FROM_CLI_AUTH below. (The token also lives in .handoff/cli-auth.json — keep it out of git.)

handoff-app mcp-token
  1. Create or edit .cursor/mcp.json in your design repo (project-only), or ~/.cursor/mcp.json for all workspaces.
  2. Paste the config below, replace the token, then restart Cursor or open Cursor Settings → MCP and enable the handoff server.
  3. In chat, ask the agent to call handoff_get_project_context first, then use reference, sync, or design tools. Pair with Figma MCP for design-to-code.
{
  "mcpServers": {
    "handoff": {
      "url": "https://demo.handoff.com/api/mcp",
      "headers": {
        "Authorization": "Bearer PASTE_ACCESS_TOKEN_FROM_CLI_AUTH"
      }
    }
  }
}
Common MCP tools
  • handoff_get_project_context — stack profile, paths, workspace summary (call first)
  • handoff_get_stack_guide — Handlebars/React authoring rules
  • handoff_get_reference — catalog, tokens, icons, property-patterns (maintained in Admin → Reference; regenerate after catalog changes)
  • handoff_get_design_guidelines / handoff_get_brand_voice — team settings from Design → Settings
  • handoff_get_component_reference — buttons / inputs / iconography reference images
  • handoff_sync_pull / handoff_sync_push — team sync (patches applied in your repo)
  • handoff_start_component_from_design — design library → component job

Full tool list and scopes: see docs/HANDOFF-MCP-RFC.md in the handoff-app package.

Full local setup guide

Context

handoff_get_brand_voice

Formatted brand voice / copy guidelines from design workspace.

handoff_get_design_guidelines

Team Design.MD guidelines from design workspace settings.

handoff_get_project_context

Project hydration: stack profile, paths, Figma key, translation hints.

handoff_get_stack_guide

Markdown authoring rules for the active stack (bootstrap-handlebars, react-tailwind, react-scss).

handoff_update_brand_voice

Update the team brand voice in design workspace settings (admin + sync:write). Accepts any subset of fields and MERGES over the stored value — omitted fields are left alone, and a field set to "" is cleared. This is the standing copy guidance every future generation inherits (design images, page copy, component previews, DESIGN.md exports), not a per-request override — it changes output for everyone until it is changed again. The response echoes a per-field before/after so the overwritten text is recoverable.

handoff_update_design_guidelines

Replace the team Design.MD guidelines in design workspace settings (admin + sync:write). This REPLACES the whole document — there is no merge, so send the complete text (read the current value with handoff_get_design_guidelines first). These are the standing design instructions every future generation inherits, not a per-request override. The response returns the previous content alongside the new one so the overwritten version is recoverable.

Components

handoff_browse_components

Open an INTERACTIVE inline gallery of the design system's components — a searchable card grid. The user can Select a component to hand it back to you, or Open it in Handoff. Use when the user wants to browse or pick a component; use handoff_search_components for raw catalog data.

handoff_get_component

Component implementation data by id — code/html/sass/css, properties, variants, and usage guidance. Slimmed for context use: excludes the compiled sharedStyles CSS (~97% of the raw row), validationResults, and Figma sync metadata. Each preview may carry a `purpose` — structural (placeholder copy showing the form) / example (real content) / builder (seed for a new block) / edge (stresses the contract) — which is what tells you which one to read or copy; previews with no `purpose` are unclassified, not "generic".

handoff_get_component_reference

Component style reference image for a slot: buttons | inputs | iconography.

handoff_get_reference

Fetch generated reference material by id: catalog | tokens | icons | property-patterns. (May also be passed as "type".)

handoff_search_components

Search the component catalog. Matches every word of the query against a component's id, title, group, tags and description, so word order does not matter. Returns a `use` line saying what each block is for — read it before choosing, because several blocks hold copy and they are not interchangeable.

Tokens

handoff_browse_tokens

Open an INTERACTIVE inline palette of the design system's foundation tokens (color swatches, type specimens, spacing scale). The user can click a token to hand it back to you. Use when the user wants to SEE and pick tokens; use handoff_get_tokens for raw token data.

handoff_export_design_md

Export a compact DESIGN.md framing brief for this design system — system identity, token brief (colors/type/spacing/radius/grid), component vocabulary, brand voice, and design guidelines. Commit it to a project and reference it from CLAUDE.md so an agent has design-system context without a live MCP call. For a multi-axis system, pass brand/scheme to frame the brief around that resolved theme.

handoff_get_tokens

Foundation design tokens (colors, typography, effects, and any spacing/radius/grid when extracted). Slimmed for context use — excludes icon/logo SVGs, per-component token usage, and the SCSS $map. Use handoff_get_icon_catalog/handoff_get_logo_set/handoff_get_component for those. Multi-axis (brand × scheme): the response advertises available `axes`; pass brand/scheme to get axis-resolved tokens under `axisTokens`.

Icons & Logos

handoff_get_icon_catalog

Return the full icon catalog as defined in the design system. Optionally filter by category. Each entry includes id, name, description, category, tags, usage guidance, and source (SVG content or iconify/fa-pro reference).

handoff_get_logo_set

Return all logo variants for the design system, including SVG content, usage guidance, and variant metadata (light/dark/color/mono, primary/alternate/wordmark/icon-only). Optionally filter by variant or form.

handoff_search_icons

Search the icon catalog by name, tag, or description substring. Returns matching IconCatalogEntry objects including SVG content where available.

Assets

handoff_get_asset

Get full details for a single asset including component usages and size info.

handoff_list_asset_collections

List all asset collections (Figma sections or manually created groups).

handoff_search_assets

Search the asset library — logos, icons and images. Matches every word of the query across title, alt text, description and tags; if nothing matches all of them, falls back to any of them and says so. Returns a summary per asset: id, title, type, storageUrl, alt text, description, tags and native dimensions. Use `handoff_get_asset` for full detail including SVG content, file size and component usages.

Design Artifacts

handoff_create_design_artifact

Create design artifact with base64 image (design:write).

handoff_generate_component_from_design

Fetch a design artifact's spec and extracted assets to generate a component locally. If no spec exists yet, queues server-side spec generation. Returns the full spec, markdown, image URLs, and stack guide context for you to implement the component in the local codebase.

handoff_get_component_spec

Get the component specification (structured spec + editable markdown) for a saved DESIGN ARTIFACT — takes an `artifactId`, not a component id. Returns the full ComponentSpec JSON and the rendered markdown for local component generation. **For an existing component's contract (properties, previews, should_do/should_not_do), use handoff_get_component instead.**

handoff_get_design_artifact

Get design artifact by id.

handoff_list_design_artifacts

List saved design library artifacts. Registry mode only.

Design Workbench

handoff_extract_design_assets

DEPRECATED — use handoff_transition_to_dev, which this now forwards to. Runs the dev handoff for a design artifact.

handoff_generate_design_image

Queue an AI design image generation (async). A durable background runner processes the job within ~1 min; poll handoff_get_design_job for the result. Requires server AI to be configured.

handoff_get_design_job

Poll a design image generation job (from handoff_generate_design_image). Read-only.

handoff_set_design_status

Set a design artifact's lifecycle status (draft → review → approved). Moving to review or approved kicks off server-side asset extraction + spec generation (when server AI is configured), so the artifact's spec/assets are ready for handoff_generate_component_from_design.

handoff_transition_to_dev

Transition a design artifact to developer-ready: extracts its assets (backgrounds, states, icons) and generates the full specification — props, behavior, accessibility, text inventory, design-token mapping against the registry's real tokens, and a brand-voice check of the copy. One operation; poll handoff_get_design_artifact and read `devHandoff` for stage-level progress (extracting_assets → generating_spec → ready). Read the result with handoff_get_component_spec.

Pages & Compositions

handoff_create_page

Compose a NEW playground page (landing page) from component blocks and save it (source: playground). Each block is {id (component id), preview? (existing preview key), args? (prop values)}. To compose blocks that render WELL (not just validly), call handoff_scaffold_args for each component first — it returns correctly-shaped `args` (seeded from a real preview) + per-field shapes; tweak and pass them here. Or reference an existing preview by key via `preview` and override only what changes in `args`. Every block is validated against its contract (unknown ids / out-of-contract args are rejected). Richtext fields are stored as Portable Text; HTML in and out by default, so pass the HTML you would write and read it back the same way. Any VISUAL slot you leave unset renders blank — the returned `report[].emptySlots` flags those. `editUrl` renders your exact args live now; `publishedUrl` (the standalone page) only reflects this composition after a rebuild.

handoff_delete_page

Archive a playground page. **This is not a hard delete** — the record and its history stay, the page is taken out of every listing, and any build briefs made from it (plus the pages built from those) are archived with it. There is no un-archive yet, so treat it as final from a caller's point of view. Added because a page composed by mistake previously had no way to be cleaned up at all.

handoff_get_page

Get one playground page (pattern): its ordered block composition ([{id, preview?, args}]) + metadata. Read this before editing/swapping blocks, then pass the modified blocks to handoff_update_page. Richtext fields are STORED as Portable Text but returned as HTML by default — HTML in and out, so blocks you read here can be edited and passed straight back. Ask for `richTextFormat: "portableText"` for the canonical stored shape, or "markdown" to read the copy without the markup.

handoff_list_pages

List playground pages — saved compositions of component blocks ("patterns"). Use to see or reuse existing landing pages before composing a new one. Optionally filter by group.

handoff_scaffold_args

Get a ready-to-fill `args` template for a component so you dispatch blocks/previews that render WELL instead of guessing prop shapes. Seeds `args` from a real preview (correctly-shaped slots, images, arrays) when one exists, and annotates every field with its editorType + expected shape (richtext = HTML string, image = { src, alt, … }, etc). Fill/tweak the returned `args`, then pass it to handoff_create_page (as a block's args) or handoff_create_preview. Call this BEFORE authoring to avoid empty slots / wrong-shaped values.

handoff_update_page

Update a playground page: metadata and/or its full block composition. To add/remove/swap/reorder blocks (e.g. swap in a new hero), read the page with handoff_get_page, modify the blocks array, and pass the FULL new array here. Blocks are validated against contracts before saving. Richtext fields take HTML (or the Portable Text a "portableText" read returned) and are stored as Portable Text.

Previews

handoff_create_preview

Author a NEW registry preview for a component — a named, semantic value-set (e.g. a "Primary CTA" button). Call handoff_scaffold_args first for correctly-shaped `values`. Values are validated against the component contract; invalid values are rejected, not saved. This is how Claude publishes a configured, meaningful example to the workbench. Richtext fields are stored as Portable Text; HTML in and out by default — pass the HTML you would write. Returns `verifyUrl` — the component page with `?preview=<key>`, which opens on this value-set. **It resolves the preview through a live API call, so on a statically exported registry it will not appear until `handoff-app build` runs.** Also returns a `report` (empty visual slots + each field's editorType) to self-check the values. Set `purpose` so the preview is grouped and picked correctly — an unpurposed preview lands in the component page's trailing "Other" group. Once a value-set is approved, mark it canonical with handoff_promote_preview.

handoff_preview_component

Render an INTERACTIVE, inline preview of a component (embedded app) — the real rendered component with responsive width controls. Pass a component id and optionally a preview key. Use when the user wants to SEE a component, not just read its data (handoff_get_component). With no key it picks by `purpose` — the component's `builder` seed, else its `example`.

handoff_promote_preview

Approve a registry preview: mark its value-set canonical (semantic="canonical") so it reads as the blessed, reference example for its component. Use after review to promote a value-set authored via handoff_create_preview / handoff_update_preview. Lifecycle only — it does not touch `purpose`, which says what the preview is FOR. Zero contract change — no rebuild, no migration.

handoff_update_preview

Update an existing registry preview (by its id). Provide any of title / values / semantic / purpose / rationale. Changed values are re-validated against the component contract; richtext fields are stored as Portable Text, and HTML is accepted (and returned) as it always was. `purpose` is authoring classification (what the value-set is FOR); to approve/canonicalize a value-set instead, use handoff_promote_preview, which sets `semantic` and leaves `purpose` alone.

Documentation

handoff_create_doc_page

Create a NEW markdown doc page. Fails if the slug already exists (use handoff_update_doc_page). The page appears in the sidebar nav automatically.

handoff_get_doc_page

Get one markdown doc page by slug — its frontmatter + markdown body.

handoff_list_doc_pages

List markdown documentation pages (slug, title, description). These are doc/content pages — distinct from playground pages (block compositions; use handoff_list_pages for those).

handoff_update_doc_page

Update an existing markdown doc page (by slug). Fails if it does not exist. Provide markdown and/or title/frontmatter; frontmatter is merged with the existing.

Change Inquiry

handoff_change_why

The reason a specific change was made: returns the human-authored push message if present, otherwise generates and caches a one-sentence AI summary from the diff. Pass the change type and id as returned by handoff_recent_changes / handoff_component_history.

handoff_component_history

Version history for one component (newest first): version number, when, who, the "why" when recorded, and the CATEGORIES that moved — contract | visual | content | asset | config. Contract versions also carry the property-level delta (added / removed / retyped / newly required), so this answers "can I still pass <prop>?" as well as "what changed in <component>" and "how has it evolved".

handoff_recent_changes

Recent changes across the design system, grouped by PUSH — one entry per push, newest first, not one per row. Each push gives who pushed it, when, the "why" (the push message, or a drafted summary), the commit, and the entities it touched with the categories that moved: contract (properties/slots), visual (artifacts/theme), content (previews/docs/metadata), asset (images), config (source/handoff config). Use to answer "what changed recently/lately/since <when>". Filter with contractOnly to answer "did anything break?". For the reason behind one specific row, follow up with handoff_change_why using its entity type + changeId.

Build & Sync

handoff_enqueue_build

DEPRECATED — server-side builds retired. Builds run locally via `handoff-app build`. Returns workspace-mode notice.

handoff_list_reference_materials

List reference material ids and sizes.

handoff_sync_pull

Fetch a bounded page of sync changes since cursor (JSON patches for local apply). Registry mode only. Results are paginated: if the response has `hasMore: true`, pull again with `since` set to `nextCursor` and repeat until `hasMore` is false to drain the full feed.

handoff_sync_push

Upload sync changes (requires sync:write). Registry mode only.

handoff_sync_status

Remote sync cursor and health. Returns workspace-mode notice if no registry is connected.

Other

handoff_component_contract_history

Contract history for one component: only the versions whose properties or slots changed, each with the property delta (added / removed / retyped / newly required) and whether it was breaking. Use before upgrading a consumer, or to answer "can I still pass <prop>?" / "when did <prop> become required?" / "has this component ever broken its API?". Ignores the visual, content, asset and config versions that handoff_component_history also lists.

handoff_delete_doc_page

Delete a markdown doc page by slug. Removes it from the sidebar nav and records the deletion in the changelog. Fails if the slug does not exist.

handoff_list_review_queue

List playground pages awaiting review — typically pages built by someone outside the team through a guest share link. Each entry carries who submitted it (a self-declared, UNVERIFIED name), the template it was built from, the share link that admitted them, and their note to the reviewer. Decide an entry with handoff_review_page.

handoff_move_doc_page

Move (rename) a markdown doc page from one slug to another, preserving its content. Fails if fromSlug does not exist or toSlug is already taken. Use this instead of delete+create so the page keeps its history and the nav tree updates atomically.

handoff_review_page

Approve a submitted playground page, or send it back to its author. "approve" marks it approved; "reject" returns it to draft, which also re-opens editing for the guest who built it, so a rejection with a message is how you ask for another pass. Visibility is never changed — promoting a page to a wider audience stays a separate, deliberate act. Maintainer only.