MCP server · Audited from source

Playwriter MCP server

by remorses/playwriterMIT licenceAudited 21 Sep 2026 · source d3e91f5401d4

npm websitestdio★ 3,908
!CAUTIONGrade C · 75/100 · 21 Sep 2026 · d3e91f5
3,908GitHub stars

Is it safe? With care — CAUTION, grade C (75/100). It exposes 2 tools: 0 read, 1 write and 1 destructive. The audit recorded 32 findings (0 critical, 0 high, 5 medium, 25 low). Maintainer's description: Chrome extension & CLI to let agents control your browser. Runs Playwright snippets in a stateful sandbox. Available as CLI or MCP

Ask an AI about this pageGChatGPTCClaudePPerplexityGeGeminiXGrok
More
Cite

Cite this page

ModelsAtlas. “Playwriter MCP server (remorses/playwriter)”. Retrieved 21 Sep 2026. https://modelsatlas.com/mcp/remorses/playwriter

Trust audit

Audit 0.4.1 · full source read 21 Sep 2026

Trust score75/100!CAUTION C
0 critical0 high5 medium25 low2 info

32 findings, listed below with the file and line each was found on. Grade A needs a sandboxed behavioural run too; this audit read the source only.

What the source does

  • FilesystemDeclared6 observations
  • NetworkDeclared5 observations
  • ShellNone observedNothing seen in the source
  • DependenciesNot pinnedSome ranges float
  • SecretsFoundSee the findings

“Declared” means the server says it does this and the source agrees. Browser, file and shell access are expected of some kinds of server.

Five audit layers

LayerWhat we checkResult
L0 ProvenanceRepo owner, licence, archive status, activityPASS 4 findings
L1 Static sourceSecrets, path traversal, supply chainWARN 20 findings
L2 InstructionsPrompt injection and authority framing in docs and tool descriptionsPASS
L3 InventoryDeclared tools match the sourceWARN 1 finding
L4 SandboxRun in isolation and watch behaviourSKIPPED

Provenance & runtime

Who published it, and what the audit could and could not run

Provenance

  • Repository owner remorsesUser accountAccount type recorded when we read the repository.
  • PackagePublished on npmwebsite, no version recorded
  • LicenceMITFrom the repository, as read at the audited commit.
  • Last push4 days agoActivity of the repository when we read it.
  • Source commit readd3e91f5401d4The audit covers exactly this commit, read on 21 Sep 2026.

Runtime

  • Sandbox runNot run yetThis audit read the source only; it did not execute the server.
  • Tool inventory2 declaredRead from the source and classed read, write or destructive.

Every value here is read from the record's own repository and audit.Suggest a correction

Findings (32)

Sorted by severity · the 25 most severe of 32 are listed

MEDIUMInformation disclosuredisclose.log_secret · playwriter/src/cli.ts:1918
F-12 Information disclosureCWE-209 · CWE-532Layer L1
console.log(`  Token: ${token ? '(configured)' : '(none)'}`)
Why
No further detail recorded for this rule.
Fix
—
MEDIUMInformation disclosuredisclose.log_secret · playwriter/src/cli.ts:1922
F-12 Information disclosureCWE-209 · CWE-532Layer L1
console.log(`CDP endpoint: http://${options.host}:${RELAY_PORT}${token ? '?token=<token>' : ''}`)
Why
No further detail recorded for this rule.
Fix
—
MEDIUMObfuscation / stealthobf.base64_blob · extension/vite.config.mts:53
F-07 Obfuscation / stealthCWE-506 · CWE-94Layer L1
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwCJoq5UYhOo5x8s50pVBUHjQ8idyUHnZFDj1JspWJPe6kvM7RFIaE/y5WTAH05kuK0R7v/ipcGA4ywA5wKdPKHZzkl5xstlNPj0Ivu4CqLobU7eY5G3k3Gq7wql2pbwb/A8Nat4VLbfBjQLA6TGWd3LQOHS
Why
No further detail recorded for this rule.
Fix
—
MEDIUMHard-coded secretssecret.generic · playwriter/src/recorder.test.ts:228
F-03 Hard-coded secretsCWE-798 · CWE-321Layer L1

Excerpt withheld: it is a secret, and we never print one.

