Compare commits

...

16 Commits

Author SHA1 Message Date
Pavel Feldman
64f65ccd10 chore: mark v0.0.48 (#1218) 2025-11-21 14:34:32 -08:00
AJ (@techfren)
3f7e2d1b45 docs: add authentication token instructions to extension README (#1207) 2025-11-21 11:28:37 -08:00
Simon Knott
e0cb424dea docs: update config file section (#1209)
Copy-paste of
7671e2b7f0/packages/playwright/src/mcp/config.d.ts (L21).
2025-11-19 17:06:43 +01:00
Joel Verhagen
86e0020b4a Update version to 0.0.47 in server.json (#1204) 2025-11-18 08:47:32 -08:00
Joel Verhagen
009aa9275b Add step for publishing to MCP Registry (#1197)
This adds a new step for the `release` event to publish to the Official
MCP Registry.

Summary of changes:
- Add `server.json` which is the MCP Server manifest
  - Used metadata from the GH MCP Registry
  - Used the name `com.microsoft/playwright-mcp`
- Add `publish-release-mcp-registry` job that runs manually
   - Install Microsoft Go for compliant Go crypto
   - Log in to Azure for Key Vault access
   - Publish to the MCP Registry in the `microsoft.com` namespace.
- Add `mcpName` to the `package.json` which the MCP Registry validates.

The publishing requires some secret variables:
- `AZURE_MCP_REGISTRY_CLIENT_ID` - service principal client ID (app ID)
with Get Key and Sign access to a Key Vault
- `AZURE_MCP_REGISTRY_TENANT_ID` - tenant ID for the service principal
(should be a production tenant)
- `AZURE_MCP_REGISTRY_SUBSCRIPTION_ID` - Azure subscription ID holding
the Key Vault
- `KV_NAME` - the Key Vault name, e.g. `mykeyvault`
- `KV_KEY_NAME` - the name of a Key in the Key Vault, needs to be ECDSA
P-384.

I can provide internal documentation for how to set up the service
principal (managed identity is easiest), vault, and key as well as
registering the key so it can be used for the `microsoft.com` namespace.

**Note:** after the new job is proven to work as expected, we can switch
it to automatically running after the `publish-release-npm` job on the
`release` event.
2025-11-17 13:43:07 -08:00
Pavel Feldman
c016643bf9 chore: mark v0.0.47 (#1198) 2025-11-14 12:23:56 -08:00
Pavel Feldman
8cc557d677 chore: mark v0.0.46 (#1188) 2025-11-07 13:41:19 -08:00
Ben Tossell
15d382b940 docs: add Factory installation instructions (#1184) 2025-11-04 08:30:14 -08:00
Pavel Feldman
e72701b21c chore: mark v0.0.45 (#1179) 2025-10-31 14:05:32 -07:00
Dmitry Gozman
8ee8445342 chore: roll to 1.57.0-alpha-1761929702000 (#1178) 2025-10-31 20:16:50 +00:00
Raduan A.
ac6e678135 docs: add codex CLI command to README (#1168) 2025-10-29 17:46:42 -07:00
Yury Semikhatsky
b945ace746 chore: mark v0.0.44 (#1165) 2025-10-24 12:33:27 -07:00
Yury Semikhatsky
b3dce4097e chore: roll 1.57.0-alpha-2025-10-24 (#1164) 2025-10-24 11:29:05 -07:00
Doan Bac Tam
67ed859c2a docs: update with Kiro IDE MCP Servers details (#1143)
Added Kiro IDE MCP Servers documentation with example configuration.
2025-10-21 18:40:09 -07:00
Pavel Feldman
7da5e7273c chore: add docker run for testing purposes (#1153) 2025-10-21 18:39:27 -07:00
dependabot[bot]
fe59d4b35f chore(deps-dev): bump vite from 5.4.20 to 5.4.21 in /extension (#1156) 2025-10-21 08:06:41 -07:00
12 changed files with 356 additions and 78 deletions

View File

@@ -147,3 +147,49 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
run: |
gh release upload ${{github.event.release.tag_name}} ./extension/playwright-mcp-extension-${{ steps.get-version.outputs.version }}.zip
publish-release-mcp-registry:
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
environment: allow-mcp-registry-publishing
permissions:
contents: read
id-token: write # Needed for GitHub OIDC authentication
steps:
- uses: actions/checkout@v5
- name: Clone MCP Registry and build publisher tool
shell: pwsh
run: |
cd ${{ runner.temp }}
# Install Microsoft Go
go run github.com/microsoft/go-infra/goinstallscript@v1.1.0
./go-install.ps1 -GitHubActionsPath
# Enable compliant crypto
$env:GOEXPERIMENT = "systemcrypto"
# Clone and build the publisher tool
git clone --branch "v1.3.7" https://github.com/modelcontextprotocol/registry
cd registry
go build -o ${{ runner.temp }}/mcp-publisher ./cmd/publisher
# show help for the tool to ensure it's working
${{ runner.temp }}/mcp-publisher --help
- name: Azure Login via OIDC
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_MCP_REGISTRY_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_MCP_REGISTRY_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_MCP_REGISTRY_SUBSCRIPTION_ID }}
- name: Publish to the MCP Registry
shell: pwsh
run: |
# log in using Key Vault
${{ runner.temp }}/mcp-publisher `
login dns azure-key-vault `
-vault "${{ secrets.KV_NAME }}" -key "${{ secrets.KV_KEY_NAME }}" `
-domain microsoft.com
# publish the server.json
${{ runner.temp }}/mcp-publisher publish ./.mcp/server.json

22
.mcp/server.json Normal file
View File

@@ -0,0 +1,22 @@
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
"name": "com.microsoft/playwright-mcp",
"title": "Playwright",
"description": "Automate web browsers using accessibility trees for testing and data extraction.",
"repository": {
"url": "https://github.com/microsoft/playwright-mcp",
"source": "github"
},
"websiteUrl": "https://github.com/microsoft/playwright-mcp",
"version": "0.0.48",
"packages": [
{
"registryType": "npm",
"identifier": "@playwright/mcp",
"version": "0.0.48",
"transport": {
"type": "stdio"
}
}
]
}

259
README.md
View File

@@ -84,7 +84,13 @@ Follow the MCP install [guide](https://modelcontextprotocol.io/quickstart/user),
<details>
<summary>Codex</summary>
Create or edit the configuration file `~/.codex/config.toml` and add:
Use the Codex CLI to add the Playwright MCP server:
```bash
codex mcp add playwright npx "@playwright/mcp@latest"
```
Alternatively, create or edit the configuration file `~/.codex/config.toml` and add:
```toml
[mcp_servers.playwright]
@@ -109,6 +115,21 @@ Go to `Cursor Settings` -> `MCP` -> `Add new MCP Server`. Name to your liking, u
</details>
<details>
<summary>Factory</summary>
Use the Factory CLI to add the Playwright MCP server:
```bash
droid mcp add playwright "npx @playwright/mcp@latest"
```
Alternatively, type `/mcp` within Factory droid to open an interactive UI for managing MCP servers.
For more information, see the [Factory MCP documentation](https://docs.factory.ai/cli/configuration/mcp).
</details>
<details>
<summary>Gemini CLI</summary>
@@ -128,6 +149,25 @@ Follow the MCP install [guide](https://github.com/google-gemini/gemini-cli/blob/
Go to `Advanced settings` -> `Extensions` -> `Add custom extension`. Name to your liking, use type `STDIO`, and set the `command` to `npx @playwright/mcp`. Click "Add Extension".
</details>
<details>
<summary>Kiro</summary>
Follow the MCP Servers [documentation](https://kiro.dev/docs/mcp/). For example in `.kiro/settings/mcp.json`:
```json
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest"
]
}
}
}
```
</details>
<details>
<summary>LM Studio</summary>
@@ -230,15 +270,21 @@ Playwright MCP server supports following arguments. They can be provided in the
server is allowed to serve from.
Defaults to the host the server is bound
to. Pass '*' to disable the host check.
--allowed-origins <origins> semicolon-separated list of origins to
allow the browser to request. Default is
to allow all.
--allowed-origins <origins> semicolon-separated list of TRUSTED
origins to allow the browser to request.
Default is to allow all.
Important: *does not* serve as a
security boundary and *does not* affect
redirects.
--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.
Important: *does not* serve as a
security boundary and *does not* affect
redirects.
--block-service-workers block service workers
--browser <browser> browser or chrome channel to use,
possible values: chrome, firefox,
@@ -267,6 +313,8 @@ Playwright MCP server supports following arguments. They can be provided in the
localhost. Use 0.0.0.0 to bind to all
interfaces.
--ignore-https-errors ignore https errors
--init-page <path...> path to TypeScript file to evaluate on
Playwright page object
--init-script <path...> path to JavaScript file to add as an
initialization script. The script will
be evaluated in every page before any of
@@ -362,6 +410,35 @@ state [here](https://playwright.dev/docs/auth).
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](extension/README.md) for installation and setup instructions.
### Initial state
There are multiple ways to provide the initial state to the browser context or a page.
For the storage state, you can either:
- Start with a user data directory using the `--user-data-dir` argument. This will persist all browser data between the sessions.
- Start with a storage state file using the `--storage-state` argument. This will load cookies and local storage from the file into an isolated browser context.
For the page state, you can use:
- `--init-page` to point to a TypeScript file that will be evaluated on the Playwright page object. This allows you to run arbitrary code to set up the page.
```ts
// init-page.ts
export default async ({ page }) => {
await page.context().grantPermissions(['geolocation']);
await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
await page.setViewportSize({ width: 1280, height: 720 });
};
```
- `--init-script` to point to a JavaScript file that will be added as an initialization script. The script will be evaluated in every page before any of the page's scripts.
This is useful for overriding browser APIs or setting up the environment.
```js
// init-script.js
window.isPlaywrightMCP = true;
```
### Configuration file
The Playwright MCP server can be configured using a JSON configuration file. You can specify the configuration file
@@ -376,72 +453,151 @@ npx @playwright/mcp@latest --config path/to/config.json
```typescript
{
// Browser configuration
/**
* The browser to use.
*/
browser?: {
// Browser type to use (chromium, firefox, or webkit)
/**
* The type of browser to use.
*/
browserName?: 'chromium' | 'firefox' | 'webkit';
// Keep the browser profile in memory, do not save it to disk.
/**
* Keep the browser profile in memory, do not save it to disk.
*/
isolated?: boolean;
// Path to user data directory for browser profile persistence
/**
* Path to a user data directory for browser profile persistence.
* Temporary directory is created by default.
*/
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
};
/**
* Launch options passed to
* @see https://playwright.dev/docs/api/class-browsertype#browser-type-launch-persistent-context
*
* This is useful for settings options like `channel`, `headless`, `executablePath`, etc.
*/
launchOptions?: playwright.LaunchOptions;
// Browser context options
// @see https://playwright.dev/docs/api/class-browser#browser-new-context
contextOptions?: {
viewport?: { width: number, height: number };
// ... other Playwright context options
};
/**
* Context options for the browser context.
*
* This is useful for settings options like `viewport`.
*/
contextOptions?: playwright.BrowserContextOptions;
// CDP endpoint for connecting to existing browser
/**
* Chrome DevTools Protocol endpoint to connect to an existing browser instance in case of Chromium family browsers.
*/
cdpEndpoint?: string;
// Remote Playwright server endpoint
/**
* CDP headers to send with the connect request.
*/
cdpHeaders?: Record<string, string>;
/**
* Remote endpoint to connect to an existing Playwright server.
*/
remoteEndpoint?: string;
/**
* Paths to TypeScript files to add as initialization scripts for Playwright page.
*/
initPage?: string[];
/**
* Paths to JavaScript files to add as initialization scripts.
* The scripts will be evaluated in every page before any of the page's scripts.
*/
initScript?: string[];
},
// Server configuration
server?: {
port?: number; // Port to listen on
host?: string; // Host to bind to (default: localhost)
/**
* The port to listen on for SSE or MCP transport.
*/
port?: number;
/**
* The host to bind the server to. Default is localhost. Use 0.0.0.0 to bind to all interfaces.
*/
host?: string;
/**
* The hosts this server is allowed to serve from. Defaults to the host server is bound to.
* This is not for CORS, but rather for the DNS rebinding protection.
*/
allowedHosts?: string[];
},
// List of additional capabilities
capabilities?: Array<
'tabs' | // Tab management
'install' | // Browser installation
'pdf' | // PDF generation
'vision' | // Coordinate-based interactions
>;
/**
* List of enabled tool capabilities. Possible values:
* - 'core': Core browser automation features.
* - 'pdf': PDF generation and manipulation.
* - 'vision': Coordinate-based interactions.
*/
capabilities?: ToolCapability[];
// Directory for output files
/**
* Whether to save the Playwright session into the output directory.
*/
saveSession?: boolean;
/**
* Whether to save the Playwright trace of the session into the output directory.
*/
saveTrace?: boolean;
/**
* If specified, saves the Playwright video of the session into the output directory.
*/
saveVideo?: {
width: number;
height: number;
};
/**
* Reuse the same browser context between all connected HTTP clients.
*/
sharedBrowserContext?: boolean;
/**
* Secrets are used to prevent LLM from getting sensitive data while
* automating scenarios such as authentication.
* Prefer the browser.contextOptions.storageState over secrets file as a more secure alternative.
*/
secrets?: Record<string, string>;
/**
* The directory to save 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".
* Specify the attribute to use for test ids, defaults to "data-testid".
*/
testIdAttribute?: string;
timeouts?: {
/*
* Configures default action timeout: https://playwright.dev/docs/api/class-page#page-set-default-timeout. Defaults to 5000ms.
*/
action?: number;
/*
* Configures default navigation timeout: https://playwright.dev/docs/api/class-page#page-set-default-navigation-timeout. Defaults to 60000ms.
*/
navigation?: number;
};
/**
* Whether to send image responses to the client. Can be "allow", "omit", or "auto". Defaults to "auto", which sends images if the client can display them.
*/
imageResponses?: 'allow' | 'omit';
}
};
```
</details>
@@ -668,6 +824,15 @@ http.createServer(async (req, res) => {
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_run_code**
- Title: Run Playwright code
- Description: Run Playwright code snippet
- Parameters:
- `code` (string): Playwright code snippet to run. The snippet should access the `page` object to interact with the page. Can make multiple statements. For example: `await page.getByRole('button', { name: 'Submit' }).click();`
- Read-only: **false**
<!-- NOTE: This has been generated via update-readme.js -->
- **browser_select_option**
- Title: Select option
- Description: Select an option in a dropdown

5
config.d.ts vendored
View File

@@ -69,6 +69,11 @@ export type Config = {
*/
remoteEndpoint?: string;
/**
* Paths to TypeScript files to add as initialization scripts for Playwright page.
*/
initPage?: string[];
/**
* Paths to JavaScript files to add as initialization scripts.
* The scripts will be evaluated in every page before any of the page's scripts.

View File

@@ -45,4 +45,33 @@ Configure Playwright MCP server to connect to the browser using the extension by
When the LLM interacts with the browser for the first time, it will load a page where you can select which browser tab the LLM will connect to. This allows you to control which specific page the AI assistant will interact with during the session.
### Bypassing the Connection Approval Dialog
By default, you'll need to approve each connection when the MCP server tries to connect to your browser. To bypass this approval dialog and allow automatic connections, you can use an authentication token.
#### Using Your Unique Authentication Token
1. After installing the extension, click on the extension icon or navigate to the extension's status page
2. Copy the `PLAYWRIGHT_MCP_EXTENSION_TOKEN` value displayed in the extension UI
3. Add it to your MCP server configuration:
```json
{
"mcpServers": {
"playwright-extension": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--extension"
],
"env": {
"PLAYWRIGHT_MCP_EXTENSION_TOKEN": "your-token-here"
}
}
}
}
```
This token is unique to your browser profile and provides secure authentication between the MCP server and the extension. Once configured, you won't need to manually approve connections each time.

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Playwright MCP Bridge",
"version": "0.0.43",
"version": "0.0.48",
"description": "Share browser tabs with Playwright MCP server",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9nMS2b0WCohjVHPGb8D9qAdkbIngDqoAjTeSccHJijgcONejge+OJxOQOMLu7b0ovt1c9BiEJa5JcpM+EHFVGL1vluBxK71zmBy1m2f9vZF3HG0LSCp7YRkum9rAIEthDwbkxx6XTvpmAY5rjFa/NON6b9Hlbo+8peUSkoOK7HTwYnnI36asZ9eUTiveIf+DMPLojW2UX33vDWG2UKvMVDewzclb4+uLxAYshY7Mx8we/b44xu+Anb/EBLKjOPk9Yh541xJ5Ozc8EiP/5yxOp9c/lRiYUHaRW+4r0HKZyFt0eZ52ti2iM4Nfk7jRXR7an3JPsUIf5deC/1cVM/+1ZQIDAQAB",
"permissions": [

View File

@@ -1,12 +1,12 @@
{
"name": "@playwright/mcp-extension",
"version": "0.0.37",
"version": "0.0.48",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@playwright/mcp-extension",
"version": "0.0.37",
"version": "0.0.48",
"license": "Apache-2.0",
"devDependencies": {
"@types/chrome": "^0.0.315",
@@ -16,7 +16,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.8.2",
"vite": "^5.4.20",
"vite": "^5.4.21",
"vite-plugin-static-copy": "^3.1.1"
},
"engines": {
@@ -1796,9 +1796,9 @@
}
},
"node_modules/vite": {
"version": "5.4.20",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.20.tgz",
"integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==",
"version": "5.4.21",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz",
"integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==",
"dev": true,
"license": "MIT",
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "@playwright/mcp-extension",
"version": "0.0.43",
"version": "0.0.48",
"description": "Playwright MCP Browser Extension",
"private": true,
"repository": {
@@ -29,7 +29,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.8.2",
"vite": "^5.4.20",
"vite": "^5.4.21",
"vite-plugin-static-copy": "^3.1.1"
}
}

32
package-lock.json generated
View File

@@ -1,23 +1,23 @@
{
"name": "@playwright/mcp",
"version": "0.0.43",
"version": "0.0.48",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@playwright/mcp",
"version": "0.0.43",
"version": "0.0.48",
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.57.0-alpha-2025-10-16",
"playwright-core": "1.57.0-alpha-2025-10-16"
"playwright": "1.58.0-alpha-1763757971000",
"playwright-core": "1.58.0-alpha-1763757971000"
},
"bin": {
"mcp-server-playwright": "cli.js"
},
"devDependencies": {
"@modelcontextprotocol/sdk": "^1.17.5",
"@playwright/test": "1.57.0-alpha-2025-10-16",
"@playwright/test": "1.58.0-alpha-1763757971000",
"@types/node": "^24.3.0",
"zod-to-json-schema": "^3.24.6"
},
@@ -50,13 +50,13 @@
}
},
"node_modules/@playwright/test": {
"version": "1.57.0-alpha-2025-10-16",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0-alpha-2025-10-16.tgz",
"integrity": "sha512-WeQm4QMmW78sKNSPrkMCkhm5jrmDYJushuuDX434EsG8l0+1yW/CxDKaUsy+URZay162SByoFbclaoJ5ElN1yg==",
"version": "1.58.0-alpha-1763757971000",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0-alpha-1763757971000.tgz",
"integrity": "sha512-7qItUHqUH9dOaLvydEZuE3+pfXa/BHzAlrG0XlVWUL5xo//7xKNtj6qjyQKvR/bUySofT7PmFJGP6EUHKaV9UQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.57.0-alpha-2025-10-16"
"playwright": "1.58.0-alpha-1763757971000"
},
"bin": {
"playwright": "cli.js"
@@ -825,12 +825,12 @@
}
},
"node_modules/playwright": {
"version": "1.57.0-alpha-2025-10-16",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0-alpha-2025-10-16.tgz",
"integrity": "sha512-a1527pq+d/EQRwfoUpnTfjZqA04qs5y3A3HedQZiU6Vicc35VcIIpYin99pklFQdyBd1M9oj9oKFsHbilflo6g==",
"version": "1.58.0-alpha-1763757971000",
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0-alpha-1763757971000.tgz",
"integrity": "sha512-Ck2UJWEaHULTN2hSjdcCpYF3wd5R8gde3IGRhms8Fb9YpqKHRiAzQqnlmouPlSh5pF+Mg9aZTtrtjq3NeIiXkQ==",
"license": "Apache-2.0",
"dependencies": {
"playwright-core": "1.57.0-alpha-2025-10-16"
"playwright-core": "1.58.0-alpha-1763757971000"
},
"bin": {
"playwright": "cli.js"
@@ -843,9 +843,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.57.0-alpha-2025-10-16",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0-alpha-2025-10-16.tgz",
"integrity": "sha512-QfB4sdxqkxN3mrBii/Fqh65qSggrPbcDMJcsqjwsShn1lxbX48P8WuNNSdF05lwDfgS3BsQBkay3SdY3caueAg==",
"version": "1.58.0-alpha-1763757971000",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0-alpha-1763757971000.tgz",
"integrity": "sha512-4nN53aSvtlz05uFtHn4+PABtZba8Z+jJKLRbPF0+mmoLfD2n9hAGZbvvrVy+iKmoUEvsHbKOBZCJ2NlKjIzZ9w==",
"license": "Apache-2.0",
"bin": {
"playwright-core": "cli.js"

View File

@@ -1,7 +1,8 @@
{
"name": "@playwright/mcp",
"version": "0.0.43",
"version": "0.0.48",
"description": "Playwright Tools for MCP",
"mcpName": "com.microsoft/playwright-mcp",
"repository": {
"type": "git",
"url": "git+https://github.com/microsoft/playwright-mcp.git"
@@ -18,6 +19,8 @@
"lint": "npm run update-readme",
"update-readme": "node update-readme.js",
"docker-build": "docker build --no-cache -t playwright-mcp-dev:latest .",
"docker-rm": "docker rm playwright-mcp-dev",
"docker-run": "docker run -it -p 8080:8080 --name playwright-mcp-dev playwright-mcp-dev:latest",
"test": "playwright test",
"ctest": "playwright test --project=chrome",
"ftest": "playwright test --project=firefox",
@@ -35,15 +38,15 @@
}
},
"dependencies": {
"playwright": "1.57.0-alpha-2025-10-16",
"playwright-core": "1.57.0-alpha-2025-10-16"
"playwright": "1.58.0-alpha-1763757971000",
"playwright-core": "1.58.0-alpha-1763757971000"
},
"bin": {
"mcp-server-playwright": "cli.js"
},
"devDependencies": {
"@modelcontextprotocol/sdk": "^1.17.5",
"@playwright/test": "1.57.0-alpha-2025-10-16",
"@playwright/test": "1.58.0-alpha-1763757971000",
"@types/node": "^24.3.0",
"zod-to-json-schema": "^3.24.6"
}

View File

@@ -36,6 +36,7 @@ test('test snapshot tool list', async ({ client }) => {
'browser_network_requests',
'browser_press_key',
'browser_resize',
'browser_run_code',
'browser_snapshot',
'browser_tabs',
'browser_take_screenshot',
@@ -67,6 +68,7 @@ test('test tool list proxy mode', async ({ startClient }) => {
'browser_network_requests',
'browser_press_key',
'browser_resize',
'browser_run_code',
'browser_snapshot',
'browser_tabs',
'browser_take_screenshot',

View File

@@ -16,10 +16,16 @@
import { test, expect } from './fixtures';
test('browser_click', async ({ client, server, mcpBrowser }) => {
test('browser_click', async ({ client, server }) => {
server.setContent('/', `
<title>Title</title>
<button>Submit</button>
<script>
const button = document.querySelector('button');
button.addEventListener('click', () => {
button.focus(); // without manual focus, webkit focuses body
});
</script>
`, 'text/html');
expect(await client.callTool({
@@ -38,6 +44,6 @@ test('browser_click', async ({ client, server, mcpBrowser }) => {
},
})).toHaveResponse({
code: `await page.getByRole('button', { name: 'Submit' }).click();`,
pageState: expect.stringContaining(`- button "Submit" ${mcpBrowser !== 'webkit' || process.platform === 'linux' ? '[active] ' : ''}[ref=e2]`),
pageState: expect.stringContaining(`button "Submit" [active] [ref=e2]`),
});
});