
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
@tontoko/fast-playwright-mcp
Advanced tools
This MCP server is a fork of the Microsoft one. https://github.com/microsoft/playwright-mcp
A Model Context Protocol (MCP) server that provides browser automation capabilities using Playwright. This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.
expectation
parameter to control response content:
includeCode: false
- Suppress Playwright code generation to reduce tokensincludeSnapshot: false
- Skip page snapshot for minimal responses (70-80% token reduction)includeConsole: false
- Exclude console messagesincludeTabs: false
- Hide tab informationimageOptions
:
format: 'jpeg'
- Use JPEG instead of PNGquality: 1-100
- Compress images (e.g., 50 for 50% quality)maxWidth: number
- Resize images to max widthbrowser_batch_execute
for multiple operations:
continueOnError
and stopOnFirstError
optionssnapshotOptions
:
selector: string
- Capture only specific page sections (recommended over maxLength)format: "aria"
- Accessibility tree format for LLM processingdiffOptions
:
enabled: true
- Show only what changed from previous state (massive token saver)format: "minimal"
- Ultra-compact diff outputbrowser_find_elements
- Find elements using multiple search criteria (text, role, attributes)browser_diagnose
- Comprehensive page analysis with performance metrics and troubleshootingFirst, install the Playwright MCP server with your client.
Standard config works in most of the tools:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@tontoko/fast-playwright-mcp@latest"
]
}
}
}
Use the Claude Code CLI to add the Playwright MCP server:
claude mcp add fast-playwright npx @tontoko/fast-playwright-mcp@latest
Follow the MCP install guide, use the standard config above.
Go to Cursor Settings
-> MCP
-> Add new MCP Server
. Name to your liking, use command
type with the command npx @tontoko/fast-playwright-mcp@latest
. You can also verify config or add command like arguments via clicking Edit
.
Follow the MCP install guide, use the standard config above.
Go to Advanced settings
-> Extensions
-> Add custom extension
. Name to your liking, use type STDIO
, and set the command
to npx @tontoko/fast-playwright-mcp
. Click "Add Extension".
Go to Program
in the right sidebar -> Install
-> Edit mcp.json
. Use the standard config above.
Follow the MCP Servers documentation. For example in ~/.config/opencode/opencode.json
:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"playwright": {
"type": "local",
"command": [
"npx",
"@tontoko/fast-playwright-mcp"
],
"enabled": true
}
}
}
Open Qodo Gen chat panel in VSCode or IntelliJ → Connect more tools → + Add new MCP → Paste the standard config above.
Click Save
.
Follow the MCP install guide, use the standard config above. You can also install the Playwright MCP server using the VS Code CLI:
# For VS Code
code --add-mcp '{"name":"fast-playwright","command":"npx","args":["@tontoko/fast-playwright-mcp@latest"]}'
After installation, the Playwright MCP server will be available for use with your GitHub Copilot agent in VS Code.
Follow Windsurf MCP documentation. Use the standard config above.
Playwright MCP server supports following arguments. They can be provided in the JSON configuration above, as a part of the "args"
list:
> npx @tontoko/fast-playwright-mcp@latest --help
--allowed-origins <origins> semicolon-separated list of origins to allow the
browser to request. Default is to allow all.
--blocked-origins <origins> semicolon-separated list of origins to block the
browser from requesting. Blocklist is evaluated
before allowlist. If used without the allowlist,
requests not matching the blocklist are still
allowed.
--block-service-workers block service workers
--browser <browser> browser or chrome channel to use, possible
values: chrome, firefox, webkit, msedge.
--caps <caps> comma-separated list of additional capabilities
to enable, possible values: vision, pdf.
--cdp-endpoint <endpoint> CDP endpoint to connect to.
--config <path> path to the configuration file.
--device <device> device to emulate, for example: "iPhone 15"
--executable-path <path> path to the browser executable.
--extension Connect to a running browser instance
(Edge/Chrome only). Requires the "Playwright MCP
Bridge" browser extension to be installed.
--headless run browser in headless mode, headed by default
--host <host> host to bind server to. Default is localhost. Use
0.0.0.0 to bind to all interfaces.
--ignore-https-errors ignore https errors
--isolated keep the browser profile in memory, do not save
it to disk.
--image-responses <mode> whether to send image responses to the client.
Can be "allow" or "omit", Defaults to "allow".
--no-sandbox disable the sandbox for all process types that
are normally sandboxed.
--output-dir <path> path to the directory for output files.
--port <port> port to listen on for SSE transport.
--proxy-bypass <bypass> comma-separated domains to bypass proxy, for
example ".com,chromium.org,.domain.com"
--proxy-server <proxy> specify proxy server, for example
"http://myproxy:3128" or "socks5://myproxy:8080"
--save-session Whether to save the Playwright MCP session into
the output directory.
--save-trace Whether to save the Playwright Trace of the
session into the output directory.
--storage-state <path> path to the storage state file for isolated
sessions.
--user-agent <ua string> specify user agent string
--user-data-dir <path> path to the user data directory. If not
specified, a temporary directory will be created.
--viewport-size <size> specify browser viewport size in pixels, for
example "1280, 720"
You can run Playwright MCP with persistent profile like a regular browser (default), in isolated contexts for testing sessions, or connect to your existing browser using the browser extension.
Persistent profile
All the logged in information will be stored in the persistent profile, you can delete it between sessions if you'd like to clear the offline state.
Persistent profile is located at the following locations and you can override it with the --user-data-dir
argument.
# Windows
%USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-profile
# macOS
- ~/Library/Caches/ms-playwright/mcp-{channel}-profile
# Linux
- ~/.cache/ms-playwright/mcp-{channel}-profile
Isolated
In the isolated mode, each session is started in the isolated profile. Every time you ask MCP to close the browser,
the session is closed and all the storage state for this session is lost. You can provide initial storage state
to the browser via the config's contextOptions
or via the --storage-state
argument. Learn more about the storage
state here.
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@tontoko/fast-playwright-mcp@latest",
"--isolated",
"--storage-state={path/to/storage.json}"
]
}
}
}
Browser Extension
The Playwright MCP Chrome Extension allows you to connect to existing browser tabs and leverage your logged-in sessions and browser state. See extension/README.md for installation and setup instructions.
The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file
using the --config
command line option:
npx @tontoko/fast-playwright-mcp@latest --config path/to/config.json
{
// Browser configuration
browser?: {
// Browser type to use (chromium, firefox, or webkit)
browserName?: 'chromium' | 'firefox' | 'webkit';
// Keep the browser profile in memory, do not save it to disk.
isolated?: boolean;
// Path to user data directory for browser profile persistence
userDataDir?: string;
// Browser launch options (see Playwright docs)
// @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch
launchOptions?: {
channel?: string; // Browser channel (e.g. 'chrome')
headless?: boolean; // Run in headless mode
executablePath?: string; // Path to browser executable
// ... other Playwright launch options
};
// Browser context options
// @see https://playwright.dev/docs/api/class-browser#browser-new-context
contextOptions?: {
viewport?: { width: number, height: number };
// ... other Playwright context options
};
// CDP endpoint for connecting to existing browser
cdpEndpoint?: string;
// Remote Playwright server endpoint
remoteEndpoint?: string;
},
// Server configuration
server?: {
port?: number; // Port to listen on
host?: string; // Host to bind to (default: localhost)
},
// List of additional capabilities
capabilities?: Array<
'tabs' | // Tab management
'install' | // Browser installation
'pdf' | // PDF generation
'vision' | // Coordinate-based interactions
>;
// Directory for output files
outputDir?: string;
// Network configuration
network?: {
// List of origins to allow the browser to request. Default is to allow all. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
allowedOrigins?: string[];
// List of origins to block the browser to request. Origins matching both `allowedOrigins` and `blockedOrigins` will be blocked.
blockedOrigins?: string[];
};
/**
* Whether to send image responses to the client. Can be "allow" or "omit".
* Defaults to "allow".
*/
imageResponses?: 'allow' | 'omit';
}
When running headed browser on system w/o display or from worker processes of the IDEs,
run the MCP server from environment with the DISPLAY and pass the --port
flag to enable HTTP transport.
npx @tontoko/fast-playwright-mcp@latest --port 8931
And then in MCP client config, set the url
to the HTTP endpoint:
{
"mcpServers": {
"playwright": {
"url": "http://localhost:8931/mcp"
}
}
}
NOTE: The Docker implementation only supports headless chromium at the moment.
{
"mcpServers": {
"playwright": {
"command": "docker",
"args": ["run", "-i", "--rm", "--init", "--pull=always", "mcr.microsoft.com/playwright/mcp"]
}
}
}
You can build the Docker image yourself.
docker build -t mcr.microsoft.com/playwright/mcp .
import http from 'http';
import { createConnection } from '@tontoko/fast-playwright-mcp';
import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
http.createServer(async (req, res) => {
// ...
// Creates a headless Playwright MCP server with SSE transport
const connection = await createConnection({ browser: { launchOptions: { headless: true } } });
const transport = new SSEServerTransport('/messages', res);
await connection.sever.connect(transport);
// ...
});
steps
(array): Array of steps to execute in sequencestopOnFirstError
(boolean, optional): Stop entire batch on first errorglobalExpectation
(optional): Default expectation for all stepselement
(string): Human-readable element description used to obtain permission to interact with the elementref
(string): Exact target element reference from the page snapshotdoubleClick
(boolean, optional): Whether to perform a double click instead of a single clickbutton
(string, optional): Button to click, defaults to leftexpectation
(object, optional): undefinedsearchForElements
(object, optional): Search for specific elements and include them in the reportincludePerformanceMetrics
(boolean, optional): Include performance metrics in the reportincludeAccessibilityInfo
(boolean, optional): Include accessibility informationincludeTroubleshootingSuggestions
(boolean, optional): Include troubleshooting suggestionsdiagnosticLevel
(string, optional): Level of diagnostic detail: none (no diagnostics), basic (critical only), standard (default), detailed (with metrics), full (all info)useParallelAnalysis
(boolean, optional): Use Phase 2 parallel analysis for improved performance and resource monitoringuseUnifiedSystem
(boolean, optional): Use Phase 3 unified diagnostic system with enhanced error handling and monitoringconfigOverrides
(object, optional): Runtime configuration overrides for diagnostic systemincludeSystemStats
(boolean, optional): Include unified system statistics and health informationexpectation
(object, optional): undefinedstartElement
(string): Human-readable source element description used to obtain the permission to interact with the elementstartRef
(string): Exact source element reference from the page snapshotendElement
(string): Human-readable target element description used to obtain the permission to interact with the elementendRef
(string): Exact target element reference from the page snapshotexpectation
(object, optional): undefinedfunction
(string): () => { /* code / } or (element) => { / code */ } when element is providedelement
(string, optional): Human-readable element description used to obtain permission to interact with the elementref
(string, optional): Exact target element reference from the page snapshotexpectation
(object, optional): undefinedpaths
(array): The absolute paths to the files to upload. Can be a single file or multiple files.expectation
(object, optional): undefinedsearchCriteria
(object): Search criteria for finding elementsmaxResults
(number, optional): Maximum number of results to returnincludeDiagnosticInfo
(boolean, optional): Include diagnostic information about the pageuseUnifiedSystem
(boolean, optional): Use unified diagnostic system for enhanced error handlingenableEnhancedDiscovery
(boolean, optional): Enable enhanced element discovery with contextual suggestionsperformanceThreshold
(number, optional): Performance threshold in milliseconds for element discoveryexpectation
(object, optional): undefinedaccept
(boolean): Whether to accept the dialog.promptText
(string, optional): The text of the prompt in case of a prompt dialog.expectation
(object, optional): undefinedelement
(string): Human-readable element description used to obtain permission to interact with the elementref
(string): Exact target element reference from the page snapshotexpectation
(object, optional): undefinedurl
(string): The URL to navigate toexpectation
(object, optional): undefinedexpectation
(object, optional): undefinedexpectation
(object, optional): undefinedurlPatterns
(array, optional): URL patterns to include (supports regex)excludeUrlPatterns
(array, optional): URL patterns to exclude (supports regex)statusRanges
(array, optional): Status code ranges to includemethods
(array, optional): HTTP methods to filter bymaxRequests
(number, optional): Maximum number of results to return (default: 20)newestFirst
(boolean, optional): Sort order - true for newest first (default: true)key
(string): Name of the key to press or a character to generate, such as ArrowLeft
or a
expectation
(object, optional): undefinedwidth
(number): Width of the browser windowheight
(number): Height of the browser windowexpectation
(object, optional): undefinedelement
(string): Human-readable element description used to obtain permission to interact with the elementref
(string): Exact target element reference from the page snapshotvalues
(array): Array of values to select in the dropdown. This can be a single value or multiple values.expectation
(object, optional): undefinedexpectation
(object, optional): undefinedtype
(string, optional): Image format for the screenshot. Default is png.filename
(string, optional): File name to save the screenshot to. Defaults to page-{timestamp}.{png|jpeg}
if not specified.element
(string, optional): Human-readable element description used to obtain permission to screenshot the element. If not provided, the screenshot will be taken of viewport. If element is provided, ref must be provided too.ref
(string, optional): Exact target element reference from the page snapshot. If not provided, the screenshot will be taken of viewport. If ref is provided, element must be provided too.fullPage
(boolean, optional): When true, takes a screenshot of the full scrollable page, instead of the currently visible viewport. Cannot be used with element screenshots.expectation
(object, optional): undefinedelement
(string): Human-readable element description used to obtain permission to interact with the elementref
(string): Exact target element reference from the page snapshottext
(string): Text to type into the elementsubmit
(boolean, optional): Whether to submit entered text (press Enter after)slowly
(boolean, optional): Whether type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.expectation
(object, optional): undefinedtime
(number, optional): The time to wait in secondstext
(string, optional): The text to wait fortextGone
(string, optional): The text to wait for to disappearexpectation
(object, optional): undefinedindex
(number, optional): The index of the tab to close. Closes current tab if not provided.expectation
(object, optional): undefinedexpectation
(object, optional): undefinedurl
(string, optional): The URL to navigate to in the new tab. If not provided, the new tab will be blank.expectation
(object, optional): undefinedindex
(number): The index of the tab to selectexpectation
(object, optional): undefinedelement
(string): undefinedx
(number): X coordinatey
(number): Y coordinateexpectation
(object, optional): undefinedelement
(string): undefinedstartX
(number): Start X coordinatestartY
(number): Start Y coordinateendX
(number): End X coordinateendY
(number): End Y coordinateexpectation
(object, optional): undefinedelement
(string): undefinedx
(number): X coordinatey
(number): Y coordinateexpectation
(object, optional): undefinedfilename
(string, optional): File name to save the pdf to. Defaults to page-{timestamp}.pdf
if not specified.Playwright MCP server includes advanced token optimization features to reduce token usage and improve performance through response filtering and batch execution.
All browser tools support an optional expectation
parameter that controls what information is included in the response. This can significantly reduce token usage by excluding unnecessary data.
// Standard call - includes all information (snapshot, console, tabs, etc.)
{
"name": "browser_navigate",
"arguments": {
"url": "https://example.com"
}
}
// Optimized call - only includes essential information
{
"name": "browser_navigate",
"arguments": {
"url": "https://example.com",
"expectation": {
"includeSnapshot": false,
"includeConsole": false,
"includeTabs": false
}
}
}
includeSnapshot
(boolean, default: varies by tool): Include page accessibility snapshotincludeConsole
(boolean, default: varies by tool): Include browser console messagesincludeDownloads
(boolean, default: true): Include download informationincludeTabs
(boolean, default: varies by tool): Include tab informationincludeCode
(boolean, default: true): Include executed code in response{
"name": "browser_click",
"arguments": {
"element": "Login button",
"ref": "#login-btn",
"expectation": {
"includeSnapshot": true,
"snapshotOptions": {
"selector": ".dashboard",
"maxLength": 1000,
"format": "text"
}
}
}
}
{
"name": "browser_navigate",
"arguments": {
"url": "https://example.com",
"expectation": {
"includeConsole": true,
"consoleOptions": {
"levels": ["error", "warn"],
"maxMessages": 5,
"patterns": ["^Error:"],
"removeDuplicates": true
}
}
}
}
Execute multiple browser actions in a single request with optimized response handling and flexible error control.
{
"name": "browser_batch_execute",
"arguments": {
"steps": [
{
"tool": "browser_navigate",
"arguments": { "url": "https://example.com/login" }
},
{
"tool": "browser_type",
"arguments": {
"element": "username field",
"ref": "#username",
"text": "testuser"
}
},
{
"tool": "browser_type",
"arguments": {
"element": "password field",
"ref": "#password",
"text": "password"
}
},
{
"tool": "browser_click",
"arguments": { "element": "login button", "ref": "#login-btn" }
}
]
}
}
{
"name": "browser_batch_execute",
"arguments": {
"steps": [
{
"tool": "browser_navigate",
"arguments": { "url": "https://example.com" },
"expectation": { "includeSnapshot": false },
"continueOnError": true
},
{
"tool": "browser_click",
"arguments": { "element": "button", "ref": "#submit" },
"expectation": {
"includeSnapshot": true,
"snapshotOptions": { "selector": ".result-area" }
}
}
],
"stopOnFirstError": false,
"globalExpectation": {
"includeConsole": false,
"includeTabs": false
}
}
}
continueOnError
(per step): Continue batch execution even if this step failsstopOnFirstError
(global): Stop entire batch on first errorEach tool has optimized defaults based on typical usage patterns:
browser_navigate
): Include full context for verificationbrowser_click
, browser_type
): Include snapshot but minimal loggingThe Fast Server includes automatic diff detection to efficiently track changes between consecutive tool executions:
{
"name": "browser_click",
"arguments": {
"element": "Load more button",
"ref": "#load-more",
"expectation": {
"includeSnapshot": true,
"diffOptions": {
"enabled": true,
"threshold": 0.1,
"format": "unified",
"maxDiffLines": 50,
"context": 3
}
}
}
}
{
"name": "browser_type",
"arguments": {
"element": "Search input",
"ref": "#search",
"text": "playwright",
"expectation": {
"includeSnapshot": true,
"snapshotOptions": {
"selector": "#search-results"
},
"diffOptions": {
"enabled": true,
"format": "minimal"
}
}
}
}
Find alternative elements when selectors fail:
{
"name": "browser_find_elements",
"arguments": {
"searchCriteria": {
"text": "Submit",
"role": "button"
},
"maxResults": 5
}
}
Generate comprehensive page diagnostics:
{
"name": "browser_diagnose",
"arguments": {
"includePerformanceMetrics": true,
"includeAccessibilityInfo": true,
"includeTroubleshootingSuggestions": true
}
}
Debug automation failures with enhanced errors: All tools automatically provide enhanced error messages with:
The browser_network_requests
tool provides advanced filtering capabilities to reduce token usage by up to 80-95% when working with network logs.
// Filter API requests only
{
"name": "browser_network_requests",
"arguments": {
"urlPatterns": ["api/", "/graphql"]
}
}
// Exclude analytics and tracking
{
"name": "browser_network_requests",
"arguments": {
"excludeUrlPatterns": ["analytics", "tracking", "ads"]
}
}
// Success responses only
{
"name": "browser_network_requests",
"arguments": {
"statusRanges": [{ "min": 200, "max": 299 }]
}
}
// Recent errors only
{
"name": "browser_network_requests",
"arguments": {
"statusRanges": [{ "min": 400, "max": 599 }],
"maxRequests": 5,
"newestFirst": true
}
}
// Complex filtering for API debugging
{
"name": "browser_network_requests",
"arguments": {
"urlPatterns": ["/api/users", "/api/posts"],
"excludeUrlPatterns": ["/api/health"],
"methods": ["GET", "POST"],
"statusRanges": [
{ "min": 200, "max": 299 },
{ "min": 400, "max": 499 }
],
"maxRequests": 10,
"newestFirst": true
}
}
// Monitor only failed requests
{
"name": "browser_network_requests",
"arguments": {
"statusRanges": [
{ "min": 400, "max": 499 },
{ "min": 500, "max": 599 }
],
"maxRequests": 3
}
}
{
"name": "browser_network_requests",
"arguments": {
"urlPatterns": ["^/api/v[0-9]+/users$"],
"excludeUrlPatterns": ["\\.(css|js|png)$"]
}
}
Existing code continues to work without changes. To optimize:
expectation: { includeSnapshot: false }
to intermediate stepsFAQs
Fast Playwright Tools for MCP
The npm package @tontoko/fast-playwright-mcp receives a total of 44 weekly downloads. As such, @tontoko/fast-playwright-mcp popularity was classified as not popular.
We found that @tontoko/fast-playwright-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.