게임 페이지는 이미 만들어져 브라우저에서 열립니다. 보드가 그려지고 말이 움직이며 "새 게임" 버튼도 있습니다. 하지만 에이전트는 이 페이지를 한 번도 본 적이 없습니다. 파일의 텍스트만 다뤘고, 브라우저를 실행하고 결과를 확인한 사람도, 그 결과를 에이전트에게 설명한 사람도 모두 여러분이었습니다. Playwright는 바로 이 간극을 메웁니다. 에이전트가 같은 페이지를 열고, 필요한 요소를 찾아 클릭한 다음 무엇이 달라졌는지 읽습니다.

아래에서는 체스 페이지를 예로 들어 페이지 열기, 살펴보기, 요소 선택, 동작 수행, 새 상태 읽기 순서로 이 과정을 알아봅니다. 여기서는 서버 설치와 연결 방법을 반복하지 않습니다. Playwright를 아직 연결하지 않았다면 프로젝트 README에 안내가 있습니다.

페이지 열기

Connected라는 표시가 증명하는 것은 무엇일까요?
딱 한 가지입니다. Claude Code가 Playwright 서버와 연결해 도구 목록을 받았다는 뜻입니다. 이 시점에는 아직 열린 페이지가 하나도 없고, 브라우저조차 실행되지 않았을 가능성도 큽니다. Connected는 연결 상태를 말할 뿐, 게임이 실행 중이거나 에이전트가 게임을 볼 수 있다는 뜻은 아닙니다.

현재 상태는 /mcp 명령으로 확인할 수 있습니다. 연결된 서버와 각 서버가 제공하는 기능이 표시됩니다. 이제 실제 작업을 시작하려면 먼저 페이지 주소가 필요합니다.

로컬 게임은 디스크의 파일로 열거나 로컬 서버에서 실행할 수 있습니다. 그런 서버의 포트도 항상 같지는 않습니다. 무엇으로 실행했느냐에 따라 5173, 8000, 3000 등으로 달라집니다. 주소는 실제로 출력된 곳에서 가져오면 됩니다. 실행 명령의 출력이나 방금 게임을 확인한 브라우저의 주소 표시줄을 보세요. 포트를 짐작하면 빈 페이지가 열리거나 엉뚱한 프로젝트에 연결될 수 있고, 도구의 응답만 보고 이를 늘 알아차릴 수 있는 것도 아닙니다.

페이지 열기는 별도의 호출인 browser_navigate로 수행하며, 매개변수는 url 하나입니다. 에이전트에게는 평범한 말로 요청하면 됩니다.

Playwright로 http://localhost:5173/ 을 열고
열린 페이지의 제목을 보여 주세요.

페이지를 연 뒤에는 두 가지를 확인하세요. 에이전트가 실제로 방문한 주소와 페이지 이름입니다. 잠깐이면 확인할 수 있고, 잘못된 곳에서 일련의 동작을 수행하는 일을 막아 줍니다. 로컬 프로젝트를 몇 개 동시에 실행 중이고 그중 하나도 localhost에 응답한다면 특히 중요합니다.

여러분의 브라우저 창이 아닙니다

Playwright는 별도의 브라우저를 실행합니다. 여러분의 탭, 확장 프로그램, 이미 로그인한 계정은 그쪽으로 옮겨지지 않습니다. 기본적으로 평소 쓰는 브라우저와 분리된 프로필을 사용합니다. 로컬 게임에는 문제가 없지만, "내가 로그인한 사이트도 알아서 열겠지"라는 기대는 저절로 충족되지 않습니다.

페이지에서 에이전트가 보는 것

열린 페이지를 살펴보는 방법은 세 가지이며, 각각 전혀 다른 정보를 돌려줍니다.

알고 싶은 것도구응답으로 받는 것
화면이 어떻게 보이는지browser_take_screenshot페이지 이미지
페이지가 무엇으로 구성됐는지browser_snapshot요소의 텍스트 트리: 역할, 이름, 요소 참조
특정 값 읽기browser_evaluate페이지에서 계산한 짧은 표현식의 결과
한 페이지에서 얻는 세 가지 데이터: 이미지, 요소 설명, 속성값페이지체스 게임스크린샷 → 겉모습browser_take_screenshot보드가 어떻게 보이나요?스냅샷 → 요소browser_snapshot"새 게임" 버튼은 어디 있나요?표현식 → 값browser_evaluatedata-turn에 무엇이 기록되어 있나요?
페이지에 관해 묻고 싶은 내용에 따라 관찰 방법을 고릅니다

세 가지 방법 모두 같은 페이지에서 시작하지만 서로 다른 데이터를 돌려줍니다. 스냅샷은 버튼을 찾는 데 도움이 되지만, data-turn 값은 따로 읽어야 합니다. 보드 이미지만으로는 HTML 속성을 알 수 없습니다.

