DaddyNote

UK, Irish and EU money and travel rules, worked through step by step, with the date each figure was checked.

AI how-to notes · 2026-09-17 · last run 2026-09-17 · 한국어 원문

Attaching Playwright MCP to Claude Code on Windows — @playwright/mcp at project scope and the first connection

The short version

On Windows PowerShell 7, claude mcp add playwright --scope project -- npx -y @playwright/mcp@latest --headless --isolated plus approval returned ✔ Connected. On our machine the first page opened without downloading a browser. Querying the server config showed the default browser as channel: "chrome", so we take it that it used the already-installed Chrome. Local HTML files did not open straight from a file:// URL.

2026-09-28 addition: the Windows output and versions below remain the 2026-09-17 record. Check with the public client near the end supplies downloadable new examples and a separate Linux validation scope. This does not restore the private mcp_client.mjs or claim a Windows rerun.

Who this is for

You are attaching Playwright MCP to Claude Code for the first time. You want it in a single project without touching your personal settings file (~/.claude.json). Or you attached it, opened a file:///C:/... URL, and hit Access to "file:" protocol is blocked.

What we tested on

ItemValue
OSWindows 11 Home (10.0.26200)
ShellsPowerShell 7.6.6 (the claude mcp commands), Git Bash (logs and file checks)
Claude Code2.1.274 (Claude Code)
Node.js / npxv24.19.0 / 11.17.0
Server package@playwright/mcp 0.0.81 (@latest per npm view); the server reported its own name and version as Playwright 1.64.0-alpha-2026-09-14
Test folderC:\Users\User\AppData\Local\Temp\longtail_C2\proj

First, check the package and the options

npm view @playwright/mcp name version bin engines --json
npx -y @playwright/mcp@latest --help

npm view reported the name @playwright/mcp, version 0.0.81, executable playwright-mcp, and "node": ">=18". The official README (github.com/microsoft/playwright-mcp, checked 2026-09-17) also requires Node.js 18 or later, and its Claude Code example is the one-liner claude mcp add playwright npx @playwright/mcp@latest.

Three options from the help text went into this experiment.

  --headless                            run browser in headless mode, headed by
                                        default
  --isolated                            keep the browser profile in memory, do
                                        not save it to disk.
  --allow-unrestricted-file-access      allow access to files outside of the
                                        workspace roots. Also allows
                                        unrestricted access to file:// URLs. By
                                        default access to file system is
                                        restricted to workspace root directories
                                        (or cwd if no roots are configured)
                                        only, and navigation to file:// URLs is
                                        blocked.

There is a reason for --isolated. The README's User profile section says the default is a persistent profile written to disk, located on Windows at %USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-{workspace-hash}. To leave no trace of the experiment, we chose to keep the profile in memory only. Comparing the child entry names under %LOCALAPPDATA%\ms-playwright before the first tool call and after the page-opening tests showed no difference.

Step 1 — add at project scope

Set-Location 'C:\Users\User\AppData\Local\Temp\longtail_C2\proj'
claude mcp add playwright --scope project -e PLAYWRIGHT_BROWSERS_PATH='C:\Users\User\AppData\Local\Temp\longtail_C2\browsers17' -- npx -y '@playwright/mcp@latest' --headless --isolated
Added stdio MCP server playwright with command: npx -y @playwright/mcp@latest --headless --isolated to project config
File modified: C:\Users\User\AppData\Local\Temp\longtail_C2\proj\.mcp.json

-e PLAYWRIGHT_BROWSERS_PATH=… is there so that any browser download would land in a temp folder. As it turned out, that folder stayed empty through the end of the experiment. The .mcp.json it produced (338 bytes):

{
  "mcpServers": {
    "playwright": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@playwright/mcp@latest",
        "--headless",
        "--isolated"
      ],
      "env": {
        "PLAYWRIGHT_BROWSERS_PATH": "C:\\Users\\User\\AppData\\Local\\Temp\\longtail_C2\\browsers17"
      }
    }
  }
}

