MCP ServerTool Reference

Classes

Generated MCP reference for classes.

This page is generated from mcp-catalog.json. Do not edit it by hand.

Source: paper3 local extraction on 2026-05-29. Generated: 2026-05-29T11:34:45.044Z.

delete_class

Delete a site class

Remove a site-level class from the design system AND strip every occurrence of its name from every node's classNames array — pages + components, both. Refuses without force: true when the class is currently applied somewhere (the result includes the usageCount so you know what you'd be unwiring). When force is true, the strip runs and unwires N references in one atomic mutation. To rename a class instead of deleting + recreating, call set_class(\{ previousName, name, … \}) — that preserves every reference.

Parameters

ParameterTypeRequiredDescription
namestringYes
forcebooleanNo
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "force": {
      "type": "boolean"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false
}

list_classes

List site classes

Returns every site-level semantic class catalogued in the design system. For each: name (kebab-case identifier), usageCount (how many nodes across every page + component reference it), properties (sorted list of CSS keys defined on the class, including responsive overrides). Call this BEFORE inventing a new class with set_class — reuse beats proliferation. The shared classes are what make the site visually coherent across pages AND keep read output small (a node using card-soft doesn't repeat the 15 inlined properties — they live in the class definition). Returns [] when the site has no classes yet (the common case on a fresh site — bootstrap with a small kit via set_class).

Parameters

ParameterTypeRequiredDescription
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "additionalProperties": false
}

merge_classes

Merge site classes

Fold one or more source classes into a single target. The source classes are removed AND every referencing node's classNames is rewritten to point at the target instead — dedup is automatic. When the target doesn't already exist, it's auto-created with the first source's style bag (subsequent sources do NOT auto-merge their style bags — that's intentional; merge styles by editing the target with set_class BEFORE calling this if needed). Use this to consolidate accidentally-divergent siblings (card, card-2, card-finalcard) without unwiring any node.

Parameters

ParameterTypeRequiredDescription
fromarrayYes
intostringYes
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "from": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "into": {
      "type": "string"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "required": [
    "from",
    "into"
  ],
  "additionalProperties": false
}

remove_class_styles

Remove a class-state bag (one or many)

Drops the entire style bag for a class on a node. Use this to clean up an authored class state (e.g. removing is-open if you change interaction approach).

INPUT SHAPES (pick whichever fits — the model-side framing overhead drops linearly with the number of tool calls): • \{ nodeId, ...patch \} — one node, one patch. • \{ nodeIds: [id1, id2, …], ...patch \} — same patch fanned out to many nodes (the 'multi-select' shape — use whenever 3+ nodes get the same change). • \{ updates: [\{ nodeId, ...patch \}, …] \} — different patches per node, batched in one call (use whenever 3+ nodes get different changes; far cheaper than N separate calls). Missing nodes are skipped silently. The result is \{ ok: true, applied, skipped \}.

Parameters

ParameterTypeRequiredDescription
nodeIdstringNo
nodeIdsarrayNo
updatesarrayNo
classNamestringNo
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "nodeId": {
      "type": "string"
    },
    "nodeIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "updates": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "nodeId": {
            "type": "string"
          },
          "className": {
            "type": "string"
          }
        },
        "required": [
          "nodeId",
          "className"
        ],
        "additionalProperties": false
      }
    },
    "className": {
      "type": "string"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "additionalProperties": false
}

rename_class

Rename a site class

Atomic rename: the class entry moves to the new name AND every node's classNames array referencing the old name is rewritten. Safer than delete_class + set_class because no node ever sees a missing reference between the two calls. Equivalent to calling set_class(\{ previousName, name, styles: existing.styles, … \}) but doesn't require re-passing the styles bag.

Parameters

ParameterTypeRequiredDescription
fromstringYes
tostringYes
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "from": {
      "type": "string"
    },
    "to": {
      "type": "string"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "required": [
    "from",
    "to"
  ],
  "additionalProperties": false
}

set_class

Create or update a site class

Create or update one site-level semantic class. name is kebab-case (card-soft, btn-primary, hide-mobile). styles is the base / desktop bag (camelCase keys, CSS values — tokens via var(--color-primary) are encouraged). responsive carries optional tablet and mobile overrides — emit ONLY the properties that diverge from base; everything else cascades naturally.

