AI 해결 노트 · 2026-09-17 · 실측 2026-09-17
윈도우에서 Playwright MCP를 Claude Code에 붙이기 — @playwright/mcp project 범위 설정과 첫 연결 확인
한 줄로
윈도우 PowerShell 7에서 claude mcp add playwright --scope project -- npx -y @playwright/mcp@latest --headless --isolated로 붙이고 승인하자 ✔ Connected가 나왔습니다. 저희 PC에서는 따로 브라우저를 내려받지 않아도 첫 페이지가 열렸습니다. 서버 설정 조회에서 기본 브라우저가 channel: "chrome"으로 나왔고, 이미 설치된 Chrome을 쓴 것으로 봅니다. 로컬 HTML 파일은 file:// 주소로 바로 열리지 않았습니다.
이런 분께
Claude Code에 Playwright MCP를 처음 붙이는 분. 개인 설정 파일(~/.claude.json)을 건드리지 않고 한 프로젝트에만 넣고 싶은 분. 붙인 뒤 file:///C:/... 주소를 열었다가 Access to "file:" protocol is blocked를 본 분.
실측 환경
| 항목 | 값 |
|---|---|
| OS | Windows 11 Home (10.0.26200) |
| 셸 | PowerShell 7.6.6 (claude mcp 명령), Git Bash (로그·파일 확인) |
| Claude Code | 2.1.274 (Claude Code) |
| Node.js / npx | v24.19.0 / 11.17.0 |
| 서버 패키지 | @playwright/mcp 0.0.81 (npm view 기준 @latest), 서버가 밝힌 이름·버전 Playwright 1.64.0-alpha-2026-09-14 |
| 실험 폴더 | C:\Users\User\AppData\Local\Temp\longtail_C2\proj |
먼저 패키지와 옵션 확인
npm view @playwright/mcp name version bin engines --json
npx -y @playwright/mcp@latest --helpnpm view 결과는 이름 @playwright/mcp, 버전 0.0.81, 실행 파일 playwright-mcp, "node": ">=18"이었습니다. 공식 README(github.com/microsoft/playwright-mcp, 2026-09-17 확인)의 요구 사항도 Node.js 18 이상이고, Claude Code용 예시는 claude mcp add playwright npx @playwright/mcp@latest 한 줄입니다.
도움말에서 이번 실험에 쓴 옵션은 셋입니다.
--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.--isolated를 넣은 이유가 있습니다. README의 User profile 절을 보면 기본값은 디스크에 남는 영구 프로필이고, 윈도우 위치는 %USERPROFILE%\AppData\Local\ms-playwright\mcp-{channel}-{workspace-hash}입니다. 실험 흔적을 남기지 않으려고 프로필을 메모리에만 두는 쪽을 골랐습니다. 서버를 붙인 뒤 첫 도구 호출 전과 페이지 열기 실험 뒤에 %LOCALAPPDATA%\ms-playwright의 하위 항목 이름을 비교했을 때 차이는 없었습니다.
1단계 — project 범위로 추가
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 --isolatedAdded 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=…는 혹시 브라우저를 내려받게 되면 임시 폴더로 받으려고 넣었습니다. 결과적으로 이 폴더는 실험이 끝날 때까지 비어 있었습니다. 만들어진 .mcp.json(338바이트)은 이렇습니다.
{
"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에는 -s, --scope <scope>의 기본값이 "local"로 적혀 있어, --scope를 빼면 project 범위로 들어가지 않습니다. 범위별 저장 위치와 cmd /c 이야기는 Claude Code에 MCP 서버 붙이기에 적었습니다.
2단계 — 상태 확인
승인 전 claude mcp list와 claude mcp get playwright는 둘 다 대기 상태였습니다.
playwright: npx -y @playwright/mcp@latest --headless --isolated - ⏸ Pending approval (run `claude` to approve)대화형 세션을 열지 않고 확인하려고 --settings로 그 실행에만 승인을 줬습니다. 여기서 PowerShell 따옴표에 한 번 걸렸습니다. '{\"enableAllProjectMcpServers\": true}'처럼 역슬래시를 넣었더니 Error: Invalid JSON provided to --settings와 종료 코드 1이 나왔습니다. 이 PC의 PowerShell 7.6.6은 $PSNativeCommandArgumentPassing이 Windows였고, 역슬래시 없이 쓰자 통과했습니다.
claude --settings '{"enableAllProjectMcpServers": true}' mcp get playwrightplaywright:
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\browsers173단계 — 도구 목록과 페이지 열기를 스크립트로 확인
✔ Connected는 연결 확인일 뿐이라 실제 도구 호출은 따로 해 봤습니다. .mcp.json의 명령·인자·환경변수를 그대로 읽어 서버를 띄우고, stdio로 initialize → notifications/initialized → tools/list → tools/call(browser_navigate) → browser_close 순서로 JSON-RPC를 보내는 node 스크립트(mcp_client.mjs)입니다. 윈도우에서 npx는 npx.cmd라서 spawn에 shell: true를 줬습니다. 전체 스크립트는 원자료에 있습니다.
node mcp_client.mjs 'C:/Users/User/AppData/Local/Temp/longtail_C2/proj' - --caps configinitialize (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",도구는 기본 26개였고, 설정 조회용 browser_get_config가 켜지는 --caps config를 붙였을 때 27개였습니다. browser_get_config가 보여 준 channel이 chrome입니다. 브라우저 다운로드 없이 페이지가 열린 이유가 이것이라고 보지만, 실제로 실행된 파일 경로는 확인하지 않았습니다(이 PC의 C:\Program Files\Google\Chrome\Application 아래에 153.0.8010.47 폴더가 있었습니다).
같은 파일(proj\test.html)을 세 가지 방법으로 열었습니다.
| 시도 | 서버 인자 | browser_navigate 결과 | 걸린 시간(서버 시작부터) |
|---|---|---|---|
A. file:///C:/…/proj/test.html | 기본(--headless --isolated) | isError=true, Error: Access to "file:" protocol is blocked. | 8.5초 |
B. 스크립트가 띄운 http://127.0.0.1:<포트>/test.html | 기본 | 성공, Page Title: longtail C2 test page | 4.3초 |
C. file:///C:/…/proj/test.html | 기본 + --allow-unrestricted-file-access | 성공, 같은 제목 | 3.7초 |
A의 오류 원문입니다.
### Error
Error: Access to "file:" protocol is blocked. Attempted URL: "file:///C:/Users/User/AppData/Local/Temp/longtail_C2/proj/test.html"B와 C의 응답에는 - [Snapshot](.playwright-mcp\page-2026-09-17T09-16-12-784Z.yml)처럼 스냅샷 파일 경로가 붙었고, 작업 폴더 아래 .playwright-mcp 폴더에 130바이트짜리 .yml이 생겼습니다.
- generic [active] [ref=e1]:
- heading "Hello from a local file" [level=1] [ref=e2]
- paragraph [ref=e3]: playwright-mcp check로컬 파일을 확인하는 용도라면 B처럼 로컬 HTTP로 여는 편이 기본 제한을 그대로 둡니다. C의 옵션은 도움말 설명대로 작업 폴더 밖 파일 접근까지 풀기 때문입니다.
4단계 — 지우기
$ 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은 {"mcpServers": {}}(22바이트)로 비었고, 제거 뒤 claude mcp list 출력에서 longtail_C2 또는 --isolated가 든 줄은 0개였습니다. %USERPROFILE%\.claude.json에서 longtail_C2 문자열도 0건이었습니다(내용은 열지 않고 건수만 셈). 실험이 끝난 뒤 임시 폴더 longtail_C2(1.5G)는 rm -rf로 지웠고, 남은 폴더는 없었습니다.
결과
| 단계 | 결과 |
|---|---|
claude mcp add … --scope project | 종료 코드 0, .mcp.json 338바이트 |
승인 전 list/get | ⏸ Pending approval |
--settings 승인 후 list/get | ✔ Connected |
initialize 응답 | 네 번 실행에서 2.5~7.4초 |
tools/list | 26개(--caps config 시 27개) |
| 기본 브라우저 | channel: "chrome", 임시 브라우저 폴더는 빈 채로 남음 |
file:// 열기 | 기본은 차단, --allow-unrestricted-file-access에서 성공 |
claude mcp remove | .mcp.json 22바이트, ~/.claude.json의 longtail_C2 문자열 0건 |
실패한 것
--settingsJSON을 PowerShell에서 역슬래시로 이스케이프한 첫 시도는Invalid JSON provided to --settings로 실패했습니다.- 첫 스크립트 실행은 서버가 3.2초에 끝났는데도 스크립트가 약 3분(183초) 뒤에야 끝났습니다. 요청마다 건 180초 제한 타이머가 node를 붙잡고 있었고, 타이머에
unref()를 붙인 뒤에는 서버 종료와 함께 끝났습니다. - 설치된 Chrome 버전을
chrome.exe --version으로 보려 했지만 버전 줄은 나오지 않고chrome.exe프로세스가 계속 떠 있었습니다. 그 프로세스(PID 하나)만 종료했고, 버전은 설치 폴더 이름으로만 확인했습니다.
확인하지 않은 것
- 대화형
claude의 승인 화면과/mcp화면, 대화 중 Claude가 도구를 부르는 모습. - 창이 뜨는(headed) 기본 모드. 이번에는
--headless만 썼습니다. - Chrome이 설치되지 않은 PC에서의 기본 동작. 전용 Chromium을 쓰는 경우는 Playwright 브라우저 실행 파일이 없을 때에 적었습니다.
--isolated없이 쓸 때 생기는 영구 프로필 폴더.local·user범위 추가, 명령 프롬프트(cmd.exe)에서의 입력,--extension모드.