Skip to content
Brand Stack
Esc
↑↓navigate↵open⌘Jpreview
Sign up
On this page

Tools reference

All 24 MCP tools the Brand Stack connector exposes, with inputs, outputs, and example agent prompts.

The Brand Stack MCP server exposes 24 tools: 14 read tools, 3 image intake tools, 3 generation tools, 2 repo tools (adoption and update proposals), 1 asset-role tool, and 1 distribution tool (the install command). Tools are filtered by your token’s scopes, so read-only tokens see only the read tools.

The definitions come from the same tool registry (@brandstack/tools-engine) that powers the workspace CLI commands, so npx @brandstack/cli list-brands and the MCP list_brands tool are the same server code with the same inputs, rules, and error messages. Only the transport differs. Authenticate the CLI with an API key; MCP connectors use OAuth. Both hit POST /api/mcp, where scopes, credits, and rate limits are enforced once, server-side, for every caller.

Read tools (mcp:read)

list_brands

List the workspace’s brands, newest first — both kinds: brand stacks (kind: "brand_stack" — created by adopt_repo or the app’s stack builder, each carrying a live status) and brand profiles (kind: "brand_profile" — the older scraped-site records). Either kind’s id resolves through get_brand.

Inputs: search (case-insensitive name filter) and limit (default 50, max 200). Returns { brands, total, note? } — the note appears when rows were cut, so an agent knows to narrow with search rather than concluding an entry does not exist.

“Show me all my brands.”

get_brand

Fetch a single brand by id — either kind:

  • A brand profile id (from list_brands) returns the full record; format controls the output.
  • A brand stack id or slug (from an adopt_repo response, a list_brands entry of kind brand_stack, or a product’s brandStackId) returns the stack’s live state: status (queued | generating | ready | failed | needs_input), per-section progress, stackUrl, and — once the pipeline has created them — productId and personas, the forward references for list_personas_for_product and the generation tools.

This is the poll after adopt_repo: call it with the returned brandStackId every 15–20 seconds until status is ready (typically 60–90 seconds).

Profile format options:

Format What it returns
json (default) Structured fields: colors, typography, voice, messaging, visual direction.
markdown A printable style-guide doc.
css CSS custom properties (--brand-primary, --brand-text, and so on).
tailwind A Tailwind config snippet that extends your theme.colors.
context A prompt-ready summary you can paste into a system prompt.

Inputs: brand_id (profile UUID, or stack UUID or slug; required), format (optional; profiles only — a stack answers with structured json and points at get_install_command for exports).

“Get my Acme brand as a Tailwind config.”

list_products

List the workspace’s products, newest first, with name, industry, target audience, and lifecycle stage. Each entry also carries brandStackId when the product belongs to a brand stack — the id create_mockup and create_scene accept as brand for explicit attribution.

Inputs: search (case-insensitive name filter) and limit (default 50, max 200). Returns { products, total, note? }. In a workspace full of demo brands, pass search with the product or repo name instead of paging the whole list.

get_product

Fetch a single product. Inputs: product_id (required).

list_personas_for_product

List every persona linked to a product. Returns compact summaries; use get_persona for the full record. Inputs: product_id (required).

“Who are the personas for my Operator product?”

get_persona

Fetch a single persona: demographics, goals, pain points, the generated long-form profile as Markdown (profileMarkdown), absolute image URLs (profileImageUrl, environmentImageUrl, safe to fetch or embed directly), and the id of the first linked product. Inputs: persona_id (required).

list_projects

List every project (a collection of related documents), with id, name, emoji, and timestamps. No inputs.

list_documents

List documents, paginated. Inputs:

  • limit (1 to 100, default 50)
  • offset (default 0)

Returns { documents, total, limit, offset }.

get_document

Fetch a single document. The body comes back as Markdown (contentMarkdown); documents authored before the editor moved to Markdown are converted on read. Inputs: document_id (required).

“Read me the latest Q4 strategy doc.”

list_assets

Search the workspace’s image library with optional filters:

Input What it does
asset_type image, logo, or avatar
source_type mockup_generated, scene_generated, persona_profile, persona_environment, brand_logo_generated, brand_logo_external, attachment, upload
product_name Filter by product (exact match)
search Substring search across source_name and filename
cursor Pass the previous page’s last createdAt for pagination
limit 1 to 100, default 40

