@debugelectron/debug-electron-mcp
v1.7.0
Published
MCP server for Electron application automation and management. See MCP_USAGE_GUIDE.md for proper argument structure examples.
Maintainers
Readme
Debug Electron MCP
The ultimate Model Context Protocol (MCP) server for automating, debugging, and testing Electron applications.
Use the power of AI to interact with ANY Electron application. Inspect the DOM, click buttons by text, fill forms, capture screenshots, and read console logs—all through a standardized protocol compatible with Claude Code, Claude Desktop, Cursor, and other MCP clients.
Install it once globally — it auto-detects which project you're in and scopes itself. Works with multiple Electron apps across multiple sessions with zero extra config.
Table of Contents
- Features
- Quick Start
- How Multi-Project Works
- Enabling Remote Debugging (Required)
- Usage Guide
- Advanced: HTTP Server Mode
- Development
- Troubleshooting
- License
Features
Universal Compatibility
- Works with ANY Electron app: No source code modifications required.
- Zero-setup integration: Connects purely via Chrome DevTools Protocol (CDP).
- Cross-platform: Supports Windows, macOS, and Linux.
Auto-Detect & Multi-Project
- Automatic project detection: Reads your
package.jsonname or folder name — each project gets its own port automatically. - No config per project: Install the MCP once globally. Open Claude Code in any Electron project and it just works.
- Multiple apps, no conflicts: App A on port 9222, App B on port 9223 — each Claude Code session only talks to its own app.
- Shared registry on disk:
~/.debug-electron-mcp.jsonpersists port assignments across sessions and restarts.
Smart UI Automation
- Semantic Interaction: specific
click_by_textandfill_inputcommands that "just work." - Visual Intelligence: Take screenshots of specific windows to verify state.
- Robust Actions: Advanced
drag,hover,type, andwaitcommands for complex workflows.
Deep Observability
- DOM Inspection:
get_page_structuregives AI a clean copy of the interactive operational map. - Log Streaming: Read main process, renderer, and console logs in real-time.
- Performance: Monitor memory, timing, and system metrics.
Quick Start
Step 1: Add to your MCP config (one time)
Claude Code (Global — recommended)
Add to ~/.claude/settings.json:
{
"mcpServers": {
"debug-electron-mcp": {
"command": "npx",
"args": ["-y", "@debugelectron/debug-electron-mcp@latest"]
}
}
}Done. Every Claude Code session now has the Electron tools available.
VS Code / Cursor
{
"mcpServers": {
"debug-electron-mcp": {
"command": "npx",
"args": ["-y", "@debugelectron/debug-electron-mcp@latest"]
}
}
}Claude Desktop
{
"mcpServers": {
"debug-electron-mcp": {
"command": "npx",
"args": ["-y", "@debugelectron/debug-electron-mcp@latest"]
}
}
}Step 2: Start your Electron app with remote debugging
The first time you use the MCP in a project, it auto-registers the project and assigns a port. Check list_projects() to see your assigned port, then start your app:
electron . --remote-debugging-port=9222That's it. The MCP auto-detects your project and scopes all commands to it.
How Multi-Project Works
The MCP automatically detects which project it's running in — no flags, no projectName in every call, no per-project config.
What happens when Claude Code opens in your project:
- Claude Code spawns the MCP server from your project directory
- The MCP reads your
package.jsonname (or uses the folder name) - If the project is already registered, it uses the existing port
- If it's new, it auto-registers and assigns the next free port
- All tool calls are automatically scoped to that project's port
Example: Two apps, two sessions
# Session A: Claude Code in ~/projects/music-app/
# MCP auto-detects "music-app" → port 9222
take_screenshot() # only sees music-app
# Session B: Claude Code in ~/projects/todo-app/
# MCP auto-detects "todo-app" → port 9223
take_screenshot() # only sees todo-appNo cross-talk. No manual setup. Each session knows its app.
Check your assigned port
Use list_projects() from any session to see all registered projects and their ports:
list_projects()
# -> Registered projects (2):
# - music-app: port 9222 [connected (1 window(s))]
# - todo-app: port 9223 [not connected]Registry persistence
Port assignments are saved to ~/.debug-electron-mcp.json and shared across all sessions:
{
"portRange": [9222, 9322],
"projects": {
"music-app": { "port": 9222 },
"todo-app": { "port": 9223 }
}
}Manual project management
You can also manage projects explicitly with the built-in tools:
register_project({ projectName: "my-app" }) # register with auto-assigned port
register_project({ projectName: "my-app", port: 9250 }) # register with specific port
unregister_project({ projectName: "old-app" }) # free a port
list_projects() # see all projectsOverride with projectName
If you need to target a different project from the current session, pass projectName explicitly:
take_screenshot({ projectName: "other-app" })Enabling Remote Debugging (Required)
Your Electron app must be running with remote debugging enabled on the port assigned to your project.
Use list_projects() to check your assigned port, then start your app with that port.
Method 1: Command Line Flag (Easiest)
electron . --remote-debugging-port=9222Method 2: package.json (Persistent)
"scripts": {
"start": "electron .",
"dev:debug": "electron . --remote-debugging-port=9222"
}Then run npm run dev:debug.
Method 3: Programmatic (Best for Codebase)
const { app } = require('electron');
if (process.env.NODE_ENV === 'development' || process.argv.includes('--dev')) {
const port = process.env.DEBUG_PORT || '9222';
app.commandLine.appendSwitch('remote-debugging-port', port);
console.log(`Remote debugging enabled on port ${port}`);
}Verification
Open http://localhost:<port>/json in your browser. If you see a JSON list of targets, you are ready.
Usage Guide
Core Workflow
- Inspect: Use
get_page_structureto see what buttons and inputs are available. - Target: Identify the element you want (e.g., a button with text "Login").
- Act: Send a command like
click_by_textorfill_input. - Verify: Use
take_screenshotorget_titleto confirm the action succeeded.
Tool Reference
| Tool | Description |
|------|-------------|
| get_electron_window_info | Lists all open windows, their titles, and connection IDs. |
| list_electron_windows | Lists all available window targets across applications. |
| take_screenshot | Captures a screenshot of a specific window or the active one. |
| read_electron_logs | Streams console logs from the app (great for debugging errors). |
| send_command_to_electron | The main tool. Executes specific actions inside the app. |
Project Management Tools
| Tool | Description |
|------|-------------|
| register_project | Register a project name, auto-assigns a debugging port. |
| unregister_project | Remove a project, free its port. |
| list_projects | Show all registered projects with ports and connection status. |
Interaction Commands
Use these inside send_command_to_electron:
Clicking & Selection
| Command | Description |
|---------|-------------|
| click_by_text | Best for buttons/links. Usage: {"text": "Submit"} |
| click_by_selector | Precise control. Usage: {"selector": ".submit-btn"} |
| click_button | Legacy click command. Usage: {"selector": "#btn"} |
| select_option | For dropdowns. Usage: {"text": "Category", "value": "Books"} |
| hover | Hover over elements. Usage: {"selector": ".tooltip-trigger"} |
| drag | Drag and drop. Usage: {"startSelector": "#item", "endSelector": "#cart"} |
Input & Forms
| Command | Description |
|---------|-------------|
| fill_input | Smart filling. Usage: {"placeholder": "Username", "value": "admin"} |
| type | Simulates real typing. Usage: {"text": "Hello World", "slowly": true} |
| verify_form_state | Checks validity of all forms. |
| send_keyboard_shortcut | Send key combinations. Usage: {"text": "Ctrl+S"} |
Observation
| Command | Description |
|---------|-------------|
| get_page_structure | Returns a simplified JSON map of the UI. |
| find_elements | Detailed list of all interactive elements. |
| is_visible | Checks visibility. Usage: {"selector": "#error-modal"} |
| get_attribute | Get attributes. Usage: {"selector": "img", "attribute": "src"} |
| count | Count matching elements. Usage: {"selector": "li.item"} |
| debug_elements | Get detailed debug info for buttons and inputs. |
| get_title | Get the document title. |
| get_url | Get the current URL. |
| get_body_text | Get the visible body text. |
Advanced
| Command | Description |
|---------|-------------|
| wait | Wait for element/time. Usage: {"duration": 1000} or {"text": "Loading"} |
| navigate_to_hash | Navigate to hash routes. Usage: {"text": "settings"} |
| eval | Execute custom JavaScript. Usage: {"code": "alert('Hello')"} |
| console_log | Write to app console. Usage: {"message": "Hello"} |
Advanced: HTTP Server Mode
For advanced use cases where you want a single long-lived server that multiple AI clients share, you can run the server in HTTP mode.
Note: Most users don't need this. The standard setup auto-detects projects and handles multiple apps with zero extra config.
Step 1: Start the server:
npx @debugelectron/debug-electron-mcp@latest serve
npx @debugelectron/debug-electron-mcp@latest serve --port 4000Step 2: Point your MCP config to the URL:
{
"mcpServers": {
"debug-electron-mcp": {
"url": "http://localhost:3100/mcp"
}
}
}Step 3: Pass projectName in tool calls (no auto-detect in HTTP mode):
send_command_to_electron({ projectName: "music-app", command: "get_title" })Health check: http://localhost:3100/health
Development
Prerequisites
- Node.js 18+
- npm or pnpm
Setup
git clone https://github.com/TheDarkSkyXD/debug-electron-mcp.git
cd debug-electron-mcp
npm install
npm run buildRunning Locally
npm run dev # stdio mode
npx tsx src/index.ts --project my-app # explicit project scope
npx tsx src/index.ts serve # HTTP modeTesting
npm test # unit tests
npm run test:react # integration testsTroubleshooting
"Target not found" / "No running Electron application"
- Check your assigned port with
list_projects(). - Start your Electron app with
--remote-debugging-port=<port>. - Verify: open
http://localhost:<port>/jsonin your browser.
"Project 'xyz' is not registered"
- This shouldn't happen with auto-detect. If it does, run
register_project({ projectName: "xyz" }). - Check
list_projects()to see registered projects.
Wrong project detected
- The MCP uses your
package.jsonname, or the folder name if no package.json exists. - To override, use
--projectflag:"args": ["-y", "@debugelectron/debug-electron-mcp@latest", "--project", "correct-name"]
"No free ports available"
- Default range is 9222-9322 (100 ports).
- Free unused ports:
unregister_project({ projectName: "old-app" }).
"Selector is empty" error
- Wrong:
{"command": "click_by_selector", "args": ".btn"} - Correct:
{"command": "click_by_selector", "args": {"selector": ".btn"}}
License
MIT License. See LICENSE for details.
Credits
Forked and maintained by Antigravity, originally based on work by halilural.