스크린샷은 이미지입니다. "어떻게 보이는지", "각 요소가 어디 있는지" 같은 질문에는 아주 유용하지만, 그 자체로 browser_click에 사용할 요소 참조를 제공하지는 않습니다. Playwright MCP의 기본 모드에서는 접근성 스냅샷을 이용해 동작을 수행합니다. 좌표를 클릭하는 기능은 해당 도구를 별도로 활성화했을 때 쓸 수 있습니다.

접근성 스냅샷은 요소를 설명하는 텍스트입니다. 페이지를 구성하는 요소의 역할(버튼, 링크, 입력 필드), 이름, 나중에 요소를 지정할 때 쓸 참조가 목록으로 나옵니다. 에이전트는 이 정보를 바탕으로 클릭합니다. 예를 들어 버튼은 대략 다음처럼 표시됩니다.

- button "새 게임" [ref=e12]
- button "수 되돌리기" [ref=e13]

실제 도구 출력이 아니라 형식을 이해하기 위한 예시입니다. 정확한 형식은 서버 버전에 따라 다르며, 이 글을 위해 굳이 실행해 보지는 않겠습니다. 여기서 중요한 것은 구두점이 아니라 사실 하나입니다. 버튼은 글자가 적힌 사각형이 아니라 역할, 이름, 참조를 담은 한 줄의 문자열로 에이전트에게 전달됩니다.

여기서 자주 헷갈리는 부분이 있습니다. 우리 게임에서 누구 차례인지 알려 주는 data-turn 표시는 접근성 스냅샷에 포함되지 않습니다. 스냅샷은 페이지 마크업이 아니라 요소의 역할, 이름, 상태, 참조를 바탕으로 만들어집니다. 임의의 data 속성은 이 목록에 들어가지 않습니다. 페이지가 해당 값을 화면에 보이는 텍스트로도 출력하면 스냅샷에 그 텍스트가 나타날 수는 있습니다. 하지만 이는 페이지 텍스트이지 속성을 직접 읽은 결과가 아닙니다. 두 가지를 혼동하지 마세요.

이런 값은 browser_evaluate 도구로 별도 작업을 수행해 읽습니다. 페이지 컨텍스트에서 짧은 표현식을 실행하고 결과를 반환합니다. 단순한 읽기가 아니라 페이지에서 코드를 실행하는 것이므로, 에이전트가 실행 전에 권한을 요청할 때도 있습니다. 표현식은 에이전트가 직접 작성하겠지만 대략 이런 형태입니다.

// 차례 표시가 있는 요소를 찾아 값을 반환합니다
() => document.querySelector('[data-turn]')?.getAttribute('data-turn') ?? null
스냅샷과 마크업은 다릅니다

접근성 스냅샷은 페이지 마크업 전체를 복사한 것이 아니라 필요한 내용을 추린 것입니다. 요소를 알아보고 클릭하는 데 필요한 정보는 있지만 모든 정보가 담기지는 않습니다. 따라서 "에이전트가 스냅샷을 만들었다"와 "에이전트가 모든 속성을 읽었다"는 서로 다른 말이며, 앞의 사실만으로 뒤의 결론을 내릴 수 없습니다.

에이전트는 요소를 어떻게 고를까요?

좌표를 기준으로 클릭하면 왜 버튼을 빗나갈 때가 있을까요?
좌표는 버튼이 아니라 화면상의 한 지점을 가리키기 때문입니다. 창 크기를 바꾸거나 사이드 패널을 접거나 글꼴 크기를 조정하거나, 페이지 위쪽에 한 줄이 추가되면 그 지점은 그대로인데 버튼은 자리를 옮깁니다. 클릭 동작 자체는 정상적으로 실행되지만, 빈 곳을 누르게 됩니다.

그래서 기본 요소 선택 방식은 다릅니다. browser_click 도구에서 중요한 필드는 두 가지입니다. element는 "새 게임 버튼"처럼 사람이 이해할 수 있는 설명으로, 에이전트가 무엇을 누르려는지 여러분이 알 수 있게 해 줍니다. target은 스냅샷에 있는 요소 참조나 고유한 선택자입니다. 여기서는 스냅샷의 참조로 요소를 고르는 방법을 살펴봅니다. 참조는 이를 가져온 스냅샷에 연결되어 있으므로, 클릭은 해당 요소를 대상으로 합니다. 텍스트 입력도 같은 방식이며, 도구 이름은 browser_type이고 요소 설명에 입력할 텍스트를 더합니다.