claude mcp add --help lists "local" as the default for -s, --scope <scope>, so leaving --scope off does not put it at project scope. Where each scope saves, and the cmd /c question, are covered in Adding an MCP server to Claude Code.

Step 2 — check the status

Before approval, both claude mcp list and claude mcp get playwright showed it waiting.

playwright: npx -y @playwright/mcp@latest --headless --isolated - ⏸ Pending approval (run `claude` to approve)

To check without opening an interactive session, we approved it for that invocation with --settings. PowerShell quoting caught us out once here: written as '{\"enableAllProjectMcpServers\": true}' with backslashes, it produced Error: Invalid JSON provided to --settings and exit code 1. This machine's PowerShell 7.6.6 has $PSNativeCommandArgumentPassing set to Windows, and dropping the backslashes made it work.

claude --settings '{"enableAllProjectMcpServers": true}' mcp get playwright
playwright:
  Scope: Project config (shared via .mcp.json)
  Status: ✔ Connected
  Type: stdio
  Command: npx
  Args: -y @playwright/mcp@latest --headless --isolated
  Environment:
    PLAYWRIGHT_BROWSERS_PATH=C:\Users\User\AppData\Local\Temp\longtail_C2\browsers17

Step 3 — tool list and page loading: the 2026-09-17 record

✔ Connected only confirms a connection, so we exercised the tools separately. We wrote a node script (mcp_client.mjs) that reads the command, args, and env straight out of .mcp.json, launches the server, and sends JSON-RPC over stdio in the order initialize → notifications/initialized → tools/list → tools/call (browser_navigate) → browser_close. On Windows npx is npx.cmd, so spawn got shell: true. That script belongs to the original raw material and is not downloadable from this article. The command below is retained as a historical record; to run a check now, use the public mcp-smoke.mjs example near the end.

