Videos
» npm install @modelcontextprotocol/server-puppeteer
» npm install @imazhar101/mcp-puppeteer-server
Yes, technically, but it is not something that is officially supported by either puppeteer or VS Code.
See this thread for some recent context : https://twitter.com/jsoverson/status/1111281688439672832
This is a test script I made in order to experiment with the possibility.
const childProcess = require('child_process');
const puppeteer = require('puppeteer');
const request = require('request-promise-native');
var delay = require('timeout-as-promise');
function spawn(port) {
return childProcess.spawn(
'/Applications/Visual Studio Code.app/Contents/MacOS/Electron',
[
`--remote-debugging-port=${port || 9229}`,
'--user-data-dir=/tmp/foo', // arbitrary not-mine datadir to get the welcome screen
'--enable-logging',
],
{
detached: true,
env: process.env,
stido: ['pipe', 'pipe', 'pipe']
}
);
}
async function main(){
const port = 29378;
const proc = spawn(port);
await delay(2000);
const resp = await request(`http://127.0.0.1:${port}/json/list`);
const devToolsPages = JSON.parse(resp);
const endpoint = devToolsPages.find(p => !p.title.match(/^sharedProcess/));
const browser = await puppeteer.connect({
browserWSEndpoint: endpoint.webSocketDebuggerUrl,
defaultViewport: null, // used to bypass Chrome viewport issue, doesn't work w/ VS code.
slowMo: 50
})
await delay(1000);
const page = (await browser.pages())[0];
await page.click('[href="command:workbench.action.files.newUntitledFile"]');
await page.type('.monaco-editor', 'Woo! I am automating Visual Studio Code with puppeteer!\n');
await page.type('.monaco-editor', 'This would be a super cool way of generating foolproof demos.');
setTimeout(() => proc.kill(), 1000);
}
main();
I'm getting the following error when I'm using playwright . does it only works with a puppeteer ? pls help . Error while handling browser contexts: Error: browserContext.newPage: Protocol error
(Target.createTarget): Not supported
at main (xyz.js:68:42) {name: 'Error', stack: 'browserContext.newPage: Protocol error (Target.createTarget): Not supported', message: 'browserContext.newPage: Protocol error (Target.createTarget): Not supported'}
openAndConnectToVsCodeUsingCdp.ts:78
arg1 =
Error: browserContext.newPage: Protocol error (Target.createTarget): Not supported
at main (xyz.js:68:42) {name: 'Error', stack: 'browserContext.newPage: Protocol error (Target.createTarget): Not supported', message: 'browserContext.newPage: Protocol error (Target.createTarget): Not supported'}
main @ xyz.ts:78:13
await
processTicksAndRejections @ internal/process/task_queues:105:5
await
processTicksAndRejections @ internal/process/task_queues:105:5
await
<anonymous> @ xyz.ts:100
<anonymous> @ internal/modules/cjs/loader:1723:14
<anonymous> @ internal/modules/cjs/loader:1888:10
<anonymous> @ internal/modules/cjs/loader:1458:32
<anonymous> @ internal/modules/cjs/loader:1275:12
traceSync @ diagnostics_channel:322:14
wrapModuleLoad @ internal/modules/cjs/loader:234:24
executeUserEntryPoint @ internal/modules/run_main:151:5
<anonymous> @ internal/main/run_main_module:33:47
Error: browserContext.newPage: Protocol error (Target.createTarget): Not supported
at main (xyz.js:68:42) {name: 'Error', stack: 'browserContext.newPage: Protocol error (Target.createTarget): Not supported', message: 'browserContext.newPage: Protocol error (Target.createTarget): Not supported'}
import { chromium, ChromiumBrowser } from 'playwright';
import { spawn } from 'child_process';
import fetch from 'node-fetch';
import { delay } from '../../utils/delay';
function spawnVSCode(port: number) {
return spawn(
'/Applications/Visual Studio Code.app/Contents/MacOS/Electron',
[
`--remote-debugging-port=${port}`,
'--user-data-dir=/tmp/foo', // Use temporary data dir to get welcome screen
'--enable-logging',
],
{
detached: true,
env: process.env,
stdio: ['pipe', 'pipe', 'pipe']
}
);
}
async function main() {
const port = 29378;
const proc = spawnVSCode(port);
// Wait for VSCode to start
await delay(2000);
// Get the WebSocket endpoint
const response = await fetch(`http://127.0.0.1:${port}/json/list`);
const endpoints = await response.json() as any[];
const endpoint = endpoints.find(p => !p.title.match(/^sharedProcess/));
if (!endpoint) {
throw new Error('Could not find VSCode debug endpoint');
}
// Connect to the browser using CDP
const browser = await chromium.connectOverCDP({
endpointURL: endpoint.webSocketDebuggerUrl,
slowMo: 50
}) as ChromiumBrowser;
let page;
try {
// Get all browser contexts
const contexts = browser.contexts();
console.log(`Found ${contexts.length} browser contexts`);
if (contexts.length === 0) {
// If no contexts exist, create a new one
console.log('No contexts found, creating new context');
const newContext = await browser.newContext();
page = await newContext.newPage();
} else {
// Try to get page from existing contexts
for (const context of contexts) {
try {
const pages = context.pages();
if (pages.length > 0) {
page = pages[0];
console.log('Found existing page');
break;
}
} catch (e) {
console.log('Error accessing pages in context:', e);
continue;
}
}
// If still no page found, create new one in first context
if (!page) {
console.log('No pages found in existing contexts, creating new page');
page = await contexts[0].newPage();
}
}
} catch (e) {
console.error('Error while handling browser contexts:', e);
throw e;
}
if (!page) {
throw new Error('Failed to get or create a page');
}
// Click new file button
await page.click('[href="command:workbench.action.files.newUntitledFile"]');
// Type some text
await page.type('.monaco-editor', 'Hello! I am automating Visual Studio Code with Playwright!\n');
await page.type('.monaco-editor', 'This is a super cool way of generating foolproof demos.');
// Clean up after 1 second
setTimeout(() => {
proc.kill();
process.exit(0);
}, 1000);
}
main().catch(console.error);
I couldn't find one, so I wrote one. Surprisingly simple!
https://medium.com/surescale/tutorial-use-claude-desktop-mcp-puppeteer-to-automatically-extract-data-from-the-web-b5692dbdcd6e
I'm still getting my head around the onslaught of tools and features flying at us and I'm confused about enabling Roo to use the browser vs. installing Puppeteer as an MCP server.
Any thoughts of one over the other or have both?
After much trial and error I finally got functioning MCP servers in Claude Code albeit with slightly less will to live.
What are MCP Servers?
They're digital prosthetics that give Claude arms and legs to crawl around your computer with. Less poetically: extensions that let it do stuff beyond generating code you'll never actually use.
The Tools (★ = Requires API Key)
Sequential Thinking: Helps Claude solve problems step‑by‑step
Filesystem: Lets Claude rummage through the folders you allow
Playwright: Modern multi‑browser automation
Puppeteer: Chrome‑only (deprecated)
Web Fetching: Grabs content from websites
Browser Tools (Chrome DevTools Integration): Capture and analyze browser data through a Chrome extension
★ Brave Search: Web searching capabilities
★ Firecrawl: Advanced web scraping
🏃♂️ One‑Command Installation (The "I Don't Have Time For This" Version)
Copy everything in the block, paste into a macOS/Linux terminal, and hit ↵.
bash <<'EOF'
echo "🔧 Installing Claude MCP servers (latest versions)…"
# Sequential Thinking — Claude's chain‑of‑thought engine
claude mcp add sequential-thinking -s user \
-- npx -y @modelcontextprotocol/server-sequential-thinking || true
# Filesystem — give Claude access to local folders
claude mcp add filesystem -s user \
-- npx -y @modelcontextprotocol/server-filesystem \
~/Documents ~/Desktop ~/Downloads ~/Projects || true
# Playwright — modern multi‑browser automation
claude mcp add playwright -s user \
-- npx -y @playwright/mcp-server || true
# Puppeteer — Chrome‑only (deprecated but still works)
claude mcp add puppeteer -s user \
-- npx -y @modelcontextprotocol/server-puppeteer || true
# Fetch — simple HTTP GET/POST
claude mcp add fetch -s user \
-- npx -y @kazuph/mcp-fetch || true
# Browser‑Tools — DevTools logs, screenshots, etc.
claude mcp add browser-tools -s user \
-- npx -y @agentdeskai/browser-tools-mcp || true
echo "--------------------------------------------------"
echo "✅ MCP registration finished."
echo ""
echo "🔴 To enable Browser‑Tools, run this in a *second* terminal and leave it open:"
echo " npx -y @agentdeskai/browser-tools-server"
echo "--------------------------------------------------"
claude mcp list
EOFSave this as install-mcp-servers.sh, make it executable (chmod +x install-mcp-servers.sh), and run it while questioning your life choices.
Windows users: you'll need a .bat file instead. Good luck with that!
# Essential MCP Servers (Individual Installation)
Sequential Thinking
claude mcp add sequential-thinking -s user \ -- npx -y @modelcontextprotocol/server-sequential-thinking
Lets Claude actually think through problems instead of making things up with confidence.
Filesystem Access (update paths as desired)
claude mcp add filesystem -s user \
-- npx -y @modelcontextprotocol/server-filesystem \
~/Documents ~/Desktop ~/Downloads ~/ProjectsGive Claude access to your files.
Playwright (multi‑browser automation)
claude mcp add playwright -s user \ -- npx -y @playwright/mcp
Puppeteer (deprecated but still works)
claude mcp add puppeteer -s user \ -- npx -y @modelcontextprotocol/server-puppeteer
Watch in existential dread as your browser operates itself.
Web Fetching
claude mcp add fetch -s user \ -- npx -y @kazuph/mcp-fetch
Grabs content from websites.
Browser Tools
Gives Claude access to your browser's console logs, network traffic, and the ability to run performance/accessibility audits.
Step 1: Install the Chrome extension – download from the releases page and load it via Chrome’s extension manager. Step 2: Start the middleware server (keep this terminal open)
npx -y @agentdeskai/[email protected]
Step 3: Add the MCP server to Claude Code (in a separate terminal)
claude mcp add browser-tools -s user \ -- npx -y @agentdeskai/[email protected]
Step 4: Open Chrome DevTools (F12) and find the BrowserTools tab.
★ Brave Search (Requires API Key)
# Replace YOUR_API_KEY_HERE with your actual Brave Search API key
claude mcp add brave-search -s user \
-- env BRAVE_API_KEY=YOUR_API_KEY_HERE \
npx -y @modelcontextprotocol/server-brave-searchLet Claude search the web and bring back results.
★ Firecrawl (Advanced Web Scraping — Requires API Key)
# Replace fc-YOUR_API_KEY with your actual Firecrawl API key
claude mcp add firecrawl -s user \
-- env FIRECRAWL_API_KEY=fc-YOUR_API_KEY \
npx -y firecrawl-mcpFor when you need to scrape websites with industrial‑grade efficiency and minimal respect for robots.txt.
# The -s user vs -s local Thing
-s user: Makes these tools available globally-s local: Only works in your current directory
# Troubleshooting
Windows issues: prepend
cmd /cbefore npx commandsTimeout errors:
MCP_TIMEOUT=10000 claudeConnection problems: Type
/mcpin Claude Code to see which servers are nappingFilesystem access: Double‑check your paths
That's it. Save yourself the four hours of my life I'll never get back.
PS – Yes, this was written mostly with the help of Claude.
EDIT: Apparently there were some stupid Reddit formatting issues. It converted the "@" to "u/", I'm such a noob, sorry! I updated the script to include playwright which is a pretty good alternative to puppeteer. Thanks all for pointing out my numerous flaws.