Stealth Browser MCP Server
by newbeb
import { FastMCP } from 'fastmcp';
import { z } from 'zod';
import { chromium } from 'playwright-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
// Add the stealth plugin to playwright
chromium.use(StealthPlugin());
// Create a new FastMCP server
const server = new FastMCP({
name: 'stealth-browser-mcp',
version: '1.0.0'
});
// Add the screenshot tool
server.addTool({
name: 'screenshot',
description: 'Navigate to a URL and take a screenshot of the webpage',
parameters: z.object({
url: z.string().describe('URL to navigate to'),
fullPage: z.boolean().default(true).describe('Whether to take a screenshot of the full page'),
selector: z.string().optional().describe('CSS selector to screenshot a specific element'),
headless: z.boolean().default(true).describe('Whether to run browser in headless mode (default) or visible mode')
}),
execute: async ({ url, fullPage = true, selector, headless = true }) => {
// Launch browser with stealth mode
const browser = await chromium.launch({ headless });
try {
const page = await browser.newPage();
// Navigate to the URL
console.error(`Navigating to ${url}...`);
await page.goto(url, { waitUntil: 'networkidle' });
// Take the screenshot
const screenshotOptions = { fullPage };
let screenshot;
if (selector) {
// Screenshot specific element if selector is provided
const element = await page.$(selector);
if (element) {
screenshot = await element.screenshot();
} else {
throw new Error(`Element with selector '${selector}' not found`);
}
} else {
// Screenshot entire page
screenshot = await page.screenshot(screenshotOptions);
}
// Return screenshot as base64 data with content type
return {
content: [
{
type: 'image',
data: screenshot.toString('base64'),
mimeType: 'image/png'
}
]
};
} finally {
await browser.close();
}
}
});
// Start the server with STDIO transport
server.start({ transportType: 'stdio' }).then(() => {
console.error('MCP server started and waiting for commands...');
}).catch(error => {
console.error('Failed to start MCP server:', error);
});