Particles UIDOCSDESIGN DECISION INFRASTRUCTUREStudioCLIMCP
Getting startedStudioTokensToken architectureThemes & modesChanges & governanceBranches & reviewsDesign documentationFigma pluginCLIConnect AI agentsMCP playbookWebhooks & CI/CDSecurityPrivacyTerms
Docs / Agents & MCP / MCP playbook

MCP playbook

Recipes for driving Particles with an AI agent over MCP. The /docs/mcp page covers connecting and lists every tool; this page is the manual — the flows to follow, the guardrails to respect, and copy-paste sequences for the things agents do most.

i

This page assumes you have already connected an agent and created an access token. If not, start at Connect AI agents. Everything below works from Claude Code, Codex, Claude Desktop, or any MCP client.

The govern-first loop#

Every write in Particles follows the same shape as the Studio editor: you browse read-only by default, and every edit happens inside a Change — a working branch you open, edit, and hand back for review. An agent never edits main directly and never merges; it proposes changes on a branch and a human reviews & merges in Studio. Keep this loop in mind and the rest of the playbook falls out of it.

terminal
discover → read → open a Change → edit on the branch → hand off for review

1. list_projects            no input needed — enumerates every accessible org's projects;
                            match the project the user named (name + kind), never ask for ids
2. list_branches            is a Change already open, or start from main?
3. get_token / find_tokens  read the current state before touching anything
4. create_branch            open a Change (a working branch) to edit on
5. create_tokens / …        make the edits on that branch
   → a human reviews and merges the Change in Studio

There is no merge tool. Merging a Change into main is a deliberate human step in Studio — agents propose, people ship. Editing a protected main directly is refused with MAIN_PROTECTED; open a Change instead.

Finding your way around#

Before acting, resolve what the user named to concrete ids. Discovery tools are reads — a read-only token is enough.

To find…CallNotes
A project by namelist_projects {}No input needed — enumerates every organization the credential can access and returns all their projects (id, name, kind, token mode, description, organizationId). Pass organizationId only to narrow.
The organizations themselveslist_organizations {}First hop of id resolution — id, name, slug for every org the credential can access. Resolve org ids here, never by asking the user.
The branches / open Changeslist_branches { projectId }Shows main plus any working branches. Discover branchId values here.
A tokenget_token / find_tokensget_token is exact-name; find_tokens is natural-language ("a calm card background").
Token types / groupslist_token_types / list_token_groupsThe structure a project organizes tokens into.
Platformslist_platformsWeb/iOS/… targets, on multi-level projects.
Themeslist_themes / get_themeThe same themes the Studio switcher shows (branch-scoped, default main). get_theme returns a theme’s full override set, resolved to token names.

When a user says “update the button colour in Astryx Foundation”, call list_projects first: the row’s name and kind let you pick the right projectId even when several projects share a similar name.

Editing tokens#

Open a Change, make the edits on its branch, then let a reviewer merge. Writing needs a read-write access token (a read-only one is refused with a clear message).

terminal
# "Darken the brand ramp one step"

create_branch {
  projectId, name: "darken-brand-ramp",
  description: "brand.600 fails on marketing surfaces; darkening one step"
}
→ { id: branchId, name: "darken-brand-ramp" }

update_token { projectId, tokenId, value: "#1d4ed8" }   # from get_token
# …repeat, or use a batch call (below)
→ a human reviews & merges "darken-brand-ramp" in Studio
i

Prefer create_branch before writing. If you write without a branchId you target main, which protectMain will usually reject. Write-time policy (naming rules, required descriptions, semantic-must-alias) is enforced on every create/update — an invalid token returns a structured 422 you can read and correct.

Bulk edits — one call, all-or-nothing

Pushing a palette or moving a selection? Use the batch tools rather than a loop of single calls — one request, atomic, and it won’t trip the rate limit. If any entry fails (policy, a dependency, a wrong id) nothing is written.

Instead of…UseBehaviour
N × create_tokencreate_tokens { tokens: [...] }Up to 200 tokens in one call. Every entry passes policy + tier ownership or none are created.
N × delete_tokendelete_tokens { tokenIds: [...] }Up to 200. Dependents inside the batch don’t block it; a token referenced from outside the batch fails the whole call (409).
terminal
# "Create a blue palette" (11 shades) — one request, not eleven

create_tokens {
  projectId, branchId,
  tokens: [
    { name: "color/blue/50",  type: "color", tier: "primitive", value: "#eff6ff", groupPath: "color/blue" },
    { name: "color/blue/100", type: "color", tier: "primitive", value: "#dbeafe", groupPath: "color/blue" },
    … 9 more …
  ]
}
→ { created: 11, tokens: [ … ] }

Managing themes#

A theme is an overlay, not a change/branch. One base value lives on the token; a theme swaps in a different value for the tokens it overrides. Themes live on a branch — created on main (the default), a theme is exactly what the Studio theme switcher shows and what products inherit. These are the same themes the token editor, Figma plugin, and export all use.

