chore: update readme, add workflow

This commit is contained in:
Pavel Feldman 2025-03-21 13:16:30 -07:00
parent 624732b187
commit f9e5abb631
7 changed files with 95 additions and 21 deletions

35
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,35 @@
name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 18
uses: actions/setup-node@v4
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linting
run: npm run lint
- name: Build
run: npm run build
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run tests
run: npm test

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
lib/
node_modules/
test-results/

View File

@ -1,10 +1,41 @@
## Playwright MCP
This package is experimental and not yet ready for production use.
It is a subject to change and will not respect semver versioning.
A Model Context Protocol (MCP) server that provides browser automation capabilities using [Playwright](https://playwright.dev). This server enables LLMs to interact with web pages through structured accessibility snapshots, bypassing the need for screenshots or visually-tuned models.
### Key Features
- **Fast and lightweight**: Uses Playwrights accessibility tree, not pixel-based input.
- **LLM-friendly**: No vision models needed, operates purely on structured data.
- **Deterministic tool application**: Avoids ambiguity common with screenshot-based approaches.
### Use Cases
- Web navigation and form-filling
- Data extraction from structured content
- Automated testing driven by LLMs
- General-purpose browser interaction for agents
## Requirements
### Example config
```js
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp",
]
}
}
}
```
### Running headless browser (Browser without GUI).
This mode is useful for background or batch operations.
```js
{
"mcpServers": {
@ -19,22 +50,7 @@ It is a subject to change and will not respect semver versioning.
}
```
### Running headed browser (Browser with GUI).
```js
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp"
]
}
}
}
```
### Running headed browser on Linux
### Running headed browser on Linux w/o DISPLAY
When running headed browser on system w/o display or from worker processes of the IDEs,
you can run Playwright in a client-server manner. You'll run the Playwright server

17
package-lock.json generated
View File

@ -20,6 +20,7 @@
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.19.0",
"@playwright/test": "1.52.0-alpha-2025-03-21",
"@stylistic/eslint-plugin": "^3.0.1",
"@types/node": "^22.13.10",
"@typescript-eslint/eslint-plugin": "^8.26.1",
@ -283,6 +284,22 @@
"node": ">= 8"
}
},
"node_modules/@playwright/test": {
"version": "1.52.0-alpha-2025-03-21",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0-alpha-2025-03-21.tgz",
"integrity": "sha512-GGnn8kqjGB0rT7GThhas73r5pONnrztPlDAYrYfSO6mWB/NGIyxU3SrNY4Po8+bOnoqlBhxCdU1q+s84HKAMBg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"playwright": "1.52.0-alpha-2025-03-21"
},
"bin": {
"playwright": "cli.js"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",

View File

@ -17,7 +17,8 @@
"scripts": {
"build": "tsc",
"lint": "eslint .",
"watch": "tsc --watch"
"watch": "tsc --watch",
"test": "playwright test"
},
"exports": {
"./servers/server": "./lib/servers/server.js",
@ -37,6 +38,7 @@
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.19.0",
"@playwright/test": "1.52.0-alpha-2025-03-21",
"@stylistic/eslint-plugin": "^3.0.1",
"@typescript-eslint/eslint-plugin": "^8.26.1",
"@typescript-eslint/parser": "^8.26.1",

View File

@ -49,7 +49,10 @@ export class Context {
const browser = await this._createBrowser();
this._page = await browser.newPage();
this._page.on('console', event => this._console.push(event));
this._page.on('framenavigated', () => this._console.length = 0);
this._page.on('framenavigated', frame => {
if (!frame.parentFrame())
this._console.length = 0
});
})();
return this._initializePromise;
}

View File

@ -5,7 +5,7 @@
"esModuleInterop": true,
"moduleResolution": "node",
"strict": true,
"module": "ESNext",
"module": "CommonJS",
"outDir": "./lib"
},
"include": [