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-dev-bridge

v0.3.0

Published

Expose Electron IPC handlers as MCP tools for Claude Code, with 22 built-in CDP tools for DOM automation

Downloads

535

Readme

electron-dev-bridge

Turn your Electron app's IPC handlers into MCP tools for Claude Code

TypeScript Node.js CDP Tools License

Built for Claude Code — Connects Electron apps via CDP and MCP


Overview

electron-dev-bridge maps your Electron app's ipcMain.handle() channels to MCP tools that Claude Code can call directly. It includes 31 built-in CDP tools for DOM automation, screenshots, interaction, JS evaluation, console/network capture, and multi-window support — no IPC handlers required.

Your Electron App                   Claude Code
     ↓                                  ↓
ipcMain.handle('profiles:query')    profiles_query  ← MCP tool
ipcMain.handle('tags:add')          tags_add        ← MCP tool
ipcMain.handle('crawl:start')       crawl_start     ← MCP tool
     ↓                                  ↓
contextBridge / preload.js    ←→    electron-dev-bridge (MCP server)
                                         ↓
                              Chrome DevTools Protocol (port 9229)

When to Use

electron-dev-bridge is ideal when you need:

  • Your app's IPC handlers as Claude Code tools with Zod schema validation
  • DOM automation for testing, debugging, or building Electron apps
  • Screenshot-based QA with visual comparison
  • Console and network observability without custom IPC hooks
  • Multi-window support for apps with multiple BrowserWindows
  • Custom tools alongside built-in CDP and IPC tools
  • Live app state exposed as MCP resources Claude can read on demand

For generic browser automation without Electron-specific features, a standard Chrome DevTools MCP server works fine.

Capabilities

IPC Bridge

Auto-Discovery — Scans ipcMain.handle() calls Zod Schemas — Typed tool inputs from existing schemas Preload Mappingdomain:actionwindow.electronAPI.domain.action

CDP Tools (31)

DOM Queries — Selectors, text search, a11y tree Interaction — Click, type, fill, key press, select Visual — Screenshots, diff, highlight DevTools — Console logs, network requests Multi-Window — List targets, switch windows

CLI + Library API

init — Scaffold config from source code register — One-command Claude Code setup startServer — Programmatic embedding Custom Tools — Plugin API for arbitrary handlers

Skills

3 Sample Skills — Drop into .claude/skills/ App Dev — Tool reference and playbooks E2E Testing — Test patterns and visual regression Debugging — Diagnostic flowcharts

Quick Start

# Install in your Electron project
npm install electron-dev-bridge

# Scaffold a config from your source code
npx electron-mcp init

# Review the generated config
cat electron-mcp.config.ts

# Register with Claude Code
npx electron-mcp register

Then in Claude Code:

# Your IPC handlers are now tools
profiles_query  query="test user"
tags_add  profileId="123"  tag="vip"

# 31 built-in CDP tools
electron_evaluate  expression="document.title"
electron_screenshot
electron_click  selector="[data-testid='submit']"
electron_fill  selector="#email"  text="[email protected]"
electron_get_console_logs  level="error"
electron_get_network_requests  errorsOnly=true

How It Works

┌──────────────────────────────────────────────────────────────────┐
│                      electron-dev-bridge                         │
├──────────────────────────────────────────────────────────────────┤
│                                                                  │
│   1. CONFIG         Define IPC channels as MCP tools             │
│        ↓            (electron-mcp.config.ts)                     │
│                                                                  │
│   2. SCAN           Auto-detect ipcMain.handle() + Zod schemas   │
│        ↓            (npx electron-mcp init)                      │
│                                                                  │
│   3. REGISTER       Add MCP server to Claude Code                │
│        ↓            (npx electron-mcp register)                  │
│                                                                  │
│   4. SERVE          Start MCP server, connect via CDP            │
│        ↓            (npx electron-mcp serve)                     │
│                                                                  │
│   5. BRIDGE         Claude calls tool → preload function → IPC   │
│                     Results flow back through MCP                │
│                                                                  │
└──────────────────────────────────────────────────────────────────┘

