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

electromcp

v1.2.0

Published

Connect Claude to any Electron app — testing, debugging, visual QA, and full automation

Readme

ElectroMCP

An Electron · Playwright · MCP Server

ElectroMCP Hero


Your AI is flying blind inside your Electron app.

Whether you're working with Claude, Gemini, Codex, Cursor, Windsurf, or GitHub Copilot — every time you want your AI to help with your UI, you're doing the same painful loop:

Run the app. Screenshot it. Paste it in. Describe what's wrong. Wait. Get an answer. Make a change. Start over.

You've become a human copy-paste machine. Manually bridging the gap between the most capable AI tools in history and the product you're building, one screenshot at a time.

ElectroMCP removes you from that loop entirely.

It's an MCP server. Connect it once to any MCP-compatible AI. Now your AI opens your app, takes its own screenshots, clicks through your flows, reads the console, runs your test suite, and comes back with a full report before you've even looked. Not a guess. A report — bugs, visual inconsistencies, broken interactions, console errors, the lot.

The QA session that used to take you an hour? It's a ten-second conversation now.

This isn't AI-assisted QA. This is AI-operated QA. There's a difference.


CI npm version


What This Looks Like In Practice

You open your AI of choice. You say: "Check my onboarding flow. Make sure every screen looks right and the button on step 3 works."

Your AI launches the app, navigates every screen, takes screenshots, clicks the button, reads the result, and comes back with a full breakdown. You didn't paste a single screenshot. You didn't describe a single UI element. You just asked.

That is what this tool does.


Install

The core command is the same everywhere — npx electromcp. Only the config location differs by AI tool.

Claude Code (one command)

claude mcp add electromcp -- npx electromcp

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "electromcp": {
      "command": "npx",
      "args": ["electromcp"]
    }
  }
}

Gemini CLI

Edit ~/.gemini/settings.json:

{
  "mcpServers": {
    "electromcp": {
      "command": "npx",
      "args": ["electromcp"]
    }
  }
}

Cursor

Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json (project-level):

{
  "mcpServers": {
    "electromcp": {
      "command": "npx",
      "args": ["electromcp"]
    }
  }
}

Windsurf

Edit ~/.codeium/windsurf/mcp_settings.json:

{
  "mcpServers": {
    "electromcp": {
      "command": "npx",
      "args": ["electromcp"]
    }
  }
}

VS Code (GitHub Copilot)

Edit .vscode/mcp.json in your project:

{
  "servers": {
    "electromcp": {
      "command": "npx",
      "args": ["electromcp"]
    }
  }
}

Smithery (any AI)

npx @smithery/cli install electromcp

Smithery handles the config automatically for whichever AI tool you're using.


Connecting Your AI to Your App

Launch from source

app_launch  {
  executablePath: "/path/to/electron",
  args: ["/path/to/your-app"]
}

Full feature set: screenshots, accessibility tree, HAR recording, dialog stubs, everything.

Attach to a running instance

app_connect  { port: 9222 }

Add one line to main.js to enable the debug port:

app.commandLine.appendSwitch('remote-debugging-port', '9222');

Or via package.json:

{
  "scripts": {
    "start:debug": "electron . --remote-debugging-port=9222"
  }
}

Tools

App Lifecycle

| Tool | What It Does | |------|-------------| | app_launch | Launch an Electron app via Playwright. Full fidelity: screenshots, HAR, dialog stubs. Accepts executablePath, args, debugPort, harPath. | | app_connect | Attach to a running app over CDP. Accepts port (default 9222) or a full url. | | app_disconnect | Disconnect without killing the app. | | app_stop | Shut down the app and disconnect. | | app_health | Ping the connection. If the page is dead, triggers automatic reconnect. |

Visual Inspection

| Tool | What It Does | |------|-------------| | ui_screenshot | Take a full screenshot of the current window. | | ui_accessibility_snapshot | Return the full accessibility tree. Faster and cheaper than a screenshot. Use this first when you want to understand structure rather than visuals. | | ui_get_dom | Get the raw HTML of the page or a specific element. | | ui_observe | Capture the visual state for AI analysis. Returns the screenshot with context so the AI can reason about what it sees. |

Interaction

