Playwright MCP는 접근성 구조를 이용해 AI가 웹페이지를 탐색·입력·검증하도록 연결하는 서버입니다. 2026년 9월 10일 Windows 11에서 현재 설치 조건과 옵션을 확인하고, 레이블 기반 폼 자동화를 실제 화면과 영상으로 검증했습니다.
먼저 알아둘 핵심: MCP와 CLI는 쓰임이 다르다
Playwright MCP는 모델이 브라우저 화면의 픽셀 위치를 추측하게 하는 대신, 버튼·입력란·제목처럼 구조화된 접근성 정보를 읽고 동작하게 만듭니다. 예를 들어 “파란 버튼을 눌러라”보다 “이름이 작업 생성인 버튼을 눌러라”라는 방식으로 대상을 특정할 수 있습니다. 화면 배치가 조금 달라져도 접근 가능한 이름과 역할이 유지되면 같은 절차를 재사용하기 쉬운 이유입니다.
Microsoft의 Playwright MCP 공식 저장소는 MCP가 지속적인 브라우저 상태, 풍부한 페이지 구조 탐색, 반복적인 에이전트 작업에 적합하다고 설명합니다. 반면 코딩 에이전트가 많은 파일과 테스트를 다루는 상황에서는 CLI와 스킬 조합이 더 적은 도구 설명으로 동작해 효율적일 수 있다고 구분합니다. 따라서 무조건 MCP가 우월하다고 보기보다, 페이지를 계속 관찰하며 판단해야 하는지 또는 짧고 반복 가능한 명령이 필요한지부터 결정해야 합니다.
이번 글에서는 두 가지 사실을 분리해 확인했습니다. 첫째, 로컬 터미널에서 @playwright/mcp 0.0.80의 버전과 도움말을 실행해 설치 요구사항과 옵션 표면을 확인했습니다. 둘째, 별도의 로컬 브라우저 세션에서 같은 접근성 원칙을 적용해 이름이 있는 입력란·선택 목록·버튼을 찾고, 입력부터 결과 상태까지 재현했습니다. 실제 MCP 서버가 이번 화면 조작을 수행했다고 과장하지 않고, CLI 확인과 브라우저 상호작용 재현을 서로 다른 검증으로 기록합니다.
설치 전에 확인한 버전과 요구사항
검증 날짜: 2026년 9월 10일. 환경: Windows 11, Node.js v24.13.0, Chrome 기반 브라우저, 로컬 정적 웹 서버. 확인한 패키지: @playwright/mcp 0.0.80. 공식 package.json에는 Node.js 18 이상과 Apache-2.0 라이선스가 명시돼 있습니다. 이 글에서 확인한 Node 버전은 최소 요구사항보다 높지만, 모든 Node 18 환경의 주변 도구 조합까지 검증했다는 뜻은 아닙니다.
공식 기본 설정은 MCP 클라이언트가 npx로 @playwright/mcp@latest를 실행하는 형태입니다. 처음 기능을 살필 때는 최신 버전을 쓰기 편하지만, 팀 프로젝트나 자동화 서버에서는 오늘 성공한 작업이 내일 다른 버전으로 바뀌지 않도록 검증한 버전을 고정하는 편이 안전합니다. 이 글의 재현 기준 버전은 0.0.80이며, 독자가 실행하는 시점에는 공식 변경 기록과 자신의 클라이언트 문서를 다시 확인해야 합니다.
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--isolated"]
}
}
}
로컬에서 실행한 npx -y @playwright/mcp@0.0.80 --help는 정상 종료됐고, --isolated, --storage-state, --allowed-hosts, --allowed-origins, --blocked-origins, --browser, --headless, --viewport-size, 동작·탐색 시간 제한 등의 옵션을 표시했습니다. 설치 성공은 도움말이 뜬 것만으로 끝나지 않습니다. 실제 MCP 클라이언트에서 서버가 연결됐는지, 필요한 도구가 노출됐는지, 테스트 사이트에서 읽기와 쓰기 동작이 기대 범위 안에서 실행되는지까지 확인해야 합니다.
브라우저 권한과 보안 경계를 먼저 정하는 방법
처음 연습할 때는 --isolated를 권장합니다. 이 모드는 브라우저 프로필을 메모리에 두고 세션이 끝나면 저장 상태를 남기지 않기 때문에, 개인 계정이 로그인된 일상 브라우저와 테스트를 분리하기 쉽습니다. 로그인 상태가 꼭 필요하다면 전용 테스트 계정과 별도 사용자 데이터 디렉터리를 사용하고, 결제·관리자·개인 메일처럼 영향이 큰 계정으로 첫 실험을 시작하지 않는 편이 좋습니다.
--allowed-origins 이름만 보고 완전한 보안 방화벽으로 오해하면 안 됩니다. 공식 README는 이 옵션이 신뢰할 출처를 제한하는 데 쓰이지만 보안 경계 역할을 하지 않으며 리디렉션에는 영향을 주지 않는다고 명시합니다. 차단 목록도 목록에 없는 모든 요청을 자동 차단하는 구조가 아닐 수 있습니다. 중요한 환경에서는 브라우저 옵션 하나에 의존하지 말고 테스트 계정, 네트워크 제한, 최소 권한, 실행 후 기록 검토를 함께 사용해야 합니다.
파일 접근 역시 최소 범위가 원칙입니다. 기본적으로 작업공간 밖 파일과 file:// 탐색은 제한되며, --allow-unrestricted-file-access는 명확한 이유가 없으면 켜지 않는 편이 좋습니다. 비밀값은 프롬프트나 캡처에 직접 적지 말고 전용 비밀 파일이나 실행 환경에서 주입하되, 출력 로그와 스크린샷에 다시 노출되지 않는지 확인합니다. 이번 실습 화면에는 이메일, 쿠키, API 키, 계정명, 실제 서비스 데이터가 들어가지 않았습니다.
자동화가 눌러도 되는 버튼의 범위도 정해야 합니다. 검색·필터·초안 저장처럼 되돌리기 쉬운 작업과 결제·삭제·배포·메시지 전송처럼 외부 상태를 바꾸는 작업은 같은 수준으로 다루면 안 됩니다. 영향이 큰 동작은 실행 직전 사람이 대상과 값을 확인하거나, 별도 승인 단계가 통과해야만 진행되도록 설계해야 합니다.
직접 실행한 폼 자동화 검증 조건
실습용 페이지는 HTML, CSS, JavaScript로 만든 로컬 화면이며 외부 API를 호출하지 않습니다. 입력값: “Playwright MCP 폼 자동화 검증”. 선택값: 우선순위 “높음”. 동작 순서: 작업 이름 입력 → 우선순위 선택 → 작업 생성 → 검증 실행. 성공 조건: 결과 배지가 “생성됨”으로 바뀌고 입력한 제목과 우선순위가 결과 카드에 표시된 뒤, 세 단계 로그가 모두 완료되고 배지가 “통과”로 바뀌는 것입니다.
먼저 페이지의 구조화된 스냅샷에서 “작업 이름” 텍스트 상자, “우선순위” 콤보 상자, “작업 생성” 버튼이 각각 정확히 한 개씩 존재하는지 확인했습니다. 대상이 0개라면 레이블이나 페이지 로딩을 다시 살펴야 하고, 2개 이상이면 더 구체적인 영역이나 이름을 사용해야 합니다. 고유성을 확인하지 않고 첫 번째 요소를 누르는 방식은 화면이 바뀌었을 때 잘못된 대상을 조작할 위험이 큽니다.
세 요소가 각각 한 개임을 확인한 뒤 작업 이름을 입력하고 “높음”을 선택한 다음 생성 버튼을 눌렀습니다. 결과 영역에는 같은 작업 이름과 선택값이 표시됐고 상태 배지는 “대기”에서 “생성됨”으로 바뀌었습니다. 검증 실행 버튼도 활성화됐습니다. 이 단계에서 관찰한 결과는 텍스트 비교가 가능하므로 화면 색상만으로 성공을 판정하지 않았습니다.
영상은 같은 세션에서 약 0.3초 간격으로 남긴 실제 화면 12장을 시간 순서대로 연결했습니다. 중간 프레임에서는 첫 단계가 완료되고 둘째 단계가 진행 중인 상태가 보이며, 마지막 확인에서는 상태 “통과”, 완료 로그 3개, 입력값과 생성된 제목의 일치, 우선순위 “높음”을 읽었습니다. 화면을 재현하기 위한 로컬 페이지이므로 실제 서비스의 로그인이나 데이터 변경을 성공했다고 의미하지는 않습니다.
접근 가능한 이름으로 재현하는 순서
첫 단계는 페이지가 완전히 준비됐는지 확인하는 것입니다. 제목이나 핵심 영역이 나타날 때까지 기다린 뒤 현재 구조를 읽습니다. 이어서 역할이 textbox이고 접근 가능한 이름이 “작업 이름”인 요소를 찾습니다. 레이블의 for 값과 입력란의 id가 연결돼 있으면 화면을 보는 사람뿐 아니라 자동화 도구와 보조기술도 목적을 이해하기 쉬워집니다.
둘째 단계에서는 콤보 상자를 이름으로 찾고 표시 문구가 아니라 실제 선택 결과가 “높음”인지 확인합니다. 셋째 단계에서는 “작업 생성” 버튼이 정확히 하나이고 활성화돼 있는지 확인한 다음 클릭합니다. 클릭 직후에는 단순히 오류가 없었다는 사실이 아니라 결과 카드의 제목, 우선순위, 상태 배지를 각각 읽어 입력과 일치하는지 비교합니다.
넷째 단계에서는 “검증 실행” 버튼이 활성화된 뒤 클릭하고, 최종 상태가 “통과”가 될 때까지 제한된 시간 안에서 기다립니다. 대기 시간을 무조건 길게 고정하면 실패를 늦게 발견하고, 너무 짧게 잡으면 정상적인 비동기 작업을 실패로 오판합니다. 서비스가 제공하는 완료 신호나 상태 요소를 기준으로 기다리고, 상한 시간을 넘으면 현재 화면과 오류 메시지를 함께 남기는 편이 좋습니다.
마지막 단계는 결과 검증입니다. 이번 실습에서는 완료 로그 수가 3개인지, 각 로그 문구가 예상 순서인지, 입력란 값과 생성된 카드 제목이 같은지, 우선순위와 상태가 기대값인지 확인했습니다. 이처럼 입력·행동·관찰 결과를 한 묶음으로 기록해야 나중에 화면이 바뀌었을 때 어느 부분이 깨졌는지 찾을 수 있습니다.
자주 실패하는 조건과 해결 순서
요소를 찾지 못하는 경우: 화면에 글자가 보이더라도 실제 레이블이 입력란과 연결되지 않았을 수 있습니다. 현재 구조를 다시 읽고 역할과 이름을 확인합니다. 이름이 자주 바뀌는 번역 문구라면 안정적인 테스트 ID를 사용할 수 있지만, 사용자에게 보이는 레이블과 접근성 품질을 포기하는 핑계가 되어서는 안 됩니다.
같은 이름의 버튼이 여러 개인 경우: 첫 번째 버튼을 임의로 고르지 말고 “검증 결과”처럼 의미 있는 영역 안으로 탐색 범위를 좁힙니다. 대상 수가 정확히 하나인지 확인한 뒤 행동합니다. 모달 창이나 모바일 메뉴가 겹쳐 같은 이름이 반복되는 상황도 있으므로 현재 보이는 상태를 함께 검사해야 합니다.
클릭 뒤 결과가 바뀌지 않는 경우: 네트워크 요청, 비동기 처리, 애니메이션 시간을 확인하고 완료 상태를 나타내는 텍스트나 요소를 기다립니다. 시간 제한을 무작정 늘리기 전에 브라우저 콘솔 오류, 요청 실패, 버튼 비활성 상태, 잘못된 입력값을 기록합니다. 재시도는 일시적인 네트워크 오류처럼 안전한 조건에만 제한적으로 적용해야 하며, 결제나 생성 요청을 중복 실행해서는 안 됩니다.
브라우저 연결이 충돌하는 경우: 공식 문서는 지속 프로필을 같은 작업공간에서 동시에 여러 인스턴스가 사용할 때 충돌할 수 있다고 안내합니다. 병렬 작업이 필요하면 각 실행에 --isolated를 사용하거나 서로 다른 사용자 데이터 디렉터리를 지정합니다. 이미 열려 있는 개인 브라우저와 자동화용 브라우저를 섞지 않으면 세션 잠금과 계정 혼동을 줄일 수 있습니다.
한계와 주의사항
이번 검증은 로컬 정적 페이지에서 단일 폼의 입력과 상태 변화를 확인한 사례입니다. 복잡한 로그인, 교차 출처 요청, 파일 업로드, 다운로드, 팝업, 결제, 관리자 권한, 실제 서비스의 이용약관까지 검증하지 않았습니다. 로컬 화면에서 성공한 선택자와 대기 방식이 모든 사이트에서 그대로 작동한다고 단정할 수 없습니다.
접근성 스냅샷은 구조화된 상호작용에 강하지만 캔버스, 지도, 그림만으로 구성된 화면처럼 의미 있는 DOM 정보가 부족한 인터페이스에서는 추가 방법이 필요할 수 있습니다. 반대로 스크린샷은 시각적 결과를 설명하는 증거가 되지만 버튼의 역할이나 현재 값을 안정적으로 판정하는 유일한 근거로 쓰기 어렵습니다. 구조 검증과 시각 증거를 목적에 맞게 함께 사용해야 합니다.
패키지 옵션과 버전은 바뀔 수 있습니다. 이 글은 2026년 9월 10일의 공식 저장소와 0.0.80 도움말을 기준으로 작성했습니다. @latest를 사용하는 독자는 실행 당일의 요구 Node 버전, 새 옵션, 폐기된 옵션, 보안 안내를 다시 확인해야 합니다. 또한 자동화 대상 사이트가 봇 접근이나 자동 조작을 제한할 수 있으므로 서비스 약관과 권한을 먼저 확인해야 합니다.
결론: 작은 읽기·입력·검증부터 시작한다
Playwright MCP를 처음 설정할 때는 로그인된 개인 브라우저로 복잡한 업무를 바로 자동화하기보다, 격리된 세션과 민감정보가 없는 페이지에서 시작하는 편이 안전합니다. 요소를 역할과 이름으로 찾고, 대상 수를 확인하고, 행동 뒤 상태를 읽고, 실패 조건을 기록하는 네 단계를 지키면 단순한 화면 클릭보다 재현성이 높아집니다.
앞서 만든 작은 웹앱이 어떻게 요구사항과 실화면 검증으로 이어지는지 궁금하다면 바이브코딩 타이머 실전 글을 함께 볼 수 있습니다. 이 사이트가 공식 자료와 직접 실행 결과를 구분하는 기준은 dea:no 소개 페이지에 정리했습니다. 다음 실습에서는 동일한 방식으로 오류가 발생한 요청을 기록하고 안전한 재시도 조건을 검증할 예정입니다.