By default the update MERGES with the existing class (preserving keys you didn't mention). Pass replace: true to overwrite the entire entry (drops unmentioned keys). Use previousName to rename atomically: the old entry is removed AND every node's classNames array referencing the old name is rewritten to the new — no orphan references.

Pattern: bootstrap a typical site with a small kit of utilities FIRST: hide-mobile ({ mobile: { display: 'none' }}), stack-mobile ({ mobile: { gridTemplateColumns: '1fr', flexDirection: 'column' }}), text-center-mobile, …. Then build named component classes (card-soft, hero-stack, cta-button) as the design crystallises. Always list_classes first to avoid recreating what's already there.

Parameters

ParameterTypeRequiredDescription
namestringYes
stylesobjectYes
responsiveobjectNo
descriptionstringNo
previousNamestringNo
replacebooleanNo
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "styles": {
      "type": "object",
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          }
        ]
      }
    },
    "responsive": {
      "type": "object",
      "properties": {
        "tablet": {
          "type": "object",
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          }
        },
        "mobile": {
          "type": "object",
          "additionalProperties": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              }
            ]
          }
        }
      },
      "additionalProperties": false
    },
    "description": {
      "type": "string"
    },
    "previousName": {
      "type": "string"
    },
    "replace": {
      "type": "boolean"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "required": [
    "name",
    "styles"
  ],
  "additionalProperties": false
}

suggest_classes

Suggest classes to extract

Scan the doc for groups of same-type nodes whose inline style bags overlap enough to be worth folding into a shared site class. Returns [\{ suggestedName, nodeType, properties, nodeIds, impact \}] ranked by impact (nodes × shared properties). Use this to discover the natural design-system seams on a fresh / messy site without reading every artboard. Materialise a suggestion with set_class(\{ name: suggestedName, styles: &lt;values from the shared props on the first nodeId> \}) then set_node_field(\{nodeIds, field: 'classNames', value: [suggestedName]\}). Re-run after extracting to find the next pattern.

Parameters

ParameterTypeRequiredDescription
minNodesnumberNo
minPropertiesnumberNo
limitnumberNo
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "minNodes": {
      "type": "number"
    },
    "minProperties": {
      "type": "number"
    },
    "limit": {
      "type": "number"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "additionalProperties": false
}

update_class_styles

Update class-state styles (one or many)

Patches the styles applied when a specific CSS class is on the node — emitted as a scoped [data-pid="..."].&lt;class> \{ ... \} rule. Pairs with set_node_behaviors: a toggleClass / openMenu / scrollReveal adds the class at runtime, and this tool defines what it looks like. Class name should be kebab-case (e.g. "is-open", "is-revealed", "is-active"). Empty value clears a property; pass replace: true to clear unspecified keys. Canonical mobile-drawer recipe: resting transform: translateX(100%), then update_class_styles(\{ className: 'is-open', styles: \{ transform: 'translateX(0)' \} \}) and a transition: transform 280ms ... on the resting state. To DROP a class entirely, use remove_class_styles — calling this with empty styles + replace=true is rejected because it's almost always a model-loop symptom.

INPUT SHAPES (pick whichever fits — the model-side framing overhead drops linearly with the number of tool calls): • \{ nodeId, ...patch \} — one node, one patch. • \{ nodeIds: [id1, id2, …], ...patch \} — same patch fanned out to many nodes (the 'multi-select' shape — use whenever 3+ nodes get the same change). • \{ updates: [\{ nodeId, ...patch \}, …] \} — different patches per node, batched in one call (use whenever 3+ nodes get different changes; far cheaper than N separate calls). Missing nodes are skipped silently. The result is \{ ok: true, applied, skipped \}.

Parameters

ParameterTypeRequiredDescription
nodeIdstringNo
nodeIdsarrayNo
updatesarrayNo
classNamestringNo
stylesobjectNo
replacebooleanNo
_sitestringNoOptional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.

Input schema

{
  "type": "object",
  "properties": {
    "nodeId": {
      "type": "string"
    },
    "nodeIds": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "updates": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "nodeId": {
            "type": "string"
          },
          "className": {
            "type": "string"
          },
          "styles": {
            "type": "object",
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                }
              ]
            }
          },
          "replace": {
            "type": "boolean"
          }
        },
        "required": [
          "nodeId",
          "className",
          "styles"
        ],
        "additionalProperties": false
      }
    },
    "className": {
      "type": "string"
    },
    "styles": {
      "type": "object",
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string"
          },
          {
            "type": "number"
          }
        ]
      }
    },
    "replace": {
      "type": "boolean"
    },
    "_site": {
      "type": "string",
      "description": "Optional target site formatted as <workspaceSlug>/<siteSlug>. Required when the workspace has multiple sites and no site header is set.",
      "pattern": "^[^/]+/[^/]+$"
    }
  },
  "additionalProperties": false
}

On this page