6 tools, 85% of debugging scenarios. Best signal-to-noise ratio for AI-assisted browser debugging.
A minimal MCP Server focused on browser debugging essentials. 6 tools vs 26+ (chrome-devtools-mcp), giving your AI assistant the best signal-to-noise ratio for debugging.
| Comparison | chrome-devtools-mcp | simple-console-mcp |
|---|---|---|
| Tools | 26+ | 6 |
| Context Cost | ~5000 tokens | ~350 tokens |
| Focus | Full-featured | Console + Network + Screenshot + JS |
This project started with a simple question: "I just want to debug my web app. Why do I need 26+ tools?"
chrome-devtools-mcp is powerful, but more tools means more cognitive load for the AI — leading to slower responses and wrong tool choices. For everyday debugging, you need a high signal-to-noise ratio, not a Swiss army knife.
So I built this "Minimum Viable MCP" with the 6 tools that cover ~85% of debugging scenarios:
list_targets— List browser tabsget_console_logs— Read Console outputget_network_logs— Monitor HTTP requests/responsesnavigate— Navigate or reloadexecute_js— Execute JavaScript in page contexttake_screenshot— Capture page screenshot for visual debugging
The core goal is best signal-to-noise ratio — maximum debugging power with minimum tool count. Every tool earns its place by covering a capability that execute_js cannot replace.
Claude Code (one-liner):
claude mcp add simple-console -- npx -y simple-console-mcpClaude Desktop or other MCP clients (Cursor / Windsurf / Cline):
{
"mcpServers": {
"simple-console": {
"command": "npx",
"args": ["-y", "simple-console-mcp"]
}
}
}Claude Code:
claude mcp add simple-console -- npx -y github:tznthou/simple-console-mcpgit clone https://github.com/tznthou/simple-console-mcp.git
cd simple-console-mcp && npm installclaude mcp add simple-console -- node /path/to/simple-console-mcp/src/index.jsNo manual setup required! The MCP automatically detects whether Chrome has CDP enabled:
- If CDP is already enabled → connects directly
- If not → auto-launches a new Chrome with debug mode using isolated profile
Just install the MCP, and tell Claude "help me debug" — it handles everything automatically.
Note (v1.4.0+): If you already have a regular Chrome open, the MCP will show a clear error message asking you to close it first. This prevents conflicts between regular and debug Chrome instances.
If auto-launch fails, you can start Chrome manually:
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222
# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222List all available browser targets (pages, Service Workers, etc.).
| Parameter | Type | Default | Description |
|---|---|---|---|
port |
number | 9222 | Chrome CDP port |
Available targets:
[0] page: http://localhost:3000
[1] service_worker: chrome-extension://xxx/background.js
[2] page: chrome-extension://xxx/popup.html
Get Console output from a specific target. Starts monitoring on first call.
| Parameter | Type | Default | Description |
|---|---|---|---|
targetIndex |
number | 0 | Target index from list_targets |
maxLines |
number | 50 | Maximum lines to return |
filter |
string | "all" | Filter type: all / error / warn / log / info / debug |
port |
number | 9222 | Chrome CDP port |
=== Console Logs for http://localhost:3000 ===
[12:34:56] ERROR: Uncaught TypeError: Cannot read property 'x' of undefined
[12:34:57] WARN: Deprecation warning...
(showing 2 of 50 total logs, filter: all)
Get HTTP request/response logs from a specific target. Starts monitoring on first call.
| Parameter | Type | Default | Description |
|---|---|---|---|
targetIndex |
number | 0 | Target index from list_targets |
maxLines |
number | 50 | Maximum entries to return |
filter |
string | "all" | Filter type: all / failed / xhr / fetch / document / stylesheet / script / image |
port |
number | 9222 | Chrome CDP port |
=== Network Logs for http://localhost:3000 ===
[GET] 200 http://localhost:3000/ (120ms, 4.2KB)
[GET] 200 http://localhost:3000/api/user (85ms, 1.1KB)
[POST] 500 http://localhost:3000/api/save (230ms)
[GET] FAILED http://localhost:3000/missing.js (15ms) Error: net::ERR_FILE_NOT_FOUND
(showing 4 of 4 total, filter: all)
Navigate to a URL or reload the page.
| Parameter | Type | Default | Description |
|---|---|---|---|
url |
string | - | Target URL or "reload" |
targetIndex |
number | 0 | Target index |
port |
number | 9222 | Chrome CDP port |
Navigated to: http://localhost:3000/login
Page title: "Login"
(Console logs cleared)
Execute JavaScript code in the page context. Useful for clicking buttons, filling forms, reading DOM, or calling page functions.
| Parameter | Type | Default | Description |
|---|---|---|---|
code |
string | - | JavaScript code to execute (max 10,000 chars) |
targetIndex |
number | 0 | Target index |
port |
number | 9222 | Chrome CDP port |
Safety measures:
- Code length limit: 10,000 characters
- Execution timeout: 5 seconds
- Result size limit: 50,000 characters
Examples:
// Click a button
document.querySelector('button#submit').click()
// Read page title
document.title
// Call page function
myApp.doSomething()
// Fill form input
document.getElementById('email').value = 'test@example.com'
// Get element count
document.querySelectorAll('.item').length=== JavaScript Executed ===
Code: document.title
Result:
"My Application"
Capture a screenshot of the current page. Returns a PNG image (auto-falls back to JPEG if too large). Useful for visual debugging of layout, CSS, or UI state.
| Parameter | Type | Default | Description |
|---|---|---|---|
targetIndex |
number | 0 | Target index from list_targets |
fullPage |
boolean | false | Capture full scrollable page (true) or viewport only (false) |
port |
number | 9222 | Chrome CDP port |
Safety measures:
- Viewport clamped to 1280×800 max
- PNG → JPEG fallback if image exceeds 500KB
fullPage: falseby default to prevent oversized captures
graph TB
subgraph Client["AI Client"]
CLAUDE["Claude Desktop<br/>or Claude Code"]
end
subgraph MCP["simple-console-mcp"]
SERVER["MCP Server<br/>StdioTransport"]
TOOLS["6 Tools<br/>list_targets | get_console_logs | get_network_logs<br/>navigate | execute_js | take_screenshot"]
CACHE["Cache<br/>Console Logs + Network Requests"]
end
subgraph Browser["Chrome Browser"]
CDP["CDP Port 9222<br/>--remote-debugging-port"]
PAGES["Browser Targets<br/>Pages | Service Workers"]
CONSOLE["Console Events<br/>log | error | warn"]
end
CLAUDE --> |"MCP Protocol"| SERVER
SERVER --> TOOLS
TOOLS --> |"puppeteer-core"| CDP
CDP --> PAGES
PAGES --> |"console event"| CACHE
CACHE --> |"formatted logs"| TOOLS
Claude calls get_console_logs → MCP returns accumulated logs → Claude processes
↑ |
└──────────────── Claude must call again ────────────────┘
Behavior:
- On first
get_console_logscall, MCP starts monitoring that target - Console events are continuously collected in memory (max 500 entries)
- Claude does NOT receive automatic notifications — must call
get_console_logsagain to see new logs
Why Pull-based? MCP protocol is request-response based and doesn't support push notifications. The server cannot proactively tell Claude "there's a new error" — Claude must actively ask.
This MCP supports monitoring Console output from Chrome Extensions:
[0] page: http://localhost:3000 ← Regular webpage
[1] service_worker: chrome-extension://abc/background.js ← Extension background script
[2] page: chrome-extension://abc/popup.html ← Extension popup
Use different targetIndex values to monitor each target separately.
| Technology | Purpose |
|---|---|
| Node.js 18+ | Runtime |
| ES Modules | Module system |
| @modelcontextprotocol/sdk | MCP protocol implementation |
| puppeteer-core | Chrome CDP connection (no bundled Chromium) |
| zod | Parameter validation |
simple-console-mcp/
├── src/
│ └── index.js # MCP Server (~770 lines, security hardened)
├── bin/
│ └── start-chrome.sh # Chrome startup helper
├── .github/
│ └── workflows/
│ └── release.yml # Tag → GitHub Release + npm publish
├── test/ # Manual test pages (HTML)
├── package.json
├── README.md # English docs (this file)
├── README_ZH.md # Chinese docs
├── CHANGELOG.md # Full changelog
└── LICENSE # Apache-2.0
| Item | Requirement |
|---|---|
| Node.js | 18+ |
| Chrome | Any version with --remote-debugging-port enabled |
| OS | macOS / Linux / Windows |
- Chrome must have CDP enabled: Chrome without
--remote-debugging-portcannot be connected - One Chrome at a time: If multiple Chrome instances exist, MCP connects to the first one
- Log cache limit: Each target keeps at most 500 console logs and 200 network entries, older ones are automatically removed
- Navigation clears cache: Calling navigate clears both console logs and network request cache
New Features:
- ✨
get_network_logstool: Monitor HTTP requests/responses- Pull-based monitoring (same pattern as console logs)
- Shows method, URL, status, duration, size
- Filter by: all / failed / xhr / fetch / document / stylesheet / script / image
- 200 entries cache per target
- ✨
take_screenshottool: Capture page screenshots- Returns PNG image via MCP image content type
- Auto-fallback to JPEG if PNG exceeds 500KB
- Viewport clamped to 1280×800, deviceScaleFactor: 1
- Optional
fullPagemode
Improvements:
- 🔧 Extracted
getTargetPage()shared helper (reduces code duplication across tools) - 🔧 Navigation now clears both console and network caches
- 🔧 Cleanup handler now removes network event listeners
- 📦 Repositioned from "97% lighter" to "6 tools vs 26+ with best signal-to-noise ratio"
New Features:
- ✨
execute_jstool: Execute JavaScript in page context- Click buttons, fill forms, read DOM, call page functions
- Safety measures: 5s timeout, 10K code limit, 50K result limit
- ✨ Simplified Chrome launch logic:
- Directly launches debug Chrome with isolated profile (
/tmp/chrome-cdp-9222) - Clear error message when regular Chrome conflicts with debug Chrome
- Directly launches debug Chrome with isolated profile (
Improvements:
- 📦 Code grew from ~460 to ~550 lines (+20%)
- 🔧 Removed automatic Chrome kill logic (user must close regular Chrome manually)
- 📝 Better error messages explaining Chrome conflict resolution
Full changelog: CHANGELOG.md
This project is licensed under the Apache License 2.0.
- GitHub: @tznthou