Documentation

FigClank MCP Design Contract

The stable contract for the FigClank read-only MCP server.

Overview

  • Mode: Read-only. No mutations are allowed via MCP.
  • Auth: Wallet-based authentication. All document-scoped tools require user authentication.
  • Units: All dimensions are in pixels (px) unless otherwise noted.
  • IDs: All identifiers (nodeId, documentId, componentId, styleId) are strings.

Node Types

type NodeType =
  | "PAGE"
  | "FRAME"
  | "RECTANGLE"
  | "TEXT"
  | "COMPONENT"
  | "INSTANCE"
  | "GROUP"
  | "VECTOR"
  | "ELLIPSE"
  | "LINE"
  | "POLYGON"
  | "STAR"
  | "BOOLEAN_OPERATION";

Core Schemas

MCPNode

The canonical node schema exposed by the MCP. All fields use consistent types and units.

interface MCPNode {
  // Identity
  id: string;
  name: string;
  type: NodeType;
  parentId: string | null;

  // Transform (all in px)
  x: number;
  y: number;
  width: number;
  height: number;
  rotation?: number; // degrees

  // Visibility
  visible?: boolean;
  locked?: boolean;
  opacity?: number; // 0-1

  // Layout (Auto Layout)
  layout?: {
    mode: "NONE" | "HORIZONTAL" | "VERTICAL";
    primaryAxisAlign: "MIN" | "CENTER" | "MAX" | "SPACE_BETWEEN";
    counterAxisAlign: "MIN" | "CENTER" | "MAX" | "STRETCH";
    primaryAxisSizing: "FIXED" | "AUTO" | "FILL";
    counterAxisSizing: "FIXED" | "AUTO" | "FILL";
    padding: { top: number; right: number; bottom: number; left: number; };
    itemSpacing: number | "AUTO";
    wrap?: boolean;
  };

  // Style
  style?: {
    fills?: MCPFill[];
    strokes?: MCPStroke[];
    effects?: MCPEffect[];
    cornerRadius?: number;
    clipsContent?: boolean;
    blendMode?: string;
  };

  // Text (for TEXT nodes)
  text?: {
    characters: string;
    fontSize: number;
    fontFamily: string;
    fontStyle: string;
    textAlignHorizontal: "LEFT" | "CENTER" | "RIGHT" | "JUSTIFIED";
    textAlignVertical: "TOP" | "CENTER" | "BOTTOM";
    autoResize: "WIDTH_AND_HEIGHT" | "HEIGHT" | "NONE";
  };

  // Component reference (for INSTANCE nodes)
  componentRef?: {
    componentId: string;
    componentKey?: string;
  };
}

MCPFill

interface MCPFill {
  type: "SOLID" | "GRADIENT_LINEAR" | "GRADIENT_RADIAL" | "GRADIENT_ANGULAR" | "GRADIENT_DIAMOND" | "IMAGE";
  visible?: boolean;
  opacity?: number; // 0-1
  blendMode?: string;

  // For SOLID
  color?: MCPColor;

  // For gradients
  gradientStops?: Array<{ position: number; color: MCPColor; }>;

  // For IMAGE
  imageRef?: string;
  scaleMode?: "FILL" | "FIT" | "CROP" | "TILE";
}

MCPColor

interface MCPColor {
  r: number; // 0-1
  g: number; // 0-1
  b: number; // 0-1
  a: number; // 0-1
}

MCPEffect

interface MCPEffect {
  type: "DROP_SHADOW" | "INNER_SHADOW" | "LAYER_BLUR" | "BACKGROUND_BLUR";
  visible?: boolean;
  radius?: number; // px
  color?: MCPColor;
  offset?: { x: number; y: number }; // px
  spread?: number; // px
}

Tool Categories

Discovery

ToolDescription
auth.whoamiGet current user info
workspace.listProjectsList user's projects/designs
documents.listList documents in a project
documents.getGet document metadata

Snapshots & History

ToolDescription
documents.getSnapshotGet lightweight snapshot summary
history.listVersionsList document versions

Node Inspection

ToolDescription
nodes.getGet single node
nodes.listChildrenList children of a node
nodes.getSubtreeGet subtree with depth limit
nodes.queryQuery nodes by criteria

Design System

ToolDescription
components.listList components
components.getGet component definition
styles.listList styles
tokens.getGet design tokens

Export / Render

ToolDescription
render.thumbnailGet node thumbnail
export.svgExport node as SVG
export.pngExport node as PNG

Read-Only Guarantee

Important
This MCP server is strictly read-only. No tools modify document state. No tools create, update, or delete nodes. No tools change styles, components, or tokens. All operations are idempotent. To edit designs, use the FigClank web application.

Error Codes

ToolDescription
NOT_FOUNDResource does not exist (404)
FORBIDDENUser lacks permission (403)
VALIDATION_ERRORInvalid input parameters (400)
RATE_LIMITEDToo many requests (429)
INTERNAL_ERRORServer error (500)

Version Pinning

All document-scoped tools accept an optional version parameter:

// Load a specific version (deterministic)
nodes.get({ nodeId, documentId, version: 42 })

// Load latest (may change between calls)
nodes.get({ nodeId, documentId })

Agents should pass version for reproducible codegen workflows.