Skip to main content
Glama

pw-pool

Playwright MCP용 에이전트 세션당 브라우저 하나.

@playwright/mcp는 서버 하나와 브라우저 하나를 가정합니다. 한 머신에서 두 개의 에이전트 세션을 실행하면 프로필 잠금에 실패하거나, 공유 브라우저를 쓸 때 같은 탭 공간에서 서로의 페이지를 탐색하게 됩니다. pw-pool은 세션마다 자체 Chrome을 부여하고 어느 것이 누구 것인지 기억합니다.

프로필

Chrome은 "사람"에 관한 모든 것을 프로필 디렉터리(--user-data-dir)에 보관합니다: 쿠키, 로컬 스토리지, 저장된 비밀번호, 열린 탭. 이것이 실행 사이에 로그인 상태를 유지해 주는 것입니다. 한 번에 하나의 Chrome만 프로필을 사용할 수 있습니다. pw-pool은 세션마다 프로필 하나를 만들고 실행 사이에 유지하며, 템플릿 — 이미 로그인된 프로필의 로그인 파일을 복사한 것 — 에서 새 프로필을 시드할 수 있으므로 새 세션이 누구와도 브라우저를 공유하지 않고 로그인된 상태로 시작합니다.

Related MCP server: antigravity-browser

설치

Node 22+와 macOS 또는 Linux가 필요합니다.

git clone https://github.com/ckarnell/pw-pool && cd pw-pool
npm install            # pins @playwright/mcp and patches it
node bin/pw-pool.js install    # checks the setup; offers to download Chrome for Testing if missing

또는 전역 설치로 pw-mcp와 pw-pool을 PATH에 넣습니다: npm install -g github:ckarnell/pw-pool.

그런 다음 pw-mcp를 Playwright MCP 명령으로 사용합니다. Claude Code(~/.claude.json 또는 프로젝트 .mcp.json):

"playwright": { "type": "stdio", "command": "pw-mcp" }

(또는 PATH에 없는 클론의 경우 "command": "node", "args": ["/path/to/pw-pool/bin/pw-mcp.js"]).

다른 MCP 플래그(--caps, --output-dir, …)는 args에 추가할 수 있으며 그대로 전달됩니다. --headless는 풀의 실행에 적용됩니다. --cdp-endpoint, --user-data-dir, --isolated, --browser는 경고와 함께 무시되는데, 풀이 브라우저를 선택하기 때문입니다.

기본적으로 브라우저는 Playwright의 Chrome for Testing입니다. 머신에 이미 설치된 Chrome을 사용하려면: pw-pool config set channel '"chrome"'(chrome-beta, chrome-canary, msedge도 가능), 또는 명시적 경로의 config.chrome.

선택 사항으로, 모든 세션을 로그인된 상태로 시작하려면:

pw-pool template save main --from ~/path/to/a/signed-in/user-data-dir
pw-pool config set defaultTemplate '"main"'

세션이 열려 있는 동안 전환

MCP 구성은 언제든 변경할 수 있습니다. 실행 중인 것에는 영향이 없습니다. MCP 서버는 세션당 한 번 시작되므로 이미 열린 세션은 재시작할 때까지 이전 서버와 브라우저를 유지합니다. 변경 후 시작되는(또는 재시작되는, 예: claude --resume) 세션은 pw-pool을 사용합니다. 작동하는 순서:

  1. 오늘 사용하는 브라우저에서 템플릿을 저장하고 기본값으로 설정(위 참조)하여 새 브라우저가 로그인된 상태가 되게 합니다.

  2. MCP 항목을 pw-mcp로 변경합니다.

  3. 다른 것은 없습니다. 이전 세션은 계속되고, 새 세션은 자체 브라우저를 얻습니다.

돌아가려면 이전 MCP 항목을 복원합니다. pw-pool이 시작한 브라우저는 유휴 TTL 후에 정리되거나 pw-pool stop all로 즉시 정리됩니다. 이전에 실행한 브라우저(예: 고정 CDP 포트의 공유 브라우저)는 pw-pool이 건드리지 않으며 옆에서 계속 실행될 수 있습니다.

작동 방식