Why
No further detail recorded for this rule.
Fix
—
MEDIUMFilesystem / pathmcp.destructive_tools
F-05 Filesystem / pathCWE-22 · CWE-59Layer L3
reset
Why
1 tool(s) can delete or overwrite
Fix
prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenanceinv.hidden_file · .agentignore
F-13 Inventory / provenanceCWE-1104Layer L0
.agentignore
Why
hidden member outside the usual dotfiles
Fix
review its purpose
LOWInventory / provenanceinv.hidden_file · .gitmodules
F-13 Inventory / provenanceCWE-1104Layer L0
.gitmodules
Why
hidden member outside the usual dotfiles
Fix
review its purpose
LOWInventory / provenanceinv.hidden_file · .prettierignore
F-13 Inventory / provenanceCWE-1104Layer L0
.prettierignore
Why
hidden member outside the usual dotfiles
Fix
review its purpose
LOWInventory / provenanceinv.hidden_file · .prettierrc.json
F-13 Inventory / provenanceCWE-1104Layer L0
.prettierrc.json
Why
hidden member outside the usual dotfiles
Fix
review its purpose
LOWCode injectioncode.eval_exec · playwriter/src/executor.unit.test.ts:190
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
expect(() => new Function(wrapped)).not.toThrow()
Why
evaluates text as code
Fix
remove; use a parser or a dispatch table
LOWCode injectioncode.eval_exec · playwriter/src/executor.unit.test.ts:196
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
expect(() => new Function(wrapped)).not.toThrow()
Why
evaluates text as code
Fix
remove; use a parser or a dispatch table
LOWCode injectioncode.eval_exec · playwriter/src/snapshot-tools.test.ts:314
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
const locatorFromString = eval('testPage.' + locatorString);
Why
evaluates text as code
Fix
remove; use a parser or a dispatch table
LOWFilesystem / pathfs.traversal · extension/src/background.ts:42
F-05 Filesystem / pathCWE-22 · CWE-59Layer L1
import ghostCursorBundleCode from '../../playwriter/dist/ghost-cursor-client.js?raw'
Why
No further detail recorded for this rule.
Fix
—
LOWFilesystem / pathfs.traversal · extension/src/background.ts:45
F-05 Filesystem / pathCWE-22 · CWE-59Layer L1
import bippyBundleCode from '../../playwriter/dist/bippy.js?raw'
Why
No further detail recorded for this rule.
Fix
—
LOWFilesystem / pathfs.traversal · website/src/components/ui/button.tsx:8
F-05 Filesystem / pathCWE-22 · CWE-59Layer L1
import { cn } from '../../lib/utils.ts'
Why
No further detail recorded for this rule.
Fix
—
LOWFilesystem / pathfs.traversal · website/src/server.tsx:21
F-05 Filesystem / pathCWE-22 · CWE-59Layer L1
import playwriterSkillMd from '../../skills/playwriter/SKILL.md?raw'
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · README.md:367
F-04 Network egressCWE-200 · CWE-319Layer L1
const browser = await chromium.connectOverCDP('http://127.0.0.1:19988')
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · playwriter/CHANGELOG.md:739
F-04 Network egressCWE-200 · CWE-319Layer L1
- Allows `chromium.connectOverCDP('http://127.0.0.1:19988')` without needing to call `getCdpUrl` first
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · playwriter/src/aria-snapshot.test.ts:54
F-04 Network egressCWE-200 · CWE-319Layer L1
baseUrl: `http://127.0.0.1:${address.port}`,
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · playwriter/src/cli-help.test.ts:73
F-04 Network egressCWE-200 · CWE-319Layer L1
['src/cli.ts', 'session', 'new', '--host', `http://127.0.0.1:${port}`],
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · playwriter/src/extension-connection.test.ts:39
F-04 Network egressCWE-200 · CWE-319Layer L1
const response = await fetch(`http://127.0.0.1:${TEST_PORT}/extension/status`)
Why
No further detail recorded for this rule.
Fix
—
LOWObfuscation / stealthobf.decode_call · extension/src/background.ts:384
F-07 Obfuscation / stealthCWE-506 · CWE-94Layer L1
const binary = atob(value)
Why
No further detail recorded for this rule.
Fix
—
LOWObfuscation / stealthobf.decode_call · website/src/components/cdp-screencast.tsx:289
F-07 Obfuscation / stealthCWE-506 · CWE-94Layer L1
const bin = atob(base64)
Why
No further detail recorded for this rule.
Fix
—
LOWSupply chainsupply.unpinned · db/package.json
F-08 Supply chainCWE-829 · CWE-1357Layer L1
ulid, @types/node, typescript
Why
3 dependency range(s) float
Fix
pin exact versions or ship a lockfile
LOWSupply chainsupply.unpinned · extension/package.json
F-08 Supply chainCWE-829 · CWE-1357Layer L1
string-dedent, zustand, @types/chrome, typescript, vite, vite-plugin-static-copy
Why
6 dependency range(s) float
Fix
pin exact versions or ship a lockfile

Tools it exposes

2 declared in source · 1 destructive

0 read1 write1 destructive

1 tool can delete or overwrite. An agent that can be talked into calling a tool can be talked into calling this one, so give it a token scoped to what you need.

ToolRiskWhat it does
resetdestructiveNo description in the source
executewriteNo description in the source

Install

audited commit d3e91f5

Read the findings first. The most severe is Information disclosure (medium) at playwriter/src/cli.ts.

One-click links open your editor with the config below filled in, exactly as the snippets show it. The audit covers commit d3e91f5 only.

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

The command does not pin a version; the audit covers commit d3e91f5401d4. Transport: stdio. Reads these environment variables: CLOUDFLARE_D1_TOKEN, PLAYWRITER_API_KEY, PLAYWRITER_CLOUD_TOKEN, PLAYWRITER_TOKEN. Give it the narrowest token it needs.

Audit history

  1. !CAUTION C 75 / 100

    Source changed, verdict held · d3e91f5401d4

README badge

For maintainers · updates on every re-audit

ModelsAtlas: CAUTION CMODELSATLASCAUTION · C
[![ModelsAtlas: CAUTION C](https://modelsatlas.com/mcp/remorses/playwriter/badge.svg)](https://modelsatlas.com/mcp/remorses/playwriter/)

The badge always shows the latest audit; a maintainer cannot pin an old verdict.

Other ratings

Cited, never blended into our score

No third-party security ratings are recorded for this server yet. When they exist they appear here with their source and date, beside, not inside, our grade.

Questions about Playwriter MCP server

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-21. The repository is watched and re-audited when it changes.

Sources

  • remorses/playwriter on GitHub — the source we read, its licence, stars and activityObserved · 21 Sep 2026
  • ModelsAtlas trust audit — CAUTION verdict for commit d3e91f5401d4Observed · 21 Sep 2026

Spotted something wrong? Report a correction · Methodology

Keep going in your AI

Opens with this page as the source. We add nothing else to the prompt.