playwriter by supercent-io/skills-template
npx skills add https://github.com/supercent-io/skills-template --skill playwriterPlaywriter 将 AI 代理连接到您正在运行的 Chrome 浏览器,而不是启动一个新的无头浏览器实例。您现有的登录状态、Cookie、扩展程序和标签页状态都将被保留。
与 agent-browser 的对比:agent-browser 会启动一个全新的无头浏览器(隔离,适合 CI 环境)。playwriter 则连接到您现有的 Chrome 会话(已认证、有状态、包含您的扩展程序)。
从 Web 应用商店安装 Playwriter Chrome 扩展(搜索 "Playwriter MCP" 或使用扩展 ID jfeammnjpkecdekppnclgkkffahnhfhe)。
安装后,在您希望允许自动化的任意标签页上点击扩展图标。当标签页启用控制时,图标会变为绿色。
npm install -g playwriter
# 或者无需安装直接运行:
npx playwriter@latest --help
扩展程序会自动在 localhost:19988 启动一个 WebSocket 中继服务器。
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
始终遵循 观察 → 执行 → 观察 的模式:
# 1. 创建一个会话
playwriter session new
# 2. 导航并观察
playwriter -s 1 -e 'await page.goto("https://example.com")'
playwriter -s 1 -e 'await snapshot({ page })'
# 3. 基于快照输出进行交互
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
# 4. 执行操作后重新观察
playwriter -s 1 -e 'await snapshot({ page })'
# 创建一个新的隔离有状态会话
playwriter session new
# 列出所有活动会话(显示浏览器、配置文件、状态信息)
playwriter session list
# 删除一个会话并清除其状态
playwriter session delete <sessionId>
# 重置 CDP 连接并清除执行环境
playwriter session reset <sessionId>
在会话中执行任意 Playwright 代码:
# 导航到一个 URL
playwriter -s 1 -e 'await page.goto("https://github.com")'
# 填写表单字段
playwriter -s 1 -e 'await page.fill("#search", "playwriter"); await page.keyboard.press("Enter")'
# 获取无障碍快照(对于文本内容,比截图更节省 token)
playwriter -s 1 -e 'await snapshot({ page })'
# 截取带有视觉无障碍标签的屏幕截图(按元素类型颜色编码)
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
# 在多次调用之间存储状态(state 对象在会话内持久存在)
playwriter -s 1 -e 'state.url = page.url(); state.title = await page.title()'
playwriter -s 1 -e 'console.log(state.url, state.title)'
引用规则:用单引号包裹代码。对于多行代码,使用 heredoc:
playwriter -s 1 -e "$(cat <<'EOF'
const text = await page.textContent('h1');
state.heading = text;
await snapshot({ page });
EOF
)"
~/.claude/settings.json 或 Claude Desktop MCP 设置){
"mcpServers": {
"playwriter": {
"command": "npx",
"args": ["-y", "playwriter@latest"]
}
}
}
{
"mcpServers": {
"playwriter": {
"command": "npx",
"args": ["-y", "playwriter@latest"],
"env": {
"PLAYWRITER_HOST": "your-relay-host",
"PLAYWRITER_TOKEN": "your-secret-token",
"PLAYWRITER_SESSION": "1"
}
}
}
}
| 工具 | 描述 |
|---|---|
execute | 运行任意的 JavaScript Playwright 代码(code、timeout 参数) |
reset | 重新创建 CDP 连接,清除状态 —— 在连接失败后使用 |
| 全局对象 | 描述 |
|---|---|
page | 当前的 Playwright 页面对象 |
context | 浏览器上下文 |
state | 持久化对象 —— 在同一会话的多次 -e 调用中持续存在 |
snapshot({ page }) | 以文本形式呈现的无障碍树(节省 token) |
screenshotWithAccessibilityLabels({ page }) | 带有颜色编码元素标记的屏幕截图 |
getPageMarkdown() | 通过 Mozilla Readability 获取文章文本 |
waitForPageLoad() | 智能页面加载检测 |
getLatestLogs() | 浏览器控制台错误/日志 |
getCleanHTML() | 清理后的 DOM HTML |
getLocatorStringForElement() | 获取 DOM 元素的选择器 |
getReactSource() | React 组件源码树 |
screenshotWithAccessibilityLabels({ page }) 在交互式元素上叠加颜色编码的标记:
| 颜色 | 元素类型 |
|---|---|
| 黄色 | 链接 |
| 橙色 | 按钮 |
| 珊瑚色 | 输入框 |
| 粉色 | 复选框 |
| 桃色 | 滑块 |
使用 aria-ref 点击带标签的元素:
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
# 拦截网络请求
playwriter -s 1 -e 'state.requests = []; page.on("request", r => state.requests.push(r.url()))'
# 稍后检查收集到的请求
playwriter -s 1 -e 'console.log(state.requests.slice(-5).join("\n"))'
# 屏幕录制
playwriter -s 1 -e 'await recording.start()'
# ... 执行操作 ...
playwriter -s 1 -e 'const video = await recording.stop(); state.video = video'
通过隧道控制远程机器上的 Chrome:
# 在运行 Chrome 的机器上:
playwriter serve --token my-secret --replace
# 从代理机器上:
playwriter --host <ip-or-hostname> --token my-secret -s 1 -e 'await page.goto("https://example.com")'
snapshot({ page })snapshot() 而非截图(更少的 token,更快)aria-ref、data-testid 或无障碍角色state 中:通过持久化页面引用避免重复导航reset:使用 playwriter session reset 可以干净地恢复 CDP 断开连接| 问题 | 解决方案 |
|---|---|
| 扩展程序未连接 | 点击标签页上的扩展图标;图标必须为绿色 |
connection refused :19988 | 扩展程序自动启动服务器;检查 Chrome 是否正在运行且已安装扩展 |
| 代码执行超时 | 使用 --timeout 30000 标志增加超时时间 |
| 点击无提示失败 | 使用 snapshot({ page }) —— 可能有模态框拦截了点击 |
| 会话过时 | 运行 playwriter session reset <id> 以恢复 CDP 连接 |
| 远程访问失败 | 确认 playwriter serve 正在运行且令牌匹配 |
playwriter skill —— 从 CLI 打印完整使用指南playwriter logfile —— 查看中继服务器 + CDP 日志路径每周安装量
464
代码仓库
GitHub 星标数
88
首次出现
2026年3月10日
安全审计
安装于
gemini-cli413
codex406
opencode393
github-copilot389
cursor389
kimi-cli388
Playwriter connects AI agents to your running Chrome browser instead of spawning a new headless instance. Your existing logins, cookies, extensions, and tab state are all preserved.
vs. agent-browser : agent-browser spawns a fresh headless browser (isolated, CI-friendly). playwriter connects to your existing Chrome session (authenticated, stateful, with your extensions).
Install the Playwriter Chrome extension from the Web Store (search "Playwriter MCP" or use extension ID jfeammnjpkecdekppnclgkkffahnhfhe).
After installing, click the extension icon on any tab you want to allow automation on. The icon turns green when a tab is enabled for control.
npm install -g playwriter
# or run without installing:
npx playwriter@latest --help
The extension auto-starts a WebSocket relay server at localhost:19988.
Always follow the Observe → Act → Observe pattern:
# 1. Create a session
playwriter session new
# 2. Navigate and observe
playwriter -s 1 -e 'await page.goto("https://example.com")'
playwriter -s 1 -e 'await snapshot({ page })'
# 3. Interact based on snapshot output
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
# 4. Re-observe after action
playwriter -s 1 -e 'await snapshot({ page })'
# Create a new isolated stateful session
playwriter session new
# List all active sessions (shows browser, profile, state info)
playwriter session list
# Delete a session and clear its state
playwriter session delete <sessionId>
# Reset the CDP connection and clear execution environment
playwriter session reset <sessionId>
Execute arbitrary Playwright code in a session:
# Navigate to a URL
playwriter -s 1 -e 'await page.goto("https://github.com")'
# Fill a form field
playwriter -s 1 -e 'await page.fill("#search", "playwriter"); await page.keyboard.press("Enter")'
# Get accessibility snapshot (preferred over screenshots for text content)
playwriter -s 1 -e 'await snapshot({ page })'
# Take screenshot with visual accessibility labels (color-coded by element type)
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
# Store state between calls (state object persists within session)
playwriter -s 1 -e 'state.url = page.url(); state.title = await page.title()'
playwriter -s 1 -e 'console.log(state.url, state.title)'
Quoting rules : Wrap code in single quotes. For multiline code, use heredoc:
playwriter -s 1 -e "$(cat <<'EOF'
const text = await page.textContent('h1');
state.heading = text;
await snapshot({ page });
EOF
)"
~/.claude/settings.json or Claude Desktop MCP settings){
"mcpServers": {
"playwriter": {
"command": "npx",
"args": ["-y", "playwriter@latest"]
}
}
}
{
"mcpServers": {
"playwriter": {
"command": "npx",
"args": ["-y", "playwriter@latest"],
"env": {
"PLAYWRITER_HOST": "your-relay-host",
"PLAYWRITER_TOKEN": "your-secret-token",
"PLAYWRITER_SESSION": "1"
}
}
}
}
| Tool | Description |
|---|---|
execute | Run arbitrary JavaScript Playwright code (code, timeout params) |
reset | Recreate CDP connection, clear state — use after connection failures |
| Global | Description |
|---|---|
page | Current Playwright page |
context | Browser context |
state | Persistent object — survives multiple -e calls in same session |
snapshot({ page }) | Accessibility tree as text (token-efficient) |
screenshotWithAccessibilityLabels({ page }) | Screenshot with color-coded element markers |
screenshotWithAccessibilityLabels({ page }) overlays color-coded markers on interactive elements:
| Color | Element type |
|---|---|
| Yellow | Links |
| Orange | Buttons |
| Coral | Inputs |
| Pink | Checkboxes |
| Peach | Sliders |
Click a labeled element using aria-ref:
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
# Intercept network requests
playwriter -s 1 -e 'state.requests = []; page.on("request", r => state.requests.push(r.url()))'
# Check collected requests later
playwriter -s 1 -e 'console.log(state.requests.slice(-5).join("\n"))'
# Screen recording
playwriter -s 1 -e 'await recording.start()'
# ... do actions ...
playwriter -s 1 -e 'const video = await recording.stop(); state.video = video'
Control Chrome on a remote machine via tunnel:
# On the machine with Chrome:
playwriter serve --token my-secret --replace
# From agent machine:
playwriter --host <ip-or-hostname> --token my-secret -s 1 -e 'await page.goto("https://example.com")'
snapshot({ page }) before and after each actionsnapshot() over screenshots for text inspection (fewer tokens, faster)aria-ref, data-testid, or accessible rolesstate: avoid repeated navigation by persisting page referencesreset on failures: CDP disconnects recover cleanly with playwriter session reset| Issue | Solution |
|---|---|
| Extension not connecting | Click extension icon on the tab; icon must be green |
connection refused :19988 | Extension auto-starts server; check Chrome is running with extension installed |
| Code execution timeout | Increase with --timeout 30000 flag |
| Click fails silently | Use snapshot({ page }) — a modal likely intercepts the click |
| Stale session | Run playwriter session reset <id> to restore CDP connection |
| Remote access failing | Confirm playwriter serve is running and token matches |
playwriter skill — print full usage guide from CLIplaywriter logfile — view relay server + CDP log pathsWeekly Installs
464
Repository
GitHub Stars
88
First Seen
Mar 10, 2026
Security Audits
Gen Agent Trust HubWarnSocketPassSnykFail
Installed on
gemini-cli413
codex406
opencode393
github-copilot389
cursor389
kimi-cli388
AI 代码实施计划编写技能 | 自动化开发任务分解与 TDD 流程规划工具
41,400 周安装
getPageMarkdown()| Article text via Mozilla Readability |
waitForPageLoad() | Smart load detection |
getLatestLogs() | Browser console errors/logs |
getCleanHTML() | Cleaned DOM HTML |
getLocatorStringForElement() | Get selector for a DOM element |
getReactSource() | React component source tree |