Your Electron app needs --remote-debugging-port=9229 enabled. The bridge connects via Chrome DevTools Protocol to evaluate preload functions in the renderer process. Auto-reconnects on HMR/page reload.

Config File

The init command generates electron-mcp.config.ts by scanning your source for ipcMain.handle() calls and Zod schema exports.

import { defineConfig } from 'electron-dev-bridge'
import { profileQuerySchema } from './src/main/ipc-schemas'

export default defineConfig({
  app: {
    name: 'my-app',
    path: '/path/to/app',
    debugPort: 9229,
  },

  tools: {
    'profiles:query': {
      description: 'Search and filter profiles with pagination',
      schema: profileQuerySchema,
      returns: 'Array of profile objects',
    },
    'crawl:start': {
      description: 'Start a new crawl job',
      preloadPath: 'window.electronAPI.crawl.startJob',
    },
  },

  resources: {
    'crawl:progress': {
      description: 'Live crawl progress',
      uri: 'electron://my-app/crawl/progress',
      pollExpression: 'window.__crawlProgress || { crawled: 0, total: 0 }',
    },
  },

  cdpTools: true,
  screenshots: { dir: './screenshots', format: 'png' },

  customTools: [
    {
      name: 'list_schemas',
      description: 'List XDM schemas from API',
      inputSchema: { type: 'object', properties: { limit: { type: 'number' } } },
      handler: async (args) => ({
        content: [{ type: 'text', text: JSON.stringify(await myApi.listSchemas(args.limit)) }],
      }),
    },
  ],
})

IPC Tool Naming

IPC channel names use colon-separated domain:action format. The bridge auto-derives tool names and preload paths:

| IPC Channel | MCP Tool Name | Preload Path | |:------------|:--------------|:-------------| | profiles:query | profiles_query | window.electronAPI.profiles.query | | tags:add | tags_add | window.electronAPI.tags.add | | crawl:start | crawl_start | window.electronAPI.crawl.start |

Override the preload path when the actual method name differs:

'crawl:start': {
  description: 'Start a crawl job',
  preloadPath: 'window.electronAPI.crawl.startJob',
}

CLI Commands

| Command | Description | |:--------|:------------| | npx electron-mcp serve [config] | Start the MCP server (default) | | npx electron-mcp init | Scan source for IPC handlers and Zod schemas, generate config | | npx electron-mcp register | Register with Claude Code via claude mcp add | | npx electron-mcp validate | Validate config and report readiness | | npx electron-mcp --version | Show version |

CDP Tools

31 built-in tools for DOM automation, interaction, observability, and multi-window support. These work on any Electron app — no IPC configuration required.

| Tool | Description | |:-----|:------------| | electron_launch | Launch Electron app with remote debugging and connect via CDP | | electron_connect | Connect to an already-running Electron app | | electron_list_targets | List all page targets (BrowserWindows) with IDs, titles, and URLs | | electron_switch_target | Switch CDP connection to a different window by target ID or URL pattern |

| Tool | Description | |:-----|:------------| | electron_query_selector | Find one element by CSS selector | | electron_query_selector_all | Find all matching elements (up to 50) | | electron_find_by_text | Find elements containing text via XPath | | electron_find_by_role | Find elements by ARIA role (explicit or implicit) | | electron_get_accessibility_tree | Structured a11y tree with roles, names, and states |

| Tool | Description | |:-----|:------------| | electron_click | Click element by selector or x/y coordinates | | electron_type_text | Type text into focused or targeted element (appends) | | electron_fill | Clear field contents and type new text (replaces) | | electron_press_key | Press special key (Enter, Tab, Escape, arrows, etc.) | | electron_select_option | Select option in <select> by value or visible text |

| Tool | Description | |:-----|:------------| | electron_get_text | Get innerText of an element | | electron_get_value | Get value of input/textarea/select | | electron_get_attribute | Get a specific attribute from an element | | electron_get_bounding_box | Get position and dimensions (x, y, width, height) | | electron_get_url | Get the current page URL | | electron_evaluate | Execute arbitrary JavaScript in the renderer and return result |

