npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

metalab-mcp-client

v1.6.1

Published

MCP client for connecting to Metalab's MCP Gateway with OAuth 2.1 authentication

Downloads

211

Readme

metalab-mcp-client

Connect your AI assistant to Metalab's MCP services - Figma, Notion, Jira, and more.

This package is a local OAuth 2.1 proxy that enables MCP clients (Claude Desktop, Claude Code, Windsurf, Cursor, etc.) to securely connect to Metalab's MCP Gateway. It handles authentication via Okta, manages tokens, and forwards your requests to backend services.

flowchart LR
    A["Your AI Tool<br/>(Claude, etc.)"] -->|stdio| B["mcp-client<br/>(this package)"]
    B -->|"HTTPS + OAuth"| C["MCP Gateway<br/>(Figma reads, Notion,<br/>Jira, GitHub, Slack)"]
    B -->|"WebSocket"| D["Figma Plugin<br/>(writes + live-reads)"]

Quick Start

  • Do you know how to manually set up your client or already have custom settings? (Windsurf, Claude, etc.)
    • Nonpx metalab-mcp-client@latest config --output
    • Yesnpx metalab-mcp-client@latest config

After setting up your client, make sure the new settings have been applied (restarting the app can help). The next time you open it, your web browser will open and ask you to sign in with Okta. After you sign in successfully, you’ll be able to start using the MCP tools in your AI assistant.


Installation

The package is published on npmjs.org (public, no authentication needed).

# Run directly with npx (recommended)
npx metalab-mcp-client@latest

# Or install globally
npm install -g metalab-mcp-client
metalab-mcp

Note on Package Name

This package was previously published as @metalabdesign/mcp-client. It was renamed to metalab-mcp-client (non-scoped) to avoid registry conflicts with project-level .npmrc files that redirect @metalabdesign packages to GitHub Packages.

If you're upgrading from the old package, update your MCP client configs to use metalab-mcp-client instead of @metalabdesign/mcp-client.


MCP Client Configuration

Claude Desktop (Recommended)

Option 1: Auto-generate config

npx metalab-mcp-client@latest config --client claude --output

Option 2: Manual configuration

Add to your Claude Desktop config file:

| Platform | Config File Location | | -------- | ----------------------------------------------------------------- | | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json | | Linux | ~/.config/Claude/claude_desktop_config.json |

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"]
        }
    }
}

With service tokens (for Figma, Notion, Jira, GitHub, Slack access):

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE",
                "NOTION_ACCESS_TOKEN": "secret_YOUR_TOKEN_HERE",
                "JIRA_API_TOKEN": "YOUR_JIRA_API_TOKEN",
                "JIRA_EMAIL": "[email protected]",
                "JIRA_INSTANCE_URL": "https://company.atlassian.net",
                "GITHUB_TOKEN": "ghp_YOUR_TOKEN_HERE",
                "SLACK_MCP_XOXB_TOKEN": "xoxb-YOUR_BOT_TOKEN_HERE"
            }
        }
    }
}

Claude Code

Option 1: Use claude mcp add command (recommended)

# Basic installation
claude mcp add metalab --scope user -- npx metalab-mcp-client@latest

# With service tokens
claude mcp add metalab --scope user \
    -e "FIGMA_ACCESS_TOKEN=figd_YOUR_TOKEN" \
    -e "NOTION_ACCESS_TOKEN=secret_YOUR_TOKEN" \
    -e "JIRA_API_TOKEN=YOUR_JIRA_TOKEN" \
    -e "[email protected]" \
    -e "JIRA_INSTANCE_URL=https://company.atlassian.net" \
    -e "GITHUB_TOKEN=ghp_YOUR_TOKEN" \
    -e "SLACK_MCP_XOXB_TOKEN=xoxb-YOUR_TOKEN" \
    -- npx metalab-mcp-client@latest

Option 2: Manual configuration

Add to ~/.claude.json:

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE"
            }
        }
    }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE"
            }
        }
    }
}

Cursor

Add to ~/.cursor/mcp.json:

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE"
            }
        }
    }
}

Cline (VS Code)

Add to .vscode/cline_mcp_settings.json in your project:

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE"
            }
        }
    }
}

With Figma Write (Plugin Bridge)