Returns { assets, nextCursor }. Use nextCursor as the next call’s cursor to paginate. Screenshots that arrive through capture_screenshot, the CLI upload, or an upload link live in their own timeline — see list_screenshots.

“Find all the mockup-generated images for the Acme product.”

list_screenshots

Browse the workspace’s Screens timeline (the Screens page in the workspace sidebar) — where every screenshot arriving through capture_screenshot, npx @brandstack/cli upload, or an upload link lands, newest first. Each entry carries the hosted url (pass it to create_mockup as screenshot_url), title, brandName / brandStackId, productName, deviceCategory, sourceUrl (the captured page), captureSource, dimensions, and createdAt.

Input What it does
brand_stack_id Filter by attributed brand stack (UUID), or "none" for unattributed
device_category mobile, laptop, or desktop
capture_source capture, upload, upload_link, or manual
since Only screenshots created at or after this ISO timestamp
search Substring search across title, filename, and source URL
cursor Pass the previous page’s last createdAt for pagination
limit 1 to 100, default 40

Returns { screenshots, nextCursor }.

“Show me the mobile screenshots we captured this week.”

list_templates

List the workspace’s saved setups: reusable compositions (device, camera, atmosphere, aspect ratio) captured from a previous mockup. Completed setups only, newest first. Each entry carries the id you pass to create_mockup as template_id, plus title, deviceType, cameraPosition, cameraLens, atmosphere, aspectRatio, outputUrl, and tags.

Ids are UUIDs on rows you saved, so this is the only way to discover one. title is nullable; describe an untitled setup by its device and lighting.

Inputs: limit (default 50, max 100), search (matches the title).

“What saved mockup setups do I have?”

get_credits

Return the workspace’s remaining credits, split between subscription plan and one-time packs, plus mockupCosts (the live per-tier prices: what a 1K, 2K, or 4K image costs in credits) and manageCreditsUrl (the workspace’s subscription page, where credits are bought). No inputs.

Agents are instructed to call this before a session’s first generation and to quote the chosen tier’s cost, so credits are never spent silently. Purchases can’t happen through the connection itself; when the balance runs low, the agent shares manageCreditsUrl and the user upgrades or buys a pack in the browser.

This is also where a newly connected workspace’s welcome lands: the first call from a workspace that has never used the connector grants credits sized to 10 free mockups, and the response carries a welcome note saying so.

get_brand_asset

Look up the asset filling a brand stack role — “the hero image”, “the logo”, “the OG card” — and get a URL back. Built-in roles (logo, favicon, og) resolve from what the pipeline maintains; named roles (hero, banner, social-card, icon, illustration, background, pattern, photo, screenshot, product-shot, email-header) resolve from assets promoted with set_brand_asset_role. An unfilled role answers with which roles are filled. Inputs: role (required), brand (optional — defaults to the workspace’s default stack).

“Use our hero image on this landing page.”

Image intake (mcp:write, no credits)

The generation tools take reference images as public https URLs the server fetches. These three tools, plus the CLI upload, are how an image gets one. None of them cost credits.

capture_screenshot

Capture a screenshot of a public web page on Brand Stack’s own servers and store it in the workspace library. This is the no-shell path: paste a URL in Claude’s chat or Cowork and the agent has a hosted screenshot in one call.

Inputs:

  • url (required): public http(s) address. A local dev server (localhost, private networks) is not reachable from Brand Stack’s servers; capture those with Playwright, then upload the file through create_upload_link (or the CLI, if a key is configured).
  • viewport (optional): desktop (1440×900, for MacBook and Studio Display mockups, the default) or mobile (390×844 at 2x, for iPhone mockups).
  • full_page (optional, default false): capture the whole scrollable page. Keep it false for device mockups; a device screen shows one viewport.

Returns { url, width, height, assetId, deviceHint }. Pass url to create_mockup as screenshot_url. Takes 5 to 15 seconds.

“Capture mysite.com at a mobile viewport and make it an iPhone mockup.”