node mcp_client.mjs 'C:/Users/User/AppData/Local/Temp/longtail_C2/proj' - --caps config
initialize (2.5s): {"name":"Playwright","version":"1.64.0-alpha-2026-09-14"} protocol 2025-06-18 
tools/list (2.5s): 27 tools
browser_get_config (3.0s):
"browser": {
    "launchOptions": {
      "headless": true,
      "channel": "chrome",

There are 26 tools by default, and 27 with --caps config, which turns on the config-inspection tool browser_get_config. The channel that browser_get_config reported is chrome. We take that to be why a page opened with no browser download, though we did not verify the executable path that actually ran (this machine has a 153.0.8010.47 folder under C:\Program Files\Google\Chrome\Application).

We opened the same file (proj\test.html) three ways.

AttemptServer argsbrowser_navigate resultElapsed (from server start)
A. file:///C:/…/proj/test.htmldefault (--headless --isolated)isError=true, Error: Access to "file:" protocol is blocked.8.5s
B. http://127.0.0.1:<port>/test.html served by the scriptdefaultsucceeded, Page Title: longtail C2 test page4.3s
C. file:///C:/…/proj/test.htmldefault + --allow-unrestricted-file-accesssucceeded, same title3.7s

The full error text from A:

### Error
Error: Access to "file:" protocol is blocked. Attempted URL: "file:///C:/Users/User/AppData/Local/Temp/longtail_C2/proj/test.html"

The responses from B and C carried a snapshot file path such as - [Snapshot](.playwright-mcp\page-2026-09-17T09-16-12-784Z.yml), and a 130-byte .yml appeared in a .playwright-mcp folder under the working directory.

- generic [active] [ref=e1]:
  - heading "Hello from a local file" [level=1] [ref=e2]
  - paragraph [ref=e3]: playwright-mcp check

If your goal is to inspect local files, serving them over local HTTP as in B leaves the default restriction in place. Option C, per its own help text, also opens up access to files outside the working folder.

Step 4 — remove it

$ claude mcp remove playwright --scope project
Removed MCP server playwright from project config
File modified: C:\Users\User\AppData\Local\Temp\longtail_C2\proj\.mcp.json

.mcp.json emptied to {"mcpServers": {}} (22 bytes), and after removal the output of claude mcp list had zero lines containing longtail_C2 or --isolated. The string longtail_C2 also appeared zero times in %USERPROFILE%\.claude.json (counts only; we never opened the contents). After the experiment we deleted the 1.5G temp folder longtail_C2 with rm -rf, leaving nothing behind.

Results

StepResult
claude mcp add … --scope projectexit code 0, .mcp.json 338 bytes
list/get before approval⏸ Pending approval
list/get after --settings approval✔ Connected
initialize response2.5 to 7.4 seconds across four runs
tools/list26 tools (27 with --caps config)
Default browserchannel: "chrome"; the temp browser folder stayed empty
Opening file://blocked by default, succeeded with --allow-unrestricted-file-access
claude mcp remove.mcp.json 22 bytes, zero longtail_C2 strings in ~/.claude.json

What didn't work

What the 2026-09-17 test did not check

Check with the public client — added 2026-09-28

Create a separate empty folder and save mcp-smoke.mjs and playwright-test.html there under those exact names. The new client uses the MCP SDK to connect and list tools, optionally calls one tool, then closes the connection. It does not read .mcp.json or change Claude Code approvals. You need Node.js and npm.

Install the pinned packages in that folder:

npm init -y
npm install --save-exact @modelcontextprotocol/sdk@1.30.1 @playwright/mcp@0.0.82

To keep browser downloads in this example folder, set this environment variable in PowerShell. Keep the same value for installation and MCP calls in this terminal.

$env:PLAYWRIGHT_BROWSERS_PATH = Join-Path $PWD 'browsers-check'

In Git Bash or Linux Bash, use this line instead:

export PLAYWRIGHT_BROWSERS_PATH="$PWD/browsers-check"

First, check server connection and the tool list without opening a browser:

node mcp-smoke.mjs -- node node_modules/@playwright/mcp/cli.js --headless --isolated --browser chromium

To open a page, install the browser this MCP version requests. Its revision may differ from the one the regular playwright package uses; see the separate missing-browser installation steps.

node node_modules/@playwright/mcp/cli.js install-browser chrome-for-testing

Open a second terminal in the same folder, start a local HTTP server that serves only the test HTML, and leave it running:

node -e "const http=require('node:http'); const fs=require('node:fs'); http.createServer((req,res)=>{res.setHeader('Content-Type','text/html; charset=utf-8'); res.end(fs.readFileSync('playwright-test.html'));}).listen(8765,'127.0.0.1');"

Save a navigate.json file in the first terminal's folder with this content:

{"url":"http://127.0.0.1:8765/playwright-test.html"}

Call the tool from the first terminal, where you set the environment variable. The new example launches the server directly with node, so it does not need shell: true for npx.cmd.

node mcp-smoke.mjs --call browser_navigate --args-file navigate.json -- node node_modules/@playwright/mcp/cli.js --headless --isolated --browser chromium

Success means the event: "result" contains no tool error and includes the page title DADDYNOTE browser check. A connected event and a tool list alone do not establish that a page opened. When finished, press Ctrl+C in the second terminal to stop the HTTP server. If the browser executable is missing, compare PLAYWRIGHT_BROWSERS_PATH at installation and invocation, and check the browser path requested in the error.

The 2026-09-28 check used Linux, Node.js 24.19.0, SDK 1.30.1, and @playwright/mcp 0.0.82. The actual server connected and listed 25 tools. Browser downloads failed with ZIP errors, so this check does not establish recovery through the default install path or successful HTTP navigation. The local HTTP server returned 200. We also attempted MCP navigation with a separately obtained Chromium 153.0.8010.0 executable, but the server's internal Unix socket failed with listen EPERM. The new client propagated isError: true and exit code 1. The separate direct-browser title check is recorded in the browser-not-found supplement. The PowerShell syntax and Windows execution were not retested. We rechecked the options and browser location guidance in the official MCP README and Playwright browser docs that day.

See also