| Tool | Description | |:-----|:------------| | electron_navigate | Navigate to a URL and wait for page load | | electron_wait_for_selector | Poll for element to appear (default timeout: 5s) | | electron_set_viewport | Override viewport metrics for responsive testing | | electron_scroll | Scroll page or element in a direction |

| Tool | Description | |:-----|:------------| | electron_screenshot | Capture full page or element screenshot | | electron_compare_screenshots | Byte-level diff of two screenshots (returns diff %) | | electron_highlight_element | Outline element in red for 3 seconds |

Console and network observability using CDP events — no app changes needed.

| Tool | Description | |:-----|:------------| | electron_get_console_logs | Read captured console messages (filter by level, search, since) | | electron_get_network_requests | Read captured HTTP requests (filter by URL, method, errors) | | electron_clear_devtools_data | Clear console and/or network capture buffers | | electron_get_devtools_stats | Get counts of captured console logs and network requests |

Buffers: 1000 console entries, 500 network entries max. Capture starts automatically on connect.

Config Reference

| Field | Type | Default | Description | |:------|:-----|:--------|:------------| | name | string | required | MCP server name, shown in Claude Code | | path | string | — | Electron app directory (for electron_launch) | | debugPort | number | 9229 | CDP remote debugging port | | electronBin | string | {path}/node_modules/.bin/electron | Path to Electron binary |

Each key is an IPC channel name in domain:action format.

| Field | Type | Default | Description | |:------|:-----|:--------|:------------| | description | string | required | Tool description shown to Claude | | schema | ZodType | — | Zod schema; converted to JSON Schema for input validation | | preloadPath | string | auto-derived | Override the renderer-side function path | | returns | string | — | Appended to description as Returns: {value} |

Expose live app state that Claude can read on demand.

| Field | Type | Description | |:------|:-----|:------------| | description | string | Resource description | | uri | string | Unique resource URI (e.g. electron://app/domain/resource) | | pollExpression | string | JavaScript evaluated in the renderer to fetch current data |

| Value | Behavior | |:------|:---------| | true | Enable all 31 CDP tools | | false / omitted | CDP tools disabled | | string[] | Enable only the listed tool names |

Register arbitrary tool handlers alongside IPC and CDP tools.

customTools: [{
  name: 'my_tool',
  description: 'What it does',
  inputSchema: { type: 'object', properties: { ... } },
  handler: async (args) => ({
    content: [{ type: 'text', text: JSON.stringify(result) }],
  }),
}]

Custom tools are dispatched after IPC and CDP tools — they can't shadow built-in tools.

| Field | Type | Default | Description | |:------|:-----|:--------|:------------| | dir | string | .screenshots | Output directory | | format | 'png' \| 'jpeg' | 'png' | Image format |

Library API

Import and use programmatically — no CLI required:

import { startServer, CdpBridge, getCdpTools, defineConfig } from 'electron-dev-bridge'

// Start the full MCP server programmatically
await startServer(config)

// Or use components individually
const bridge = new CdpBridge(9229)
await bridge.connect()
const tools = getCdpTools(bridge, config.app, config.screenshots)

Preload Convention

The bridge assumes your app uses the contextBridge pattern:

// preload.js
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  profiles: {
    query: (args) => ipcRenderer.invoke('profiles:query', args),
    get: (id) => ipcRenderer.invoke('profiles:get', id),
  },
  tags: {
    add: (args) => ipcRenderer.invoke('tags:add', args),
  },
})

The channel profiles:query maps to window.electronAPI.profiles.query. Override with preloadPath when the naming differs.

Zod Schema Integration

Import your existing Zod schemas for typed tool inputs:

import { defineConfig } from 'electron-dev-bridge'
import { profileQuerySchema, crawlJobSchema } from './src/main/ipc-schemas'