session A ─▶ pw-mcp ─▶ registry ─▶ Chrome :9300, profiles/A/ ◀─ @playwright/mcp --cdp-endpoint
session B ─▶ pw-mcp ─▶ registry ─▶ Chrome :9301, profiles/B/ ◀─ @playwright/mcp --cdp-endpoint
  • pw-mcp는 MCP 서버 명령으로 npx @playwright/mcp를 대체합니다. 호출하는 세션이 무엇인지 알아내고, 풀에서 해당 세션의 브라우저를 가져와(필요하면 실행) 번들된 @playwright/mcp를 CDP로 그 브라우저에 대해 실행합니다. Stdio는 그대로 통과합니다.

  • MCP가 종료되어도 브라우저는 유지됩니다. 재개된 세션은 탭까지 포함해 같은 브라우저를 얻습니다.

  • 열린 탭이 없고 활성 세션이 없는 브라우저는 즉시 중지됩니다. 탭이 남아 있는 브라우저는 세션 종료 후 1시간 뒤에 중지됩니다(탭 저장됨). 이후 시작 시 같은 프로필로 다시 실행되고 탭이 다시 열립니다. 사용되지 않은 프로필은 30일 후 삭제됩니다. 활성 세션은 임대를 보유하며 절대 정리되지 않습니다.

  • 창을 띄우는 일은 없습니다: 브라우저는 창 없이 시작되고 탭은 백그라운드에서 열립니다. 번들된 MCP는 같은 이유로 두 줄 패치를 포함합니다(포커스 참조).

데몬 없음. 상태는 ~/.pw-pool/ 아래의 JSON 레지스트리이며 잠금으로 보호됩니다.

어느 세션이 어느 것인지

pw-mcp는 세션당 안정적인 키가 필요합니다. 순서:

  1. --key / PW_POOL_KEY — 명시적. 모든 하네스가 설정할 수 있습니다. PW_POOL_NAME은 창에 라벨을 붙입니다.

  2. CLAUDE_CODE_SESSION_ID — Claude Code(2.1.239+)가 MCP 서버의 환경에 설정합니다.

  3. ~/.claude/sessions/<parent pid>.json — Claude Code가 세션 id, 이름, cwd를 여기에 씁니다.

  4. 부모 pid — 폴백. 임대가 끝나면 브라우저가 삭제됩니다.

같은 키, 같은 브라우저. claude --resume는 세션 id를 유지하므로 브라우저를 되찾습니다.

템플릿

pw-pool template save <name> --from <dir>는 프로필의 로그인 파일(쿠키, 로컬 저장소, IndexedDB, 저장된 비밀번호, 기본 설정 — 몇 MB, 캐시 없음)을 복사합니다. 새 세션의 프로필은 --template <name>, PW_POOL_TEMPLATE, 또는 config.defaultTemplate에서 생성 시 한 번 시드됩니다. 그 후 각 프로필은 독립적으로 진화합니다. --fresh는 빈 프로필을 강제합니다.

템플릿과 프로필에는 실제 자격 증명이 포함됩니다. ~/.pw-pool/을 저장소에 넣지 마세요. 템플릿은 특정 시점의 복사본입니다. 새로 로그인한 것이 있으면 다시 저장하세요.

CLI

pw-pool install [--yes]            first-time setup; asks before downloading Chrome
pw-pool ls                         registered browsers: key, name, port, pid, status, tabs, leases
pw-pool cdp [key] [--ensure]       CDP endpoint of a session's browser (default: the calling session)
pw-pool tabs [key]
pw-pool gc [--force] [--dry-run]   reap stale leases, idle browsers, old profiles
pw-pool stop <key|all> [--rm]      stop a browser (tabs saved); --rm also deletes its profile
pw-pool template save <name> [--from <dir>] | ls | rm <name>
pw-pool config [get <key> | set <key> <json>]
pw-pool doctor

<key>는 전체 키, 고유 접두사, 또는 세션 이름입니다. pw-pool cdp --ensure는 스크립트가 세션의 MCP와 같은 브라우저를 구동하게 합니다. 모든 pw-mcp 시작은 gc를 실행합니다. 세션이 드문 머신에서는 cron이나 launchd에서 pw-pool gc를 실행하세요.

구성은 ~/.pw-pool/config.json(pw-pool config)에 있습니다: portRange [9300, 9399], idleTtlHours 1, profileTtlDays 30, defaultTemplate, sourceProfile, chrome, channel, headless, sandbox(Playwright의 chromiumSandbox처럼 끔), profileTheme, windowCascade, windowSize, extraChromeArgs, launchTimeoutMs. PW_POOL_HOME은 전체 상태 디렉터리를 이동합니다. PW_POOL_HEADLESS=1은 브라우저를 헤드리스로 실행합니다(서버, 컨테이너).