Figma write tools are enabled by default. They work with both personal access tokens and Figma OAuth. No extra flags needed:

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE"
            }
        }
    }
}

To disable the write bridge (reads only), use --no-figma-write:

{
    "mcpServers": {
        "metalab": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest", "--no-figma-write"],
            "env": {
                "FIGMA_ACCESS_TOKEN": "figd_YOUR_TOKEN_HERE"
            }
        }
    }
}

When enabled, the proxy starts a local WebSocket server (auto-selects a port in range 9380-9389) that the Figma plugin connects to:

  • Figma token (FIGMA_ACCESS_TOKEN): for API-based reads via the gateway; also auto-enables the write bridge
  • Figma plugin: for write and live-read operations via the local bridge

See the Figma Write Bridge section below for plugin setup and available tools.

Using Development Environment

For testing against the dev gateway, add the --dev flag:

{
    "mcpServers": {
        "metalab-dev": {
            "command": "npx",
            "args": ["metalab-mcp-client@latest", "--dev"]
        }
    }
}

Service Tokens

Each MCP service requires a personal access token for authentication. The tokens you provide are forwarded to the respective service APIs.

| Service | Required Credentials | How to Provide | | ---------- | -------------------------------- | ------------------------------------------------------ | | Figma | Access Token | FIGMA_ACCESS_TOKEN env var or --figma-token flag | | Notion | Integration Secret | NOTION_ACCESS_TOKEN env var or --notion-token flag | | Jira | API Token + Email + Instance URL | See Jira section below | | GitHub | Personal Access Token | GITHUB_TOKEN env var or --github-token flag | | Slack | Bot or User Token | SLACK_MCP_XOXB_TOKEN env var or --slack-token flag |

Getting Your Figma Token

  1. Log in to your Figma account
  2. From the file browser, click your account menu (top-left corner) and select Settings
  3. Select the Security tab
  4. Scroll to Personal access tokens and click Generate new token
  5. Enter a descriptive name (e.g., "MCP Integration")
  6. Configure scopes (permissions):
    • File content: Read-only (required for all MCP tools)
    • No write permissions needed
  7. Copy the token immediately (starts with figd_)

Important: The token only displays once after generation. If you navigate away, you'll need to create a new one.

Token format: figd_XXXXXXXXXXXXXXXXXXXXX

Required Scopes: The gateway MCP tools perform read operations (fetching design data, downloading images, searching nodes). Your token needs read access to files you want to work with. Write operations (creating/modifying nodes) go through the Figma plugin bridge and don't require a token — the plugin uses your Figma session.

Getting Your Notion Token

  1. Log in to your Notion workspace
  2. Go to the integrations dashboard at https://www.notion.so/profile/integrations
  3. Click + New integration
  4. Configure the integration:
    • Name: Give it a descriptive name (e.g., "MCP Integration")
    • Associated workspace: Select your workspace
    • Capabilities (required permissions):
      • Read content: Required for reading pages, databases, and blocks
      • Read comments: Required for retrieving comments
      • Insert content: Optional, for creating pages/blocks
      • Update content: Optional, for updating pages/blocks
  5. Click Submit to create the integration
  6. Go to the Configuration tab and copy the Internal Integration Secret (starts with secret_)

Important: Store your token securely using environment variables. Never commit it to version control.

Token format: secret_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Required Capabilities: At minimum, enable Read content and Read comments. Enable Insert content and Update content only if you need write operations.

Important: After creating the integration, you must share pages/databases with it:

  1. Open the page or database you want to access
  2. Click ••• (more menu) in the top-right corner
  3. Click + Add connections
  4. Search for and select your integration

Getting Your Jira Token

Jira requires three pieces of information:

  1. API Token: Generated from Atlassian
  2. Email: Your Atlassian account email (optional - auto-derived from Okta if not provided)
  3. Instance URL: Your Jira Cloud URL

Steps to get your API token:

  1. Go to https://id.atlassian.com/manage-profile/security/api-tokens
  2. Click Create API token (or Create API token with scopes for enhanced security)
  3. Give it a descriptive label (e.g., "Metalab MCP Access")
  4. Set the expiration (default is 1 year, max 365 days)
  5. If using scopes, select the Jira app and permissions:
    • Read: Required for searching issues, viewing projects, boards, sprints
    • Write: Optional, for creating/updating issues, transitions, comments
  6. Click Create and copy the token immediately

Important: You cannot recover the token after this step. Store it securely.

Required Permissions: The API token inherits your Jira account permissions. You can only access projects and issues that your account has access to. For read operations (search, view), standard user access is sufficient. For write operations (create, update, transition), you need the appropriate project permissions.

Configuration example:

{
    "env": {
        "JIRA_API_TOKEN": "ATATT3xFfGF0...",
        "JIRA_EMAIL": "[email protected]",
        "JIRA_INSTANCE_URL": "https://company.atlassian.net"
    }
}

Note: The JIRA_EMAIL is optional. If not provided, the gateway uses your authenticated Okta email.

Getting Your GitHub Token

GitHub tokens enable access to private repositories (guides/skills) and authenticated GitHub API calls for dev-context tools like get_recent_changes, get_pr_context, compare_branches, etc.

Required Repository Access

Your GitHub token must have read access to all repositories you want to work with:

| Use Case | Required Repo Access | | ----------------- | ------------------------------------------------------------------------------- | | Guides & Skills | metalabdesign/librarian-dev-ai-assistants | | Dev Context Tools | Any repository you query (e.g., metalabdesign/web-app, yourorg/backend-api) |

Important: Dev context tools make API calls to whatever owner/repo you specify in the tool parameters. Your token must have access to those repositories.

Creating a Token

For Personal Access Tokens (Classic):

  1. Go to GitHub > Settings > Developer settings > Personal access tokens > Tokens (classic)
  2. Click Generate new token, then select Generate new token (classic)
  3. Give it a descriptive name in the "Note" field (e.g., "Metalab MCP Access")
  4. Set an expiration date (recommended for security)
  5. Select scopes:
    • repo - Full control of private repositories (read access to code, commits, PRs)
    • Or public_repo - If only working with public repositories
  6. Click Generate token and copy it immediately