| Tool | What It Does | |------|-------------| | ui_click | Click any element by selector or visible text. | | ui_fill | Fill an input field instantly (no typing delay). | | ui_type | Type text character by character. Useful when apps respond to keystrokes rather than final values. | | ui_press | Press a keyboard shortcut: Enter, Escape, Ctrl+S, Cmd+K, anything. | | ui_hover | Hover over an element to trigger tooltips or hover states. | | ui_scroll | Scroll the page or a specific element in any direction. | | ui_wait_for | Wait for a selector to appear, disappear, or become visible. | | ui_get_element | Get the attributes, text content, bounding box, visibility, and enabled state of an element. | | ui_act | Returns a screenshot so the AI can decide what to do next. You describe the goal, the AI figures out the selector. |

Debugging

| Tool | What It Does | |------|-------------| | app_console_logs | Pull the console output from the renderer process. Everything console.log, console.error, and console.warn produced since launch. | | app_evaluate_renderer | Run any JavaScript in the renderer process and get the return value. Inspect live state, query the DOM, check variables. | | app_evaluate_main | Run JavaScript in the main process. Requires ALLOW_MAIN_EVAL=1. Intentionally gated. | | app_crash_status | Check whether the renderer has crashed. | | app_crash_reset | Clear the crash flag and continue. |

Test Runner

| Tool | What It Does | |------|-------------| | test_run | Run any shell command and parse it as a test run: pass/fail counts, failure details, raw output. Works with Jest, Vitest, Playwright, Mocha, or anything that exits non-zero on failure. | | test_run_file | Run a specific test file. | | test_run_grep | Run tests matching a name pattern. | | test_get_results | Return the parsed results from the last test run. |

Window Management

| Tool | What It Does | |------|-------------| | window_list | List every open window: title, URL, dimensions, focus state. | | window_switch | Switch to a window by title substring or index. | | window_get_by_title | Find the first window whose title contains a given string. |

Electron-Specific

| Tool | What It Does | |------|-------------| | electron_ipc_send | Send a message on any IPC channel via ipcRenderer. Works in launch and CDP modes. Tries contextBridge first, then nodeIntegration fallback. | | electron_stub_dialog | Stub native OS dialogs before the action that opens them. Native dialogs block Playwright, so stub them so flows don't hang. | | electron_on_crash | Wait for a renderer crash or timeout. Useful for crash-recovery testing. |

Network Recording

| Tool | What It Does | |------|-------------| | batch_run | Plan a multi-step sequence. Returns an ordered list for the AI to execute one tool at a time. | | app_record_har | Start HAR network recording. Relaunches the app with recordHar enabled and captures every HTTP request and response. | | app_stop_har | Flush and save the HAR file. Ends the session; call app_launch to reconnect. |

Video Recording

| Tool | What It Does | |------|-------------| | app_record_video | Start .webm video recording of the app session. Relaunches with Playwright recordVideo enabled. Launch mode only. Accepts outputDir. | | app_stop_video | Flush and save the video file. Returns the .webm file path. Ends the session; call app_launch to reconnect. |


The Recommended Flow

1. app_health                 confirm the connection is alive
2. ui_accessibility_snapshot  understand what's on screen (no image cost)
3. ui_screenshot              capture the visual state (only when layout matters)
4. ui_click / ui_fill / ...   interact with the app
5. ui_accessibility_snapshot  verify the result

For debugging:

1. app_console_logs           what did the renderer actually log?
2. app_evaluate_renderer      inspect live DOM, variables, state
3. app_evaluate_main          check main process (needs ALLOW_MAIN_EVAL=1)

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | ALLOW_MAIN_EVAL | unset | Set to 1 to enable app_evaluate_main |


Limitations Worth Knowing

electron_ipc_send sends from the renderer. If your app uses contextIsolation: true without a contextBridge-exposed ipcRenderer and without nodeIntegration: true, the call fails with a clear error.

HAR recording requires launch mode. It cannot be added to an existing CDP session.

app_evaluate_main is launch mode only and requires ALLOW_MAIN_EVAL=1.

Headless mode is not officially supported by Electron. On Linux CI: xvfb-run npm test.


Development

git clone https://github.com/TheRealSeanDonahoe/electromcp
cd electromcp
npm install
npm run build    # tsc -> build/
npm run dev      # tsx src/index.ts
npm test         # builds + runs 8 integration tests against a real Electron window

On Linux: xvfb-run npm test


License

MIT