profileTheme: true는 각 브라우저의 툴바를 키에서 파생된 안정적인 색으로 물들여, 여러 풀 창을 화면에서 쉽게 구분할 수 있게 합니다(macOS Cmd-Tab은 여전히 인스턴스당 아이콘 하나를 표시합니다. 이것은 창 자체를 색칠합니다). 고정 "R,G,B"는 모든 풀 브라우저를 같은 색으로 테마합니다.

포커스

macOS에서 두 가지가 Chrome 앱을 활성화하고 머신을 사용하는 사람의 포커스를 빼앗습니다: 시작 시 생성된 창, 그리고 포그라운드에서 생성된 탭. pw-pool은 --no-startup-window로 Chrome을 실행하고 CDP의 background: true로 탭을 엽니다. @playwright/mcp에는 이 옵션이 없으므로 scripts/patch-focus.js가 번들된 복사본의 두 줄을 변경합니다(browser_tabs new → 백그라운드 탭, browser_tabs select → bringToFront 없음). 패치는 npm install 시 적용됩니다. pw-pool doctor가 확인합니다. PW_MCP_FOREGROUND_TABS=1은 원래 동작을 복원합니다.

패치의 범위 밖인 경우가 하나 있습니다: 페이지 자체가 팝업을 열 때(window.open 또는 클릭 시 target="_blank" 링크) macOS는 브라우저를 활성화하여 표시합니다. 일반 Chrome과 동일합니다. 브라우저는 기본적으로 헤디드이며 @playwright/mcp와 일치합니다. 공유 머신에서 포커스 도용이 문제가 된다면 헤드리스로 실행하세요: pw-pool config set headless true, PW_POOL_HEADLESS=1, 또는 세션별로 pw-mcp --headless(그리고 기본이 헤드리스일 때 헤디드를 강제하는 --headed). 헤드리스는 스냅샷과 스크린샷에 대해 동일하게 렌더링됩니다.

문제 해결

  • browser_evaluate 직후 MCP가 연결 해제됩니다("Connection closed"). 결과가 클라이언트의 메시지당 제한(Claude Code에서 16MB)보다 커서 클라이언트가 연결을 닫은 것입니다. 이는 pw-pool 특유의 문제가 아닙니다. 클라이언트는 몇 초 내에 서버를 재시작하고 pw-mcp는 탭 포함한 같은 브라우저에 다시 연결합니다. 도구를 다시 호출하고 더 작은 값을 반환하세요. Claude Code는 서버 로그를 ~/Library/Caches/claude-cli-nodejs/<project>/mcp-logs-playwright/에 유지합니다.

  • "Chrome exited during startup" 또는 "did not answer": 오류는 ~/.pw-pool/logs/<key>.chrome.log의 끝부분을 인용합니다. 일반적인 원인: Linux에서 디스플레이 없음(headless 또는 Xvfb 사용), 실행할 수 없는 바이너리(pw-pool doctor).

  • 브라우저가 아무에게도 속하지 않는 것 같습니다: pw-pool ls는 임대를 표시합니다. !는 종료된 보유자를 표시합니다. pw-pool gc가 이를 정리합니다. pw-pool stop <key>는 확실한 브라우저를 중지합니다.

개발

npm test               # unit tests (no browser needed)
npm run test:e2e       # real browsers, throwaway pool home: isolation, reattach, concurrency, recovery, templates
npm run test:docker    # the same on Linux in a container

@playwright/mcp 버전은 고정되어 있습니다. 올리려면 버전을 변경하고 npm install을 실행한 후, 설치가 실패하면 scripts/patch-focus.js를 수정하세요(번들이 형태가 바뀌었습니다).

릴리스

게시는 npm 신뢰 게시(GitHub Actions의 OIDC)를 사용합니다 — 토큰 없음. npmjs.com에서 일회성 설정: 패키지의 설정 → 신뢰 게시자 → 이 저장소의 publish.yml 워크플로우. 그 후 태그로 릴리스: npm version patch && git push --follow-tags. 워크플로우는 테스트와 npm publish --provenance를 실행합니다. (패키지가 존재하기 전의 첫 게시는 로컬에서 npm publish --access public --auth-type=web으로 한 번 수행됩니다.)

라이선스

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    Enables agents to sign into websites through a real browser without exposing passwords, keeping cookies in a local Chrome profile and providing tools for browsing and managing authenticated sessions.
    5
    1
    MIT