Mint a 30-minute upload channel into the workspace, no login and no API key on either of its two routes:

  • uploadUrl: a browser page where a person drops an image. The pasted-image path for clients with no shell: the user pasted a screenshot into the chat, the agent cannot move the bytes itself, so it sends the user this link and picks the upload back up from list_screenshots (newest first).

  • uploadEndpoint: accepts the raw file bytes by POST, for agents that do have a shell but no CLI key:

    curl -X POST -H "content-type: image/png" -H "x-filename: shot.png" \
      --data-binary @shot.png "$UPLOAD_ENDPOINT"

    The response carries the hosted url (pass it as screenshot_url) plus width and height, which is what device inference runs on. No user step at all.

No inputs. Returns { uploadUrl, uploadEndpoint, validForMinutes, expiresAt }.

If the POST to uploadEndpoint fails with a 403 or policy error from a proxy, your agent is running in a sandbox whose network allowlist blocks brandstack.dev while MCP calls go through their own channel. Fall back to upload_screenshot below, or add brandstack.dev to the allowlist.

upload_screenshot

Upload a screenshot by passing its bytes base64-encoded inside the tool call. This is the fallback for sandboxed agent runtimes (Claude Code on the web, restricted CI) where general HTTP egress runs through an allowlist: the POST to create_upload_link’s uploadEndpoint dies with a 403 from the proxy, but MCP tool calls ride a separate channel that works. This tool moves the bytes over that channel.

Prefer the POST route whenever it works: base64 inside a tool argument passes through the model’s context window, costing roughly 35K tokens per 100KB of image. Before falling back, make the file small (downscale, or re-encode as JPEG/WebP around quality 80; a UI screenshot rarely needs more than ~200KB). The decoded limit is 3MB; the POST route accepts 5MB.

Inputs:

  • data_base64 (required): the image file’s bytes, base64-encoded (base64 -w0 shot.png). A data: URI prefix and base64url both work; the type is detected from the bytes (PNG, JPEG, WebP, GIF).
  • filename (optional): the original filename, used for the stored name and the timeline title.
  • brand (optional): brand stack UUID, or none.
  • device (optional): mobile, laptop, or desktop; inferred from the image’s dimensions when omitted.
  • source_url (optional): the page the screenshot shows (the localhost or preview URL it was captured from).

Returns the same shape as the upload endpoint: { url, width, height, screenshotId, deviceCategory, brandName, filename }. Pass url to create_mockup as screenshot_url. The screenshot lands in the Screens timeline like every other intake route.

“The upload POST got blocked by the sandbox proxy — compress the screenshot and send it through upload_screenshot instead.”

Uploading from a shell with the CLI

With an API key configured (npx @brandstack/cli login once, or BRANDSTACK_API_KEY), the CLI does the shell route in one command:

npx @brandstack/cli upload ./shot.png

prints the hosted URL plus the image’s width×height. Every --*-url flag on the CLI’s create-mockup also accepts a local path directly and uploads it first. Optional: an agent without a key uses create_upload_link and loses nothing but the shortcut. See Screenshots → mockups for the full flow.

Generation tools (mcp:write, consume credits)

All three tools consume credits from the connected workspace (a new workspace’s first 10 mockups are free). Generation typically takes 20 to 60 seconds and the call returns synchronously with the final image URL.

All three tools accept an idempotency_key (8 to 128 characters): agents pass a fresh unique value per intended image and reuse the same value when retrying after a timeout or dropped connection. If the earlier attempt completed, its result comes back marked replayed: true and no credits are spent again.

create_mockup

Generate a product mockup: a device, photographed in a real environment, with your screenshot on its screen. At least one of persona_id, template_id, device_type, screenshot_url, atmosphere, camera_position, or custom_instructions must be provided.

The tool’s description teaches the agent to infer before asking. The screenshot’s own dimensions answer the device question (portrait means iPhone with no question; landscape earns exactly one, MacBook Pro or Apple Studio Display), the coding session answers the persona question (the agent matches the product it is working on against list_products), and everything else has a sensible default. You get at most one short question, and none if you say “just make it”.

