Skip to main content
Glama
grm

Context Figma MCP

by grm
README.md
# Context Figma MCP

A **read-only MCP server** for extracting actual Figma prototype flows and transitions. Designed to complement [GLips/Figma-Context-MCP](https://github.com/GLips/Figma-Context-MCP): GLips provides design/layout context, while this server exposes navigational behavior for agent-generated specifications.

**No LLM inference and no Figma writes.** Missing destinations and ambiguous prototype data are returned as explicit warnings. This server does not infer backend business rules from visual design.

## Requirements

- macOS, Linux, or Windows; **Node.js 22+**
- Figma personal access token with `file_content:read`, and permission to view the file
- OpenCode (optional; the MCP Inspector can test tools independently)

## Setup

```bash
 git clone https://github.com/grm/context-figma-mcp.git
 cd context-figma-mcp
 npm install
 npm run build
 npm test
```

Keep the Figma token in your shell/session (not inside Git):

```bash
read -rs 'FIGMA_TOKEN?Figma token: ' FIGMA_TOKEN; echo
export FIGMA_TOKEN
```

On macOS Terminal, if using zsh, `read -rs` can prompt as shown. Or configure the token securely through your shell's credential manager. The token is never written to files by the MCP.

### Try all MCP tools without a Figma account (offline mode)

The repository includes a **synthetic** Figma REST-shaped JSON fixture with five screens, explicit navigation, a conditional branch, an overlay, a BACK action and a deliberately broken destination. It exercises the actual MCP tool handlers, but does **not** validate Figma API access or compatibility against a live file.

From the repository root:

```bash
npm install
npm run build
npm test
export FIGMA_FIXTURE_PATH="$(pwd)/test/fixtures/prototype.json"
npx @modelcontextprotocol/inspector node dist/index.js
```

In the Inspector, connect, then call these tools using the following test arguments:

| Tool | Arguments |
| --- | --- |
| `get_prototype_flows` | `{"fileKey":"offline-demo"}` |
| `get_prototype_graph` | `{"fileKey":"offline-demo"}` |
| `get_screen_interactions` | `{"fileKey":"offline-demo","screenNodeId":"1:2"}` |

Expected: `Edit email` flow, 5 screens, conditional transitions and a warning about unresolved destination `99:99`.

To test the same fixture **inside OpenCode**, merge this local MCP entry into your existing OpenCode configuration:

```json
{
  "mcp": {
    "figma-prototype-demo": {
      "type": "local",
      "command": ["node", "/ABSOLUTE/PATH/context-figma-mcp/dist/index.js"],
      "enabled": true,
      "environment": {
        "FIGMA_FIXTURE_PATH": "/ABSOLUTE/PATH/context-figma-mcp/test/fixtures/prototype.json"
      }
    }
  }
}
```

Then ask OpenCode to invoke `figma-prototype-demo_get_prototype_graph` with `fileKey="offline-demo"`. This does not require `FIGMA_TOKEN`. The `fileKey` parameter is ignored **only in offline mode**; in normal mode, it is validated and used with the Figma API.

Unset `FIGMA_FIXTURE_PATH` and remove the demo MCP entry when you switch to the real Figma service. **Never set this variable in production**, or the server will continue to serve the local fixture instead of live data.

### OpenCode integration

Add the following to the OpenCode configuration that already contains GLips, changing the absolute executable path:

```json
{
  "mcp": {
    "figma-prototype": {
      "type": "local",
      "command": ["node", "/ABSOLUTE/PATH/context-figma-mcp/dist/index.js"],
      "enabled": true,
      "environment": { "FIGMA_TOKEN": "{env:FIGMA_TOKEN}" }
    }
  }
}
```

**Merge this entry into your existing `mcp` object:** do not replace your GLips configuration. Run `opencode mcp list` to verify registration. Restart OpenCode after editing its configuration. See [`examples/opencode.jsonc`](examples/opencode.jsonc).

### Test tools without an LLM

```bash
npx @modelcontextprotocol/inspector node dist/index.js
```

Click **Connect**, select a tool and supply a Figma file URL or file key. The MCP Inspector launches the server and calls the tool directly.

Then in OpenCode try:

```text
Call figma-prototype_get_prototype_flows on this Figma design URL: https://www.figma.com/design/<FILE_KEY>/... . Report the raw flows, do not invent any transitions.
```

After choosing a flow, use `get_prototype_graph` and optionally `startNodeId` to get just the reachable screens. Use `get_screen_interactions` for buttons/interactions on a particular screen.

## Tools

| Tool | Inputs | Output |
|---|---|---|
| `get_prototype_flows` | `fileKey` | Named Figma flow starts and associated pages |
| `get_prototype_graph` | `fileKey`, optional `startNodeId` | Screens, interactions, explicit destinations and warnings |
| `get_screen_interactions` | `fileKey`, `screenNodeId` | Trigger/actions nested inside one screen |

`fileKey` accepts a file key or `https://www.figma.com/design/...` link. IDs can be `12:345` or `12-345`.

### What the graph preserves

- The triggering event (`ON_CLICK`, `ON_HOVER`, `AFTER_TIMEOUT`, etc.)
- Figma `NODE` actions, with `navigation.type` such as `NAVIGATE`, `OVERLAY`, `SWAP`, `SCROLL_TO`, `CHANGE_TO`
- Non-navigational `BACK`, `CLOSE`, variable and media actions
- Nested `CONDITIONAL` actions, including the original condition object encoded in `conditionPath`
- `transition` animation metadata, including type/duration when present
- Older `transitionNodeID` information only when modern `interactions` are absent
- Exact source and destination IDs, their screen mapping, and `provenance`

A transition to an unknown ID is **not guessed**: `resolved:false` and a warning are returned. `BACK` has no statically known destination, so `destinationId:null`.

### Local test suite

`npm test` exercises a fixture with linked screens, nested interaction nodes, condition branches, an overlay, back/close, unresolved and legacy transitions. No Figma token is needed for the tests. `npm run check` performs TypeScript checking.

## Limitations / roadmap

- This version loads the complete file once **per tool call**. Very large files may be slow or rate-limited; the next iteration can add caching and partial node fetching.
- Figma URLs and destination references stay inside the same file; external navigation uses action metadata, not cross-file screen resolution.
- The server cannot derive functional validation or API behavior from Figma alone. Combine its output with Jira tickets, screenshots and PO validation in `/specify`.
- Frames without configured interactions cannot become reliably inferred navigation flows.
- Only the specific official Figma REST structures are interpreted. Unknown action fields are not treated as implicit transitions.

## Security

Read-only REST endpoint `GET /v1/files/{key}`; file keys are validated; arbitrary URLs are never fetched; token passed only via `X-Figma-Token`; no HTTP server is exposed (stdio only). Never commit `.env` or token values.

## Development

The MCP SDK used is the current v2 TypeScript SDK. Node 22+ required; CI runs types, build and tests for PRs. This implementation is initially tested against synthetic fixtures; validation against a real prototyped Figma file is required before relying on it in a specification pipeline.

TDQS

A3.7/5.0

Scored across 3 tools

Disambiguation4/5

The three tools target distinct granularities: single screen, flow starting points, and global graph. However, get_screen_interactions and get_prototype_graph (when limited to a screen) can both return screen-level interactions, creating minor overlap that descriptions mostly resolve.

Naming Consistency5/5

All tools use the get_ prefix followed by a snake_case noun phrase (get_screen_interactions, get_prototype_flows, get_prototype_graph), a consistent verb_noun pattern throughout.

Tool Count5/5

Three tools is well-scoped for a focused, read-only prototype-context server. Each tool covers a distinct retrieval need (per-screen details, flow list, navigation graph) without redundancy.

Completeness4/5

The set covers screen interactions, flow origins, and the full navigation graph, which is complete for read-only prototype context. A minor gap exists for retrieving interactions of arbitrary nodes not tied to a screen or flow, but core workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues