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

electron-ui-mcp

v0.1.3

Published

Electron UI automation MCP server with Playwright-style primitives

Readme

electron-ui-mcp

⚠️ WARNING: This project is under active development and not ready for production use.

APIs, tool names, and configuration formats may change without notice.

Electron UI automation MCP server with Playwright-style primitives.

This package provides a Model Context Protocol (MCP) server that enables AI assistants to automate Electron desktop applications using a familiar Playwright-like API.

Features

  • Electron-focused tool naming - Uses electron_* for renderer tools and main_* for main process tools
  • Auto-detection - Automatically finds Electron entry points when run from a project root
  • Lazy initialization - App launches automatically on first tool call
  • Lifecycle guards - State machine ensures tools only run when app is ready
  • Snapshot-based element addressing - ARIA tree snapshots with element refs (e0, e1, etc.)
  • Annotated screenshots - Overlay ref labels on screenshots for visual debugging
  • Dev and packaged app support - Works with both development builds and packaged executables
  • Session-scoped app override - Tools accept an optional app field to override entry/path detection

Quick Start

No installation required - use npx directly:

Add to Claude Code

claude mcp add electron-ui-mcp -- npx electron-ui-mcp --dev .vite/build/main.js --cwd /path/to/your-electron-app

Add to Codex CLI

codex mcp add electron-ui-mcp -- npx electron-ui-mcp --dev .vite/build/main.js --cwd /path/to/your-electron-app

Add to Gemini CLI

gemini mcp add electron-ui-mcp -- npx electron-ui-mcp --dev .vite/build/main.js --cwd /path/to/your-electron-app

Usage

CLI

# Dev mode - launch from main.js entry
electron-ui-mcp --dev .vite/build/main.js --cwd /path/to/app

# With Vite dev server
electron-ui-mcp --dev .vite/build/main.js --dev-server http://localhost:5173

# Packaged app (macOS)
electron-ui-mcp --packaged /Applications/MyApp.app

# Packaged app (Windows)
electron-ui-mcp --packaged "C:\Program Files\MyApp\MyApp.exe"

# With isolated userData (default) + E2E
electron-ui-mcp --dev .vite/build/main.js --e2e

# Disable isolation (use real userData)
electron-ui-mcp --dev .vite/build/main.js --no-isolated

CLI Options

Options:
  --dev <path>           Launch dev mode with main.js entry (auto-detects if omitted)
  --packaged <path>      Launch packaged app executable
  --cwd <path>           Working directory
  --user-data-dir <path> Custom userData directory
  --no-isolated          Disable isolated userData (default: enabled)
  --dev-server <url>     Dev server URL for renderer
  --e2e                  Enable E2E mode
  --timeout <ms>         Launch timeout (default: 60000)
  --config <path>        Path to config file

Configuration

Claude Desktop

Add to your Claude Desktop config (~/.claude.json):

{
  "mcpServers": {
    "electron": {
      "command": "npx",
      "args": ["electron-ui-mcp", "--dev", ".vite/build/main.js"],
      "cwd": "/path/to/your-electron-app"
    }
  }
}

Codex CLI

Codex stores MCP config in ~/.codex/config.toml:

[mcp_servers.electron]
command = "npx"
args = ["electron-ui-mcp", "--dev", ".vite/build/main.js", "--cwd", "/path/to/your-electron-app"]

Gemini CLI

Gemini stores MCP config in ~/.gemini/settings.json:

{
  "mcpServers": {
    "electron": {
      "command": "npx",
      "args": ["electron-ui-mcp", "--dev", ".vite/build/main.js", "--cwd", "/path/to/your-electron-app"]
    }
  }
}

Configuration File

Create electron-ui-mcp.json in your project root:

{
  "mode": "dev",
  "appPath": ".vite/build/main.js",
  "rendererUrl": "http://localhost:5173",
  "isolated": true,
  "e2e": true,
  "timeout": 60000
}

Environment Variables

| Variable | Description | |----------|-------------| | ELECTRON_APP_PATH | Path to executable or main.js | | ELECTRON_CWD | Working directory | | ELECTRON_USER_DATA_DIR | Custom userData directory | | ELECTRON_RENDERER_URL | Dev server URL for renderer | | E2E | Enable E2E mode (sets E2E=1) | | ELECTRON_LAUNCH_TIMEOUT | Launch timeout in ms | | ELECTRON_MODE | dev or packaged |

Auto-Detection

When run from an Electron project root without explicit --dev or --packaged flags, the MCP server automatically detects the entry point by checking (in order):

  1. .vite/build/main.js (Electron Forge + Vite)
  2. dist/main.js
  3. dist/main/index.js (Electron Builder)
  4. out/main.js
  5. out/main/index.js
  6. build/main.js
  7. package.json#main (if it exists on disk)

The server validates that package.json contains an Electron dependency before attempting auto-detection.

Session-Scoped App Override

All renderer tools accept an optional app field to override detection for the current session (until another override is provided):

{
  "name": "electron_snapshot",
  "arguments": {
    "app": {
      "path": "/path/to/my-electron-app",
      "entry": "out/main/index.js",
      "isolated": true,
      "e2e": true
    }
  }
}

| Field | Description | |-------|-------------| | path | App root directory (defaults to CWD) | | entry | Explicit entry point (relative to path) | | devServer | Dev server URL for renderer | | isolated | Use isolated userData (default: true) | | e2e | Enable E2E mode |

Available Tools

Renderer Tools (electron_*)

| Tool | Description | |------|-------------| | electron_navigate | Navigate to URL | | electron_navigate_back | Go back in history | | electron_snapshot | Capture accessibility tree with refs | | electron_screenshot | Take screenshot (with optional ref annotations) | | electron_click | Click element by ref | | electron_type | Type into element | | electron_press_key | Press keyboard key | | electron_fill_form | Fill multiple form fields | | electron_select_option | Select dropdown option | | electron_hover | Hover over element | | electron_drag | Drag and drop | | electron_file_upload | Upload files | | electron_handle_dialog | Handle JS dialogs | | electron_wait_for | Wait for condition | | electron_evaluate | Execute JS in renderer | | electron_windows | List/select windows | | electron_resize | Resize window | | electron_close | Close application | | electron_console | Get console log | | electron_network | Get network log |

Main Process Tools (main_*)

| Tool | Description | |------|-------------| | main_evaluate | Execute JS in main process | | main_app_info | Get app metadata |

How It Works

Snapshot and Refs

The electron_snapshot tool captures an accessibility tree of the current page:

- [e0] heading "Welcome" [level 1]
- [e1] button "Sign In"
- [e2] textbox "Email"
- [e3] textbox "Password"
- [e4] button "Submit"

Use these refs with interaction tools:

{
  "name": "electron_click",
  "arguments": {
    "element": "Submit button",
    "ref": "e4"
  }
}

Important: Refs are invalidated when a new snapshot is taken or when switching between windows. Always take a fresh snapshot before interacting with elements.

Annotated Screenshots

Use electron_screenshot with annotate: true to overlay ref labels on the screenshot:

{
  "name": "electron_screenshot",
  "arguments": {
    "annotate": true
  }
}

This draws red highlight boxes and ref labels (e0, e1, etc.) at each element's position, making it easy to visually identify which ref corresponds to which UI element.

Note: If no snapshot has been taken yet, annotate: true will automatically capture one, which generates new refs. This can invalidate refs from a previous snapshot.

┌─────────────────────────────────┐
│  e0                             │
│  ┌───────────────────────────┐  │
│  │     Welcome to App        │  │
│  └───────────────────────────┘  │
│                                 │
│  e1                e2           │
│  ┌──────┐  ┌─────────────────┐  │
│  │Email │  │_________________│  │
│  └──────┘  └─────────────────┘  │
│                                 │
│             e3                  │
│           ┌────────┐            │
│           │ Submit │            │
│           └────────┘            │
└─────────────────────────────────┘

If no snapshot has been taken yet, one will be captured automatically before annotating.

Lifecycle States

The server manages these states:

  • idle - Not launched
  • launching - Starting up
  • ready - App running, ready for tools
  • error - Launch failed
  • closed - App was closed

Tools automatically launch the app if needed (lazy initialization).

Programmatic Usage

Install as a dependency:

npm install electron-ui-mcp

Then use in your code:

import { createServer, resolveConfig } from 'electron-ui-mcp';

const config = resolveConfig({
  dev: '.vite/build/main.js',
  isolated: true,
});

const server = createServer(config);

Security Considerations

Main Process Code Execution

The main_evaluate tool executes arbitrary JavaScript in the Electron main process. This is intentionally powerful for automation but should only be used in trusted environments. The main process has full Node.js and system access.

Environment Variable Passthrough

By default, all environment variables from the host process are passed to the launched Electron app. This can unintentionally expose secrets if the app logs or exposes environment variables. Prefer a sanitized environment or set specific variables via the config. Isolation is enabled by default; use --no-isolated only if you need real user data.

File Access

The electron_file_upload tool can read arbitrary local files. This is expected behavior for automation but worth noting when exposing this server to untrusted callers.

Requirements

  • Node.js >= 18
  • Electron >= 28 (peer dependency)
  • Playwright >= 1.50

License

MIT