안정적인 것은 참조 자체가 아니라 요소를 찾는 방법입니다. 역할과 이름의 조합은 꽤 일정합니다. 디자이너가 버튼을 화면 반대편으로 옮겨도 "새 게임" 버튼은 여전히 "새 게임" 버튼입니다. 에이전트는 이 조합으로 새 스냅샷에서 필요한 요소를 다시 찾아 최신 참조를 가져옵니다. 그래서 이 글의 뒷부분에서도 "동작한 뒤 다시 확인하세요"라는 규칙이 되풀이됩니다.

보드의 칸은 조금 까다롭습니다. 64칸 모두 역할이 같기 때문입니다. 이때는 앱이 제공하는 표시가 도움이 됩니다. 칸마다 e2나 e4 같은 고유 이름이 있으면 정확히 지정할 수 있습니다. 스냅샷의 칸에 이름이 하나도 없다면 역할과 이름만으로는 원하는 칸을 고를 수 없습니다. 마크업에 다른 고유한 표시가 있는지 확인하거나 사용할 수 있는 좌표 도구를 써야 합니다.

Playwright MCP에는 좌표 도구도 있지만 기본 구성에서는 꺼져 있으며 별도로 활성화해야 합니다. canvas처럼 다른 방법으로 요소를 찾을 수 없는 경우를 위한 기능입니다. 기본 구성에는 이 도구가 없으니 이미지 하나만 보고 동작할 방법도 실제로 없습니다. 이 섹션 앞부분에서 스크린샷에 관해 주의를 준 것도 바로 이 때문입니다.

동작과 새로운 상태

작업 흐름: 새 스냅샷, 요소 선택, 동작 수행, 새 상태 읽기, 다음 동작 전 스냅샷으로 돌아가기1. 최신 스냅샷페이지에 무엇이 있나요?2. 요소 선택역할과 이름 → 참조현재 스냅샷에서 가져오기3. 동작클릭 또는 텍스트 입력4. 새 상태스냅샷, 필요하면속성 읽기다음 동작은 새 데이터에 기반합니다
동작 후에는 다시 관찰 단계로 돌아갑니다

왼쪽의 화살표가 순환을 완성합니다. 다음 동작 전에 에이전트는 최신 페이지 설명을 사용합니다. 이전 동작의 응답에 새 스냅샷이 포함되어 있다면 그 정보를 활용해도 됩니다. 클릭이 실행됐다는 사실만으로 원하는 변화가 일어났다고 확인할 수는 없습니다.

전체 과정을 한 번에 요청할 수 있는 순서로 정리해 보겠습니다. 다섯 단계이며, 각 단계 뒤에 무엇이 보여야 하는지 분명합니다. 보드의 칸에 이전 섹션에서 본 e2와 e4 같은 이름이 붙어 있다고 가정합니다. 이름이 없다면 4단계에서 칸을 확실히 지정할 다른 방법이 필요합니다.

단계에이전트의 동작확인할 내용
1게임 주소를 엽니다페이지 제목, 보드 표시
2"새 게임" 버튼을 누릅니다말이 시작 위치에 놓임
3data-turn을 읽습니다white
4페이지 인터페이스에서 e2-e4 수를 둡니다폰이 두 칸 이동함
5data-turn과 e4에 놓인 말을 다시 읽습니다black, e4에 흰 폰
e2-e4 수 확인: 수를 두기 전 data-turn은 white이고 e2에 폰이 있습니다. 둔 뒤에는 black, 빈 e2, e4의 흰 폰을 기대하며 다시 읽은 값으로 결론을 냅니다수를 두기 전data-turn: whitee2: 흰 폰e4: 비어 있음수를 둔 뒤 기대 상태data-turn: blacke2: 비어 있음e4: 흰 폰e2-e4다시 읽고 비교하기기대한 값과 일치하나요?
차례 변경과 폰의 위치를 확인합니다

왼쪽에는 처음 상태가, 오른쪽에는 수를 둔 뒤 기대하는 결과가 표시되어 있습니다. 아래 블록은 검증을 통해 두 상태를 연결합니다. 에이전트가 차례 표시와 말의 위치를 다시 읽고 값을 비교합니다. 더 정확히 확인하려면 시작 칸인 e2가 비었는지도 살펴보세요. white가 black으로 바뀌었다고 해서 폰이 e4에 도착했다고 확인되는 것은 아닙니다.

data-turn은 특정 앱이 정한 약속이라는 점을 분명히 해 두겠습니다. 페이지 작성자가 이 표시를 제공하기로 했기 때문에 읽을 수 있습니다. Playwright가 이 표시를 만들거나 어디선가 가져오는 것은 아닙니다. 페이지에 이미 있는 값을 읽을 뿐입니다. 다른 페이지에 이 표시가 없다면 이 방법은 통하지 않으며, 화면에 실제로 보이는 정보에 의존해야 합니다.