For Fine-Grained Personal Access Tokens (recommended):

  1. Go to GitHub > Settings > Developer settings > Personal access tokens > Fine-grained tokens
  2. Click Generate new token
  3. Give it a descriptive name (e.g., "Metalab MCP Access")
  4. Set an expiration date
  5. Select a resource owner (your user or an organization)
  6. Select repository access:
    • All repositories (simplest, works with any repo)
    • Or Only select repositories (more secure, but must include all repos you'll query)
  7. Set permissions:
    • Contents: Read (for commits, branches, file content)
    • Pull requests: Read (for PR context, reviews, comments)
    • Metadata: Read (required by default)
  8. Click Generate token and copy it immediately

Token format: ghp_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (classic) or github_pat_XXXXXX... (fine-grained)

Configuration example:

{
    "env": {
        "GITHUB_TOKEN": "ghp_YOUR_TOKEN_HERE"
    }
}

Or via CLI:

metalab-mcp --github-token ghp_YOUR_TOKEN_HERE

Getting Your Slack Token

Slack tokens enable access to workspace channels, messages, threads, and search. Two types of tokens are supported:

  • Bot tokens (xoxb-): For basic operations (list channels, read messages, post messages)
  • User tokens (xoxp-): Required for search functionality

Important: When you provide a token, it's used for all operations. There is no per-operation fallback. If you need search, your user token must also have all other required scopes.

Option 1: Bot Token Only (No Search)

Use this if you don't need search functionality:

  1. Go to https://api.slack.com/apps
  2. Click Create New App > From scratch
  3. Give it a name and select your workspace
  4. Go to OAuth & Permissions in the sidebar
  5. Under Scopes > Bot Token Scopes, add the required scopes (see table below)
  6. Click Install to Workspace at the top
  7. Copy the Bot User OAuth Token (starts with xoxb-)

Token format: xoxb-XXXXXXXXXXXXX-XXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX

Option 2: User Token with Full Access (Including Search)

Use this if you need search functionality. The user token must have all scopes:

  1. In your Slack App settings, go to OAuth & Permissions
  2. Under User Token Scopes, add the required scopes (see table below)
  3. Click Install to Workspace (or Reinstall if already installed)
  4. Copy the User OAuth Token (starts with xoxp-)

Required Scopes Reference

| Scope | Purpose | Bot Token | User Token | | ------------------ | -------------------------------- | ---------------- | ------------------- | | channels:read | List public channels | Required | Required | | channels:history | Read public channel messages | Required | Required | | groups:read | List private channels | Required | Required | | groups:history | Read private channel messages | Required | Required | | users:read | List workspace users | Required | Required | | search:read | Search messages across workspace | Not available | Required for search | | im:read | List direct messages | Optional | Optional | | im:history | Read direct messages | Optional | Optional | | chat:write | Post messages | Optional (write) | Optional (write) | | reactions:write | Add emoji reactions | Optional (write) | Optional (write) |

Note: Bot tokens cannot use search:read - this is a Slack API limitation. If you need search functionality, you must use a user token

Configuration example:

{
    "env": {
        "SLACK_MCP_XOXB_TOKEN": "xoxb-YOUR_BOT_TOKEN_HERE"
    }
}

Or via CLI:

metalab-mcp --slack-token xoxb-YOUR_TOKEN_HERE

CLI Reference

Commands

metalab-mcp (default)

Connect to the MCP Gateway.

metalab-mcp [options]

| Option | Description | Default | | ------------------------ | ------------------------------------------ | -------------------------- | | --gateway-url <url> | Explicit gateway URL (highest priority) | Auto-detected | | --prod | Use production environment | Default | | --dev | Use development environment | - | | --profile <name> | AWS profile for SSM lookup | Default profile | | --figma-token <token> | Figma access token | FIGMA_ACCESS_TOKEN env | | --notion-token <token> | Notion access token | NOTION_ACCESS_TOKEN env | | --jira-token <token> | Jira API token | JIRA_API_TOKEN env | | --jira-email <email> | Jira account email | JIRA_EMAIL env | | --jira-instance <url> | Jira instance URL | JIRA_INSTANCE_URL env | | --github-token <token> | GitHub personal access token | GITHUB_TOKEN env | | --slack-token <token> | Slack bot or user token | SLACK_MCP_XOXB_TOKEN env | | --no-figma-write | Disable Figma write tools (auto-enabled with Figma token) | - | | --figma-write-port <n> | WebSocket port for Figma plugin | 9380 (range: 9380-9389) | | --inspect | Run with MCP Inspector | false | | -h, --help | Show help | - |

Examples:

# Basic usage (production, auto-detects gateway URL)
metalab-mcp

# Use development environment
metalab-mcp --dev

# With Figma token (auto-enables write bridge)
metalab-mcp --figma-token figd_YOUR_TOKEN

# Figma reads only (disable write bridge)
metalab-mcp --figma-token figd_YOUR_TOKEN --no-figma-write

# With MCP Inspector for debugging
metalab-mcp --inspect

# Using environment variables
FIGMA_ACCESS_TOKEN=figd_YOUR_TOKEN metalab-mcp

metalab-mcp config

Generate configuration for MCP clients.

metalab-mcp config [options]

| Option | Description | | ------------------------ | --------------------------------------------------------------------- | | --client <name> | Target client: claude, claude-code, windsurf, cursor, cline | | --output | Write directly to client's config file | | --figma-token <token> | Include Figma token in config | | --notion-token <token> | Include Notion token in config | | --jira-token <token> | Include Jira token in config | | --slack-token <token> | Include Slack token in config |

Examples:

# Interactive mode
metalab-mcp config

# Generate config for Claude Desktop
metalab-mcp config --client claude

# Write directly to Claude Desktop config
metalab-mcp config --client claude --output

# Include tokens in generated config
metalab-mcp config --client claude --figma-token figd_YOUR_TOKEN

Gateway URL Resolution

The gateway URL is resolved in this priority order:

  1. --gateway-url option (highest priority)
  2. AWS SSM Parameter Store (environment-specific path)
  3. MCP_SERVER_URL environment variable
  4. Hardcoded URL for the environment (fallback)

How It Works

Architecture

sequenceDiagram
    participant Client as MCP Client<br/>(Claude, etc.)
    participant Proxy as mcp-client<br/>(this package)
    participant Gateway as MCP Gateway
    participant Services as MCP Services<br/>(Figma, Notion, Jira)
    participant Plugin as Figma Plugin

    Client->>Proxy: stdio
    Note over Proxy: First request triggers<br/>OAuth authentication

    alt Gateway tools (reads, Notion, Jira, etc.)
        Proxy->>Gateway: HTTPS + Bearer Token
        Gateway->>Services: Forward request
        Services-->>Gateway: Response
        Gateway-->>Proxy: MCP response
    else Figma write/live-read tools
        Proxy->>Plugin: WebSocket command
        Plugin-->>Proxy: Result from Plugin API
    end

    Proxy-->>Client: stdio

Key Features

  1. OAuth 2.1 with PKCE: Secure authentication via Okta with browser-based login
  2. Token Management: Automatically persists and refreshes access tokens
  3. Lazy Connection: Only connects to gateway when first MCP request is made
  4. Service Token Forwarding: Your personal tokens (Figma, Notion, Jira) are forwarded as HTTP headers
  5. Multiple Environments: Supports production and development gateways
  6. Automatic Session Recovery: Detects session expiration and reconnects automatically (see below)
  7. Figma Write Bridge: Optional local WebSocket bridge for direct Figma canvas manipulation via plugin (see below)

Automatic Session Recovery

Gateway sessions expire after a period of inactivity (default: 1 hour). When this happens, the proxy automatically:

  1. Detects the session error (e.g., "session not found", "internal server error")
  2. Resets the connection and establishes a new session
  3. Retries the failed request once

This means you don't need to restart Claude Code when sessions expire - the proxy handles reconnection transparently.

Rate limiting: To prevent masking real server errors, only one reconnection attempt is allowed every 10 minutes. If errors persist after reconnection, subsequent requests will fail until the cooldown period passes.

Token Flow

flowchart LR
    subgraph Client["mcp-client (with tokens)"]
        Tokens["X-Figma-Token<br/>X-Notion-Token<br/>X-Jira-Token<br/>X-Slack-Token"]
    end

    subgraph Gateway["MCP Gateway (forwards)"]
        Forward["Routes tokens<br/>to services"]
    end

    subgraph Services["MCP Services"]
        Figma["Figma MCP"]
        Notion["Notion MCP"]
        Jira["Jira MCP"]
        Slack["Slack MCP"]
    end

    Client -->|"Headers"| Gateway
    Gateway --> Figma
    Gateway --> Notion
    Gateway --> Jira
    Gateway --> Slack

Your service tokens are included in every request to the gateway, which forwards them to the appropriate downstream service.


Figma Write Bridge

The Figma Write Bridge enables your AI assistant to create, modify, and read live canvas state directly in Figma. It works alongside the gateway's API-based Figma reads, giving you the best of both worlds.

How It Works

The write bridge is enabled by default (use --no-figma-write to disable). The proxy starts a local WebSocket server, and the Metalab MCP Bridge plugin running in Figma connects to it, creating a two-way channel between the AI and the Figma canvas.

AI Assistant  ──stdio──>  mcp-client  ──WebSocket──>  Figma Plugin
                              │                            │
                              │                      Plugin API calls
                              │                      (create, modify, read)
                              │
                         Gateway reads
                         (REST API, full history)
  • Write tools (figma_write_*): Create and modify nodes directly in the open file
  • Live-read tools (figma_live_*): Read the current canvas state, including unsaved changes
  • Gateway reads (get_figma_node, search_nodes, etc.): API-based reads via the gateway (requires Figma token)
  • use_connected_file: Gateway read tools can automatically target the file open in the plugin — pass use_connected_file: true instead of a fileKey

Plugin Setup

  1. Open a file in Figma (Desktop or Web)
  2. Go to Plugins > From Metalab > Metalab MCP Bridge
  3. The plugin UI shows connection status — it should say "Connected" with a green dot

The plugin auto-reconnects if the MCP client restarts.

Available Tools

Write Tools (figma_write_*)

| Tool | Description | |------|-------------| | check_connection | Check plugin connection status and get file context | | create_frame | Create a frame (container for layouts) | | create_rectangle | Create a rectangle shape | | create_ellipse | Create an ellipse/circle | | create_component | Create a reusable component | | create_text | Create a text node (auto-loads fonts) | | create_image | Create a rectangle filled with an image (from URL or base64) | | clone_node | Duplicate an existing node | | group_nodes | Group multiple nodes together | | modify_node | Modify node properties (position, size, name, opacity, etc.) | | move_node | Move or reparent a node | | resize_node | Resize a node | | delete_node | Delete a node | | set_text_content | Update text content of a text node | | set_fill_color | Set solid fill color (RGBA 0-1) | | set_image_fill | Set an image fill on an existing node (from URL or base64) | | set_stroke | Set stroke/border properties | | set_auto_layout | Configure auto-layout (flex) on a frame | | set_selection | Select specific nodes in Figma | | export_node | Export a node as PNG/SVG/JPG/PDF (returns base64) | | evaluate_script | Run arbitrary Figma Plugin API JavaScript |

Live-Read Tools (figma_live_*)

| Tool | Description | |------|-------------| | get_current_file | File info: name, pages, current page | | get_page_structure | Node tree of the current page (configurable depth) | | get_node | Full properties of a specific node (includes unsaved changes) | | get_selection | Currently selected nodes | | get_styles | All local styles (paint, text, effect, grid) | | get_local_components | All local components with variant properties |

File Context Sync (use_connected_file)

When the plugin is connected, gateway Figma read tools can automatically use the file key from the open file:

# Instead of:
get_figma_node { "fileKey": "abc123", "nodeId": "0:1" }

# You can use:
get_figma_node { "use_connected_file": true, "nodeId": "0:1" }

This works with: get_figma_node, search_nodes, download_node_images, download_file_all_raw_images.

The figma_write_check_connection tool returns a hint about this capability when a file is connected.


Security

  • PKCE: Uses SHA-256 code challenge for OAuth 2.1
  • Token Storage: Tokens stored with 0600 permissions (owner read/write only) in ~/.metalab/mcp-local-proxy/tokens/
  • Localhost Binding: OAuth callback server binds to 127.0.0.1 only
  • Gateway Protected: MCP Gateway requires Okta authentication
  • Public Package: Safe because gateway still requires authentication

AWS SSO Integration

For automatic gateway URL discovery via SSM Parameter Store:

# Configure AWS SSO profile
aws configure sso --profile metalab-dev

# Log in
aws sso login --profile metalab-dev

# Now mcp-client will auto-detect the gateway URL
metalab-mcp --profile metalab-dev

SSM Parameter Paths:

  • Production: /mcp/gateway-url (us-east-1)
  • Development: /mcp/gateway-url (us-east-2)

Troubleshooting

"No Figma/Notion/Jira access token available"

Cause: No token provided

Solution: Add the token to your MCP client config's env section or pass via CLI flag.

OAuth callback timeout (5 minutes)

Cause: Browser didn't complete authentication in time

Solutions:

  • Ensure your browser opened the Okta login page
  • Complete authentication within 5 minutes
  • Check if port 9876 is available (or the port in your callback URL)

Token refresh fails

Cause: Refresh token expired or invalid

Solution: Clear stored tokens and re-authenticate:

rm -rf ~/.metalab/mcp-local-proxy/tokens/*

Port already in use

Cause: Another process is using the OAuth callback port

Solutions:

  • Kill the process using the port: lsof -ti:9876 | xargs kill -9
  • Use a different callback URL: --callback-url http://localhost:9877/callback

Figma write: Port 9380 already in use

Cause: Another process is using the WebSocket port

Solutions:

  • Kill the process: lsof -ti:9380 | xargs kill
  • Use a different port: --figma-write-port 9381 (also update the plugin's manifest.json and ui.html)

Figma write: Plugin not connecting

Cause: Plugin can't reach the WebSocket server

Solutions:

  • Ensure the MCP client is running (write bridge is enabled by default; check with --no-figma-write is not set)
  • Check the plugin UI — it should show connection status
  • Close and reopen the plugin from Plugins > From Metalab > Metalab MCP Bridge
  • Verify ws://localhost:9380 is accessible (or your custom port)

Tools not showing up

Cause: No token configured for that service

Expected behavior: Tools only appear when you have a valid token for the service

Solution: Configure your personal token for the service you want to use


Development

Requirements

  • Node.js 20 or later
  • (Optional) AWS CLI for SSM-based gateway URL discovery

Building

# Install dependencies
pnpm install

# Build TypeScript
pnpm run build

# Watch mode
pnpm run dev

Testing Locally

# Build and run CLI
pnpm run build
node dist/bin/cli.js --dev --inspect

Publishing

# Build and publish
pnpm run build
npm publish --access public

License

MIT