Most-used inputs:

  • screenshot_url: the image shown on the device screen. Without it the screen content is invented.
  • persona_id: pulls the persona’s demographics and reference imagery automatically.
  • template_id: a saved setup’s UUID from list_templates. Applies that setup’s composition and uses its rendered image as the reference, the same as picking it in the studio.
  • device_type / device_label: for example macbook_pro, iphone, studio_display.
  • camera_position / camera_lens: for example Over the shoulder plus 35mm Wide.
  • atmosphere: Natural Light, Studio Lighting, Golden Hour, Moody / Dark, Bright & Minimal, Neon / Vibrant, Outdoor Daylight. Free-form values are accepted.
  • custom_instructions: free-form prompt. Takes precedence over the single-device default, so ask here for extra monitors or devices in shot.
  • style_reference_url: the “make it look like this” image. Its colors, lighting, and mood shape the whole shot; it does not appear on the device screen. When a user pastes two images, the agent routes the UI capture to screenshot_url and the photographic one here.
  • character_reference_url, previous_output_url: further reference images (a person’s likeness; a previous generation to vary).
  • aspect_ratio: 16:9 (default), 3:2, 4:3, 1:1, 3:4, 2:3, 9:16.
  • image_size: 0.5K, 1K (default), 2K, 4K. Higher tiers cost more credits.
  • brand: brand attribution. Usually omitted — the workspace default applies automatically (the persona’s brand stack when a persona is set, otherwise the most recently used stack, falling back to the most recently created). Pass a brand stack id (from list_products’ brandStackId) to attribute explicitly, or "none" for an image unrelated to any workspace brand, such as a screenshot of a third-party website.

Returns { mockupId, outputUrl, promptText, viewUrl, creditsRemaining }. viewUrl opens the mockup in the workspace’s studio, so the image is findable later without digging through chat history; creditsRemaining is the balance after the generation, which the agent surfaces when it runs low.

The workspace’s first mockup is guided: when no mockup has ever been generated, the agent offers choices in one message (camera angle, aspect ratio, and image size with each tier’s real cost) so the user learns what is configurable. From the second mockup on it infers instead.

“Turn that screenshot into a MacBook Pro mockup with Natural Light.”

create_scene

Generate a lifestyle scene featuring a persona. persona_id is required. Either pass an environment_type preset or a free-form environment_prompt.

Inputs:

  • persona_id (required): the subject of the scene.
  • environment_type / environment_label: preset slug plus label.
  • environment_prompt: free-form description; overrides the preset.
  • camera_position / camera_lens, atmosphere, custom_instructions: same as mockup.
  • character_reference_url, style_reference_url, previous_output_url.
  • aspect_ratio, image_size, brand: same as mockup.

Returns { sceneId, outputUrl, promptText, viewUrl, creditsRemaining }. viewUrl links to the workspace’s asset library, where the scene is saved.

“Create a scene of persona <id> in a coffee shop, golden hour lighting, 9 aspect.”

create_template

Generate a reusable mockup template: a screenshot-free device composition (device, camera angle, lighting, and an optional style reference) meant to be saved once and reused. The resulting template’s id (returned here, or from list_templates) becomes create_mockup’s template_id, which applies the same composition — and its rendered look — to future mockups. There is no persona and no screenshot; at least one of device_type, camera_position, atmosphere, style_reference_url, or custom_instructions must be provided.

Inputs:

  • style_reference_url: a photo or moodboard whose color palette, lighting, and composition the template adopts. When set, an explicit camera_position or atmosphere you also pass is applied as an edit to the reference — e.g. camera_position: "Bird's eye view" changes the reference’s angle while everything else about its framing and mood carries over. Leave both unset to keep the reference’s own angle and lighting untouched.
  • device_type / device_label, camera_position / camera_lens, atmosphere, custom_instructions: same vocabulary as create_mockup.
  • previous_output_url: a prior template generation to use as a variation/regeneration starting point.
  • aspect_ratio, image_size, brand: same as create_mockup.
  • title: display name for the template. Optional — when omitted, one is derived from the device, camera angle, and lighting, so the row never sits unnamed in list_templates or the Template Studio gallery.

Returns { templateId, title, outputUrl, promptText, viewUrl, creditsRemaining }. viewUrl opens the template in the workspace’s Template Studio; the saved row then shows up in list_templates for reuse.

“Save a template for a MacBook Pro shot from a bird’s-eye angle, styled after this moodboard image.”