그리고 어떤 동작이든 마친 뒤 지켜야 할 가장 중요한 규칙이 있습니다. 상태를 새로 읽으세요. 클릭 전에 만든 스냅샷은 아무리 최신처럼 보여도 클릭 전 페이지를 설명합니다. 보드가 다시 그려진 뒤에는 그 안의 요소 참조가 더 이상 유효하지 않을 수 있고, 클릭 전에 읽은 data-turn 값도 달라졌을 수 있습니다. 동작을 마쳤다면 다시 확인하세요.

표시가 없다면 없다고 말해야 합니다

앱이 필요한 값을 제공하지 않았다면 에이전트는 "값을 읽을 수 없습니다. 페이지에 해당 속성이 없습니다"라고 답해야 합니다. 수를 둔 것 같다는 이유로 그럴듯하게 추측한 black은 실제로 읽은 값과 똑같아 보이지만, 아무것도 증명하지 못합니다. 요약이 아니라 직접 읽은 값을 보여 달라고 요청하세요.

동작이 실패했을 때

가장 흔한 문제는 "요소를 찾을 수 없습니다"라는 메시지입니다. 다음 순서로 확인해 보세요.

  1. 올바른 페이지가 열렸는지 확인합니다. 처음에 확인한 주소와 제목을 다시 보세요.
  2. 페이지가 준비됐는지 확인합니다. 게임 로딩이 끝나기 전이라 버튼이 요청보다 조금 늦게 나타났을 수 있습니다.
  3. 새 스냅샷을 가져옵니다. 대화에 이미 있는 스냅샷이 아니라 새로 만든 것입니다.
  4. 최신 스냅샷의 설명을 기준으로 요소를 다시 선택하고 동작을 반복합니다.

세 번째 단계에서 가능한 원인 하나를 찾을 수 있습니다. 요소는 여전히 페이지에 있지만 참조가 오래된 것입니다.

문제를 살펴볼 때 스크린샷도 도움이 되지만, 모든 문제를 해결하는 만능 도구는 아닙니다. "페이지가 어떻게 보이고 각 요소가 어디에 있는가"라는 질문에 답합니다. 예를 들어 보드가 비어 있거나 그 위에 모달 창이 떠 있는지 확인할 수 있습니다. 차례가 페이지 텍스트로 표시된다면 스크린샷에서도 볼 수 있습니다. 하지만 data-turn의 정확한 값은 해당 속성을 읽어야 확인할 수 있습니다. 서로 다른 질문에는 서로 다른 도구가 필요합니다. 둘을 혼동하면 이미지만 보고 데이터가 무엇인지 논쟁하게 됩니다.

작업 방식은 어떻게 달라질까요?

에이전트에게 클릭 목록을 주는 대신 확인 지점이 있는 순서를 요청하게 됩니다. 지금까지 살펴본 내용을 하나의 요청으로 정리하면 다음과 같습니다.

Playwright로 http://localhost:5173/ 을 여세요.
1) "새 게임"을 누르세요.
2) data-turn을 읽고 값을 보여 주세요.
3) 페이지 인터페이스에서 e2-e4 수를 두세요.
4) data-turn과 e4에 놓인 말을 다시 읽으세요.
값 중 하나라도 페이지에 없다면 없다고 말하고
직접 추측해 채우지 마세요.

다음 내용을 기억해 두세요.

  • 주소는 대략 짐작한 값이 아니라 실행 출력에서 가져온 실제 주소여야 합니다.
  • 요청에 "읽고 보여 주세요"라는 단계가 있어야 합니다. 없으면 결과에 관한 설명만 듣게 됩니다.
  • 동작 전후의 상태를 쌍으로 확인합니다. 처음 값이 무엇인지 모르면 마지막 값 하나만으로는 아무것도 증명되지 않습니다.
  • 스냅샷, 스크린샷, 속성 읽기는 서로 다른 질문에 답하므로 습관이 아니라 질문에 맞춰 선택합니다.
  • 연습용 순서 하나면 충분합니다. e2-e4 수가 제대로 두어졌다고 해서 그 뒤의 대국 전체가 규칙대로 진행된다는 뜻은 아닙니다. 그건 훨씬 더 큰 범위의 별도 검증입니다.

간단히 기억하면 됩니다. 브라우저는 에이전트에게 손과 눈을 주지만 결론까지 알려 주지는 않습니다. 에이전트가 페이지를 열고 클릭하고 값을 읽을 수는 있지만, 그 값이 무엇을 의미하는지는 여전히 여러분이 판단해야 합니다.


이 글에 나온 도구 이름과 매개변수는 2026년 9월 19일 기준으로 Playwright MCP README와 대조했으며 버전에 따라 달라질 수 있습니다. 페이지를 열고, 살펴보고, 요소를 선택해 동작한 뒤 다시 읽는 기본 순서는 그대로입니다.