Don’t model themes as separate change branches. Seven branches each setting the same token to a different value would collide at merge (one token holds one value; last-merge-wins flattens the rest). The override overlay exists precisely to avoid that.

terminal
# "Add a dark theme where the background is near-black"

create_theme { projectId, name: "dark" }   # defaults to main; pass branchId to target another
→ { id: themeId }

set_theme_overrides {
  projectId, themeId,
  overrides: [
    { tokenName: "color/background", value: "#0b0b0f" },
    { tokenName: "color/text",       value: "#f5f5f7" }
  ]
  # mode defaults to "merge" — updates only these tokens, keeps the theme's others.
  # mode: "replace" makes the listed set the theme's ENTIRE overlay.
}
→ { themeId, overrideCount }

Overrides are given by token name (resolved to ids for you), and the whole overlay is written in a single call — applying a themed set is one request, not one per token. Use get_theme to inspect what a theme changes before editing it, and delete_theme to remove an overlay (base values are untouched).

Managing design-system structure#

The same surfaces Studio exposes for shaping a design system are available as tools — project-scoped, gated by tokens:write / tokens:delete.

SurfaceToolsWhat it is
Token typeslist / create / update / delete_token_typeBuilt-in and custom token types, each scoped to a tier (primitive/semantic/…).
Token groupslist / create / delete_token_groupNamed sub-namespaces within a type (e.g. a "brand" group under color).
Platformslist / create / update / delete_platformWeb/iOS/… targets semantic tokens vary across on a multi-level project. May need the Business plan.
Contrast pairslist / create / delete_contrast_pairForeground/background token pairs the a11y gate checks — created by token name.

Understand before you change#

Reads that make an agent’s edits safer. Reach for these before a risky change and to answer “is this a good idea?” without writing anything.

QuestionTool
What breaks if I change this token?get_impact — affected tokens, the components that bind it, and a11y risk.
Is this colour pair readable?check_contrast — WCAG ratio + AA/AA-large/AAA between two named tokens.
How healthy is the token system?get_score (scalability) · get_coverage (bound/unbound, orphans).
What’s the governance state?get_governance_status — lead time, review coverage, gate blocks, stale changes.
How does a token resolve in a theme?resolve_theme — the value a token takes inside a named theme.

Permissions & plans#

An access token can never exceed the permissions of the person who created it, and its scope is enforced on every call — exactly like Studio. Two things decide whether a call succeeds:

GateWhat it means for an agent
Read vs read-write tokenEvery read tool works with a read token. The write tools (create/update/delete of tokens, branches, themes, types, groups, platforms, contrast pairs) need a read-write token — a read-only one returns 403 "This access token is read-only."
Project allowlistA token scoped to specific projects returns PROJECT_NOT_IN_SCOPE for any other project.
PlanMCP access needs the Team plan or above. Some features (knowledge-graph, platforms/multi-level) need Business — those return a clear "upgrade required" (FEATURE_GATE).
protectMainWriting to a protected main is refused (MAIN_PROTECTED). Open a Change and write there.
org-level actionsOrganisation management (e.g. linking foundation/brand modules) is never available to an access token — those stay in Studio with an interactive session.

Guardrails & good patterns#

DoWhy
Resolve the project by name + kind firstlist_projects returns kind/description so you pick the right project even when names are similar.
Open a Change before writingKeeps edits off main, gives reviewers a titled diff, and avoids MAIN_PROTECTED.
Batch when you cancreate_tokens / delete_tokens are one atomic request — faster, and they won’t exhaust the rate limit like a loop of single calls.
Work in names, not idsTheme overrides and contrast pairs take token names and resolve them for you; get ids from get_token/find_tokens when a tool needs one.
Read impact before a big changeget_impact / check_contrast tell you what a change affects before you make it.
Surface the server’s error verbatimA 422 policy violation or 403 lists exactly what to fix — pass it on rather than guessing.

Reading errors#

Tool errors are actionable — the message says what to do. The common ones:

ErrorWhat to do
This access token is read-onlyThe token lacks write permission. Create a read-write access token in Studio (Settings → Access Tokens) and reconnect.
MAIN_PROTECTEDYou tried to write to a protected main. Call create_branch and write on that branch.
POLICY_VIOLATION (422)A token breaks the project’s write-time policy (naming, required description, semantic-must-alias). The response lists each rule — fix and retry.
PROJECT_NOT_IN_SCOPEThe token isn’t scoped to this project. Use a token that covers it, or pick a project it does.
FEATURE_GATE / plan limitThe feature needs a higher plan. Nothing to retry until the org upgrades.
HAS_DEPENDENTS (409)A delete is blocked because other tokens alias it or a component binds it. Remove those references first (or include them in a batch delete).

For connection-level problems (401, tools not appearing, connector won’t connect) see the troubleshooting section on the Connect AI agents page.

← PREVIOUS
Connect AI agents
NEXT →
Webhooks & CI/CD