← MCP servers · remorses

Playwriter

CAUTIONgrade C · trust 75/100

Chrome extension & CLI to let agents control your browser. Runs Playwright snippets in a stateful sandbox. Available as CLI or MCP

mcpplaywright

Overview

From the repository's own README, as read at the audited commit.

# ChangesetsThis folder contains **pending release notes** for public packages. Each `.md` file describes one user-facing fix or feature that should appear in the next generated changelog.## What to put here- Add one descriptive kebab-case `.md` file per logical change, for example `fix-auth-token-refresh.md`.- Use `patch` for fixes and `minor` for new features.- Write in present tense, focused on what users see.- Check GitHub issues first. If the change fixes one, include `Fixes #123` on its own line.## What not to put here- Do not add changesets for private packages or packages without a `version` field.- Do not edit `CHANGELOG.md` directly.- Do not run the interactive changeset CLI.- Do not add vague entries like "misc improvements" or "update internals".

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add website --env CLOUDFLARE_D1_TOKEN=${CLOUDFLARE_D1_TOKEN} --env PLAYWRITER_API_KEY=${PLAYWRITER_API_KEY} --env PLAYWRITER_CLOUD_TOKEN=${PLAYWRITER_CLOUD_TOKEN} --env PLAYWRITER_TOKEN=${PLAYWRITER_TOKEN} -- npx -y website
claude-desktop
{
  "mcpServers": {
    "website": {
      "command": "npx",
      "args": [
        "-y",
        "website"
      ],
      "env": {
        "CLOUDFLARE_D1_TOKEN": "${CLOUDFLARE_D1_TOKEN}",
        "PLAYWRITER_API_KEY": "${PLAYWRITER_API_KEY}",
        "PLAYWRITER_CLOUD_TOKEN": "${PLAYWRITER_CLOUD_TOKEN}",
        "PLAYWRITER_TOKEN": "${PLAYWRITER_TOKEN}"
      }
    }
  }
}

Exposed tools (2) 0 read · 1 write · 1 destructive

Blast radius: 1 tool can delete or overwrite. An agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
executewrite
resetdestructive

Details

Source
remorses/playwriter
npm
website
Transports
stdio
Credentials it reads
CLOUDFLARE_D1_TOKENPLAYWRITER_API_KEYPLAYWRITER_CLOUD_TOKENPLAYWRITER_TOKEN
License
MIT
Stars
3,899 · pushed 0d ago

Trust audit

Install with care. The audit found things worth knowing before you trust its output.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (6 observation(s))
Network
declared (5 observation(s))
Shell
none-observed
Dependencies
not all pinned
Secrets in source
found

Findings (25)

MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
playwriter/src/cli.ts:1918
console.log(`  Token: ${token ? '(configured)' : '(none)'}`)
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
playwriter/src/cli.ts:1922
console.log(`CDP endpoint: http://${options.host}:${RELAY_PORT}${token ? '?token=<token>' : ''}`)
MEDIUMObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
extension/vite.config.mts:53
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCJoq5UYhOo5x8s50pVBUHjQ8idyUHnZFDj1JspWJPe6kvM7RFIaE/y5WTAH05kuK0R7v/ipcGA4ywA5wKdPKHZzkl5xstlNPj0Ivu4CqLobU7eY5G3k3Gq7wql2pbwb/A8Nat4VLbfBjQLA6TGWd3LQOHS
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
playwriter/src/recorder.test.ts:228
body: JSON.stringify({ password: 'recorded-body-secret', operation: 'recorder-test' }),
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
reset
Why it matters. 1 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.agentignore
.agentignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.gitmodules
.gitmodules
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierrc.json
.prettierrc.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
playwriter/src/executor.unit.test.ts:190
expect(() => new Function(wrapped)).not.toThrow()
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
playwriter/src/executor.unit.test.ts:196
expect(() => new Function(wrapped)).not.toThrow()
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
playwriter/src/snapshot-tools.test.ts:314
const locatorFromString = eval('testPage.' + locatorString);
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
extension/src/background.ts:42
import ghostCursorBundleCode from '../../playwriter/dist/ghost-cursor-client.js?raw'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
extension/src/background.ts:45
import bippyBundleCode from '../../playwriter/dist/bippy.js?raw'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
website/src/components/ui/button.tsx:8
import { cn } from '../../lib/utils.ts'
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
website/src/server.tsx:21
import playwriterSkillMd from '../../skills/playwriter/SKILL.md?raw'
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
README.md:367
const browser = await chromium.connectOverCDP('http://127.0.0.1:19988')
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
playwriter/CHANGELOG.md:739
- Allows `chromium.connectOverCDP('http://127.0.0.1:19988')` without needing to call `getCdpUrl` first
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
playwriter/src/aria-snapshot.test.ts:54
baseUrl: `http://127.0.0.1:${address.port}`,
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
playwriter/src/cli-help.test.ts:73
['src/cli.ts', 'session', 'new', '--host', `http://127.0.0.1:${port}`],
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
playwriter/src/extension-connection.test.ts:39
const response = await fetch(`http://127.0.0.1:${TEST_PORT}/extension/status`)
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
extension/src/background.ts:384
const binary = atob(value)
LOWObfuscation / stealth · obf.decode_call · CWE-506, CWE-94
website/src/components/cdp-screencast.tsx:289
const bin = atob(base64)
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
db/package.json
ulid, @types/node, typescript
Why it matters. 3 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
extension/package.json
string-dedent, zustand, @types/chrome, typescript, vite, vite-plugin-static-copy
Why it matters. 6 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-09-17 · audit v0.4.0 · source sha d3e91f5401d4 · full audit: observations/trust-audit/mcp-server/remorses__playwriter.json · Report an issue or request a re-scan

Audit history

DateSourceVerdictGradeScoreChange
2026-09-17d3e91f5401d4CAUTIONC75first audit

Alternatives

Other servers in the same categories, safer ones first.

Questions

What is the Playwriter MCP server?

Chrome extension & CLI to let agents control your browser. Runs Playwright snippets in a stateful sandbox. Available as CLI or MCP

What tools does Playwriter expose?

2 in total: 0 read-only, 1 that write, and 1 that can delete or overwrite (reset). Every one is listed on this page with its risk.

Is Playwriter safe to connect to an agent?

With care. The audit graded it C (75/100) and found 25 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does Playwriter need?

It reads CLOUDFLARE_D1_TOKEN, PLAYWRITER_API_KEY, PLAYWRITER_CLOUD_TOKEN and PLAYWRITER_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does Playwriter run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as website.

How current is this page?

The grade is for one exact copy of the source (d3e91f5401d4), read on 2026-09-17. The repository is watched and re-audited when it changes.

Provenance: OBSERVED · read 2026-09-17 · job trust-audit-2026-09-17