AgentStack
MCP verified MIT Self-run

Electron Dev Bridge

mcp-delta-and-beta-electron-dev-bridge · by delta-and-beta

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

No reviews yet
0 installs
4 views
0.0% view→install

Install

$ agentstack add mcp-delta-and-beta-electron-dev-bridge

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Electron Dev Bridge? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

electron-dev-bridge

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

[](https://github.com/delta-and-beta/electron-dev-bridge/actions) [](https://www.typescriptlang.org/) [](https://nodejs.org/) [](./src/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 33 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 (33)

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"

# 33 built-in CDP tools
electron_evaluate  expression="document.title"
electron_screenshot
electron_click  selector="[data-testid='submit']"
electron_fill  selector="#email"  text="new@example.com"
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

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

Connection & Targets (4 tools)

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

DOM Queries (5 tools)

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

Interaction (6 tools)

| 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 ` by value or visible text | | electron_hover` | Hover over element, triggering CSS :hover and JS mouseenter events |

State Reading (6 tools)

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

Navigation & Viewport (5 tools)

| 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 | | electron_wait_for_network_idle | Wait until no network requests are pending for N ms |

Screenshots & Visual (3 tools)

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

DevTools Capture (4 tools)

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

app

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

tools

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} |

resources

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 |

cdpTools

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

customTools

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.

screenshots

| 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_

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.