Repo adoption (mcp:write)

adopt_repo

Adopt the repo an agent is working in as a Brand Stack. The agent analyzes the codebase first — global styles and design tokens for colors, font config for typography, landing components and the README for copy, package.json for the stack — and submits what it observed as the analysis JSON (the tool description carries the exact shape; only repo.name is required). Brand Stack detects the repo’s target profile (framework + styling system) along the way and registers the repo as a connection on the stack in both modes.

Inputs:

  • analysis (required): JSON string of repo observations — repo identity, observed colors with their sources, font families, real UI copy, taglines, README excerpt, and raw stack signals.
  • brand: an existing stack’s id or slug. Omit to create a new stack.
  • proposal_title: title for the change proposal (existing-stack mode).

Two modes:

  • Without brand — creates a new brand stack from the analysis. Generation runs in the background (60–90s) and consumes credits like creating a stack in the app. Observed colors, typography, and copy are applied verbatim with repo-observed provenance; the model fills the unobserved fields from the repo’s own copy. Returns { brandStackId, slug, stackUrl, status, next, targetProfile }. Then poll get_brand with the returned brandStackId every 15–20 seconds: it reports status (queued | generating | ready | failed) with per-section progress, and once ready it carries the stack’s productId and personas — the direct route to list_personas_for_product, no workspace-wide listing needed.
  • With brand — files a free change proposal instead: nothing is applied until a workspace member with publish permission reviews it in the app. Returns { proposalId, reviewUrl, proposedPaths, status, targetProfile }.

“Adopt this repo into Brand Stack — analyze the styles and copy first.”

propose_update

The precise counterpart to adopt_repo for an existing stack: instead of raw observations, the agent passes changes already in canonical model terms — it diffed the repo against the pinned brand version and knows exactly which fields moved.

Inputs:

  • brand (required): the stack’s id or slug.
  • changes (required): JSON string — an array of { path, after, before? } canonical model changes (paths root at strategy, voice, visual_identity, or assets_manifest).
  • repo (required): the proposing repo as owner/name.
  • base_version, title: optional.

Files a free open change proposal and returns { proposalId, reviewUrl, proposedPaths }. Nothing is applied until a workspace member reviews the field-level diff at reviewUrl and approves — approval applies under provenance precedence and cuts a new brand version. A new proposal from the same repo supersedes that repo’s older open proposals.

“The design team retuned our primary color in globals.css — propose that update to the brand stack.”

set_brand_asset_role

Assign a workspace asset a brand role — “make this mockup the hero image” is one call. Inputs: brand (id or slug), role (a named role), asset_id (from list_assets / list_screenshots / a generation result), optional name and use; remove: true demotes. Single-slot roles replace their holder; collection roles (photo, illustration, icon, screenshot) append.

Role assignments are model state: a promotion stamps human-edited provenance and cuts a new brand version, shows in the changelog under Assets, and ships in every bundle under assets/library/. Free.

“This is our official product shot now — promote it.”

get_install_command

The distribution verb: returns the exact commands to pull a brand stack into the repo an agent is working in. Inputs (all optional): brand (id or slug; defaults to the workspace’s stack), profile (a target profile id — nextjs-tailwind-v4, nextjs-tailwind-v3, tailwind-v4, tailwind-v3, or css-variables — to compile the bundle for), pin (a brand version like 1.2.0 for reproducible installs).

Returns downloadUrl, a ready-to-run installCommand (curl + unzip — authorized by the stack’s share link, so it works in a fresh repo with no API key), the equivalent npx @brandstack/cli pull command for keyed/CI use, and the full install prompt the app’s Build panel shows. Mints the stack’s share link on first use (why it needs mcp:write); an existing link is reused. Free.

“Install our brand into this repo, compiled for Tailwind v4.”

A typical agent loop

1. capture_screenshot url="https://mysite.com" viewport="desktop"
   → { url, width: 1440, height: 900, deviceHint: "landscape ..." }
2. create_mockup screenshot_url="..." device_type="macbook_pro"
   → { mockupId, outputUrl, promptText }
3. list_assets source_type="mockup_generated" limit=5
   → confirms the new shot appears in the library

Was this page helpful?