export default defineConfig({
  app: { name: 'my-app' },
  tools: {
    'profiles:query': {
      description: 'Search profiles',
      schema: profileQuerySchema,
    },
    'crawl:start': {
      description: 'Start a crawl',
      schema: crawlJobSchema,
      preloadPath: 'window.electronAPI.crawl.startJob',
    },
  },
})

Zod schemas are converted to JSON Schema via zod-to-json-schema. Supports Zod v3 and v4.

Sample Skills

Three Claude Code skills that teach Claude how to use the bridge effectively.

# Copy all sample skills
cp -r node_modules/electron-dev-bridge/skills/* .claude/skills/

# Or copy individual skills
cp -r node_modules/electron-dev-bridge/skills/electron-app-dev .claude/skills/

| Skill | Triggers On | Covers | |:------|:------------|:-------| | electron-app-dev | Electron app, desktop app, UI automation, DOM, IPC | Tool reference, selector strategy, build & verify playbooks | | electron-e2e-testing | Test, e2e, regression, form testing | Test patterns, form automation, visual regression, multi-page flows | | electron-debugging | Debug, bug, broken, not working, element not found | Diagnostic flowcharts, connection troubleshooting, error patterns |

Claude Code automatically loads the relevant skill when prompts match trigger keywords.

Troubleshooting

| Problem | Fix | |:--------|:----| | Cannot connect to app | Ensure app runs with --remote-debugging-port=9229. Check lsof -i :9229. | | Connects to DevTools instead of app | Bridge auto-skips devtools:// targets. If issue persists, use electron_list_targets to find the right window. | | Element not found | Use electron_get_accessibility_tree to inspect. Check for iframes or shadow DOM. | | Blank screenshot | Add electron_wait_for_selector before capturing. | | Stale connection | Bridge auto-reconnects on disconnect. If still stale, call electron_connect. | | Config not found | Run npx electron-mcp init or create electron-mcp.config.ts manually. | | Tool returns undefined | Check preload path matches contextBridge exposure. Run npx electron-mcp validate. | | Wrong window targeted | Use electron_list_targets then electron_switch_target to select the right BrowserWindow. |

Architecture

src/
├── cdp-tools/                # 31 CDP tool implementations
│   ├── lifecycle.ts           # launch, connect, list_targets, switch_target
│   ├── dom-query.ts           # query_selector, find_by_text, a11y_tree
│   ├── interaction.ts         # click, type_text, fill, press_key, select_option
│   ├── state.ts               # get_text, get_value, get_attribute, get_url, evaluate
│   ├── navigation.ts          # navigate, wait_for_selector, set_viewport, scroll
│   ├── visual.ts              # screenshot, compare_screenshots, highlight
│   └── devtools.ts            # get_console_logs, get_network_requests, clear, stats
├── server/                    # MCP server runtime
│   ├── mcp-server.ts          # Server setup, IPC/CDP/custom tool dispatch
│   ├── cdp-bridge.ts          # CDP connection, auto-reconnect, multi-target
│   ├── tool-builder.ts        # IPC channel → MCP tool conversion
│   └── resource-builder.ts    # Config resources → MCP resources
├── cli/                       # CLI commands
│   ├── index.ts               # Entry point (serve, init, register, validate)
│   ├── serve.ts               # Load config, start server
│   ├── init.ts                # Scan source, generate config
│   ├── register.ts            # claude mcp add
│   └── validate.ts            # Config validation
├── scanner/                   # Source code scanners
│   ├── ipc-scanner.ts         # Find ipcMain.handle() calls
│   └── schema-scanner.ts      # Find Zod schema exports
└── index.ts                   # Public API: defineConfig, CdpBridge, getCdpTools, startServer

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Type check
npm run lint

References

| | | |:--|:--| | Claude Code | claude.ai/code | | MCP Specification | modelcontextprotocol.io | | MCP SDK | github.com/modelcontextprotocol/typescript-sdk | | Chrome DevTools Protocol | chromedevtools.github.io/devtools-protocol | | Electron | electronjs.org |


MIT License