코딩 에이전트가 직접 크롬을 열어 성능과 콘솔을 확인한다, Chrome DevTools MCP
Tools15분 읽기

코딩 에이전트가 직접 크롬을 열어 성능과 콘솔을 확인한다, Chrome DevTools MCP

크롬 개발자 도구 팀의 chrome-devtools-mcp로 에이전트가 느린 페이지의 LCP 원인과 메모리 누수를 직접 진단하는 과정을 따라가고, 켜기 전에 정할 통제 설정까지 정리했습니다.

목요일 오후, 상품 목록 페이지를 손본 직후에 QA 채널에 제보가 올라옵니다. “첫 화면이 한참 비어 있다가 이미지가 뜹니다.” 에이전트에게 이유를 물으면 코드를 읽고 “이미지가 커서 그렇습니다” 정도의 추측을 내놓는 것이 보통입니다. 크롬을 열어 재 본 적이 없으니 추측 이상을 말할 수 없습니다. 크롬 개발자 도구 팀이 관리하는 오픈소스 MCP 서버 chrome-devtools-mcp를 붙이면 같은 질문의 답이 달라집니다. 에이전트가 직접 페이지를 열고 성능 추적을 돌려, 가장 큰 콘텐츠가 그려지기까지의 시간(LCP)이 어느 구간에서 길어졌는지를 숫자로 말합니다.

이 글은 그 하루를 따라갑니다. 설정, 첫 호출, 원인 좁히기, 수정 뒤 재측정까지가 첫 번째 제보이고, 이어서 “모달을 열수록 메모리가 쌓인다”는 두 번째 제보를 스냅샷 세 장으로 판정하며, 마지막에 켜기 전에 통제할 것을 정리합니다. 페이지(staging.example.com/products)와 수치는 편집부가 설명용으로 만든 예시이고, 도구 이름·인자·판정 기준은 공식 문서와 스킬 문서에서 가져왔습니다. 2026-10-27 UTC 기준으로 이 도구는 Apache-2.0 라이선스이고 GitHub 별 54,197개, npm 최신판은 10월 22일에 나온 1.12.0입니다. 8월 25일의 1.8.0 이후 여섯 번 릴리스가 나왔을 만큼 빠르게 바뀌며, README 제목은 이제 “Chrome DevTools for agents”이고 패키지 이름은 그대로입니다.

설정 한 줄과 확인용 첫 프롬프트

필요한 것은 Node.js LTS(패키지가 요구하는 범위는 20.19 이상 또는 22.12 이상), 최신 안정판 Chrome, npm입니다. 에이전트 클라이언트의 MCP 설정에는 아래 덩어리를 넣는 것이 표준입니다.

{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["-y", "chrome-devtools-mcp@latest"]
    }
  }
}

@latest는 클라이언트를 켤 때마다 최신 서버를 쓰게 합니다. 팀 환경에서 재현성이 필요하면 번호를 고정하는 쪽이 낫습니다. Claude Code는 서버만 추가하는 한 줄 명령과, 서버와 스킬 일곱 개를 함께 설치하는 플러그인 경로가 따로 있습니다. 이 글에서 따라갈 진단 절차(LCP 다섯 단계, 스냅샷 세 장)는 스킬 문서에 적힌 것이라, 에이전트가 같은 순서를 참고하게 하려면 플러그인 쪽이 맞습니다.

  1. node -v로 20.19 이상(22 계열이면 22.12 이상)인지 본다.
  2. 서버만 쓸 거라면 claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest를 실행한다. 스킬까지 쓸 거라면 /plugin marketplace add ChromeDevTools/chrome-devtools-mcp 다음 /plugin install chrome-devtools-mcp@chrome-devtools-plugins를 실행한다. 서버만 먼저 깔아 둔 상태라면 문서는 플러그인 설치 전에 기존 설치를 지우라고 안내한다.
  3. Claude Code를 다시 시작한다. 플러그인으로 깔았다면 /skills에 스킬이 보이는지 확인한다.
  4. README의 확인 문장 "Check the performance of https://developers.chrome.com"을 그대로 보낸다. 크롬 창이 뜨고 성능 추적이 기록되면 연결된 것이다.

서버를 연결했다고 크롬이 바로 뜨지는 않습니다. README는 브라우저가 도구가 처음 필요해질 때 시작된다고 못박습니다. 연결만 해 두고 다른 작업을 하는 동안에는 크롬이 꺼져 있습니다.

첫 호출 한 번에 오가는 것: 크롬 기동, uid, 추적 요약

아래 그림은 확인용 프롬프트 하나가 서버와 크롬 사이에서 만드는 순서입니다. 붉은 화살표가 크롬이 처음 뜨는 지점이고, 점선은 에이전트에게 돌아오는 응답입니다.

에이전트가 도구를 부르면 서버가 처음 크롬을 띄우고, 스냅샷과 추적 결과가 요약 형태로 돌아오는 시퀀스 그림 1. 첫 도구 호출에서 크롬이 뜨고, 이후 응답은 글로 된 요약이다

세 가지를 짚어 둘 만합니다. 첫째, 서버가 직접 띄운 크롬은 전용 프로필 폴더(맥·리눅스는 $HOME/.cache/chrome-devtools-mcp/chrome-profile)를 실행 사이에 유지하므로, 한 번 로그인한 사이트는 다음 실행에도 로그인된 채로 남습니다. 둘째, 페이지에 일을 시키는 도구는 모두 pageId를 받습니다. 1.8.0부터 이것이 기본 필수가 되어, 한 서버를 여러 에이전트 세션이 나눠 써도 각자 자기 탭을 가리킵니다. 셋째, 에이전트는 화면 그림을 보고 좌표를 찍는 대신 take_snapshot이 돌려주는 접근성 트리를 글로 읽습니다. 요소마다 uid가 붙어 있고 click, fill은 그 uid를 받습니다. 도구 설명에는 스크린샷보다 스냅샷을 우선하고 항상 가장 최근 스냅샷을 쓰라고 적혀 있습니다. 좌표로 누르는 click_at은 --experimentalVision을 켜야 나타납니다.

응답이 요약 형태인 것은 설계 원칙입니다. 프로젝트의 설계 문서는 “LCP was 3.2s”가 5만 줄짜리 JSON보다 낫다고 적고, 스크린샷·추적·영상처럼 무거운 자료는 값 대신 파일 경로로 돌려주라고 합니다. 그래서 추적 한 번의 결과로 에이전트가 받는 것은 LCP 시간과 “사용할 수 있는 인사이트 묶음” 목록이고, 상세는 performance_analyze_insight로 하나씩 되물어 얻습니다. 원본 추적이 필요하면 filePath를 주어 파일로 저장합니다.

추적 한 번이 LCP 3.9초를 네 토막으로 가른다

첫 번째 제보로 돌아가 에이전트에게 staging.example.com/products 주소를 주고 성능을 보라고 합니다. 스킬이 정한 시작은 두 호출입니다. navigate_page로 주소를 연 뒤 performance_start_trace를 reload: true, autoStop: true로 부릅니다. 캐시를 우회한 처음 방문을 재려면 1.11.0에서 들어온 ignoreCache 옵션을 같이 줍니다. 예시 결과는 LCP 3.9초입니다. 스킬이 인용하는 판정 기준은 2.5초 이하가 좋음, 2.5~4.0초가 개선 필요, 4.0초 초과가 나쁨이므로 가운데 구간에 해당합니다.

숫자 하나로는 어디를 고칠지 알 수 없어서, 스킬은 LCP를 순서대로 이어지는 네 구간으로 쪼갭니다. 서버가 첫 바이트를 보내기까지(TTFB), 그 뒤 브라우저가 LCP 요소의 자원을 요청하기까지의 대기(로드 지연), 자원을 내려받는 시간(로드 시간), 내려받은 뒤 화면에 그려지기까지의 대기(렌더 지연)입니다. 이상적인 비중은 TTFB가 약 40%, 로드 시간이 약 40%이고, 두 지연 구간은 각각 10% 미만입니다. 지연 구간은 “기다리는 시간”이라 0에 가까울수록 좋습니다.

이상적인 비중, 수정 전, 수정 후의 LCP 네 구간 비중을 비교한 누적 막대 그림 2. 맨 위가 스킬의 이상적 분할, 가운데와 아래는 가정한 예시 값(편집부 계산 비율)

지금은 위 두 줄만 보면 됩니다(맨 아래 줄은 수정 뒤의 결과라 두 절 뒤에서 다시 봅니다). 이상적인 분할과 달리 수정 전 막대에서는 로드 지연이 41%, 1.6초로 가장 깁니다. 이미지를 내려받는 데 걸린 시간은 1.0초에 불과한데, 내려받기를 시작하기 전에 기다린 시간이 그보다 깁니다. 이때 이미지 파일을 줄이는 것은 헛수고입니다. 스킬 문서도 한 구간만 최적화하고 다른 구간을 확인하지 않는 것을 흔한 함정으로 꼽습니다. 파일을 줄여 아낀 시간이 렌더 지연으로 옮겨 갈 뿐이라는 설명입니다.

범인을 좁히는 세 번의 질의와 한 줄 수정

스킬은 구간을 확인한 뒤 원인을 좁히는 순서까지 정해 둡니다. 인사이트 이름 네 개(LCPBreakdown, DocumentLatency, RenderBlocking, LCPDiscovery) 가운데 구간표를 주는 LCPBreakdown을 먼저 열고, 그다음 LCP 요소가 무엇인지, 그 요소의 요청이 왜 늦었는지를 차례로 묻습니다.

인사이트 조회, LCP 요소 식별, 일반 문제 점검, 네트워크 목록의 네 호출과 결과 모양을 보여 주는 터미널 화면 그림 3. 진단 호출 네 번. 도구 이름과 결과 키는 문서 기준이고 숫자는 예시 값

두 번의 evaluate_script는 스킬의 참조 문서(references/lcp-snippets.md)에 들어 있는 스니펫을 실행합니다. 첫 스니펫은 largest-contentful-paint 항목을 관찰해 LCP 요소의 태그, 주소(url), 시작·렌더 시각을 돌려줍니다. url이 비어 있으면 글자 요소라서 따라갈 자원이 없습니다. 이번 예시에서는 IMG와 /img/hero-1.avif가 나왔습니다. 둘째 스니펫은 화면 안에 있는데 loading="lazy"가 붙은 이미지, 큰데 fetchpriority가 없는 이미지, <head> 안의 async·defer 없는 스크립트를 찾아 issues 배열에 넣어 줍니다. 마지막으로 list_network_requests를 resourceTypes: ["image","font"]로 불러 LCP 이미지가 언제 시작했는지 봅니다.

결과가 가리키는 쪽은 한 곳입니다. 스타일시트는 0.9초에 요청이 시작됐는데 히어로 이미지는 2.4초에야 시작했고, 이 간격 1.5초는 로드 지연 1.6초와 맞아떨어집니다. 첫 화면에 보이는 이미지에 지연 로딩을 걸었기 때문입니다. 스킬의 첫 번째 처방이 정확히 이것입니다. LCP 이미지는 지연 로딩하지 않고, 필요하면 fetchpriority="high"를 줍니다.

<!-- 수정 전 -->
<img src="/img/hero-1.avif" loading="lazy" alt="이번 주 인기 상품">

<!-- 수정 후 -->
<img src="/img/hero-1.avif" fetchpriority="high" alt="이번 주 인기 상품">

바뀐 것은 한 줄이지만, 에이전트가 이 줄을 고르기까지의 근거가 호출 네 번에 남아 있다는 점이 중요합니다. “이미지가 커서”라는 추측이었다면 파일 압축부터 했을 것이고, 앞에서 본 함정대로 숫자는 거의 움직이지 않았을 것입니다.

다시 재고, 느린 기기로 다시 재고

고친 뒤에는 같은 추적을 한 번 더 돌립니다. 스킬의 검증 절차도 같은 performance_start_trace를 reload: true로 다시 불러 구간 비중을 비교하는 것입니다. 그림 2의 맨 아래 줄이 그 결과입니다. 예시에서는 LCP가 2.4초가 되어 좋음 구간(2.5초 이하)에 들어왔고, 로드 지연은 1.6초에서 0.1초로 줄었습니다. 그런데 렌더 지연 0.5초가 이제 21%로 두 번째 후보로 올라섭니다. 가장 큰 병목을 치우면 그다음 병목이 보이는 것이 보통이고, 같은 방식으로 한 바퀴를 더 돌릴 수 있습니다.

마지막으로 콘솔을 확인합니다. list_console_messages는 마지막 이동 이후의 콘솔 메시지를 돌려주고, types로 종류를 걸러 오류만 볼 수 있습니다. 스택 트레이스가 필요하면 includeStackTraces를 켭니다. 1.8.0에서 들어온 옵션이고, 응답이 커지는 대가가 있습니다. 수정이 새 오류를 만들지 않았는지를 같은 대화 안에서 확인하는 것이 이 서버의 쓸모입니다.

개발 기기에서 잰 값은 사용자의 기기보다 빠르기 마련입니다. 스킬은 emulate에 networkConditions: "Fast 3G"와 cpuThrottlingRate: 4를 주어 느린 환경을 흉내 내라고 안내합니다. 도구 설명에는 emulate를 부를 때마다 이전 에뮬레이션 설정(추가 HTTP 헤더 제외)이 통째로 바뀐다고 적혀 있으므로, 원하는 설정은 한 번에 모두 넘겨야 합니다. 구간별로 먼저 시도할 처방은 아래와 같습니다.

구간(이상적 비중) 큰 값이 말해 주는 것 먼저 할 일
TTFB (약 40%) HTML이 늦게 도착한다 리디렉션 줄이기, 서버 응답 개선, HTML을 가장자리(CDN)에 캐시, 뒤로 가기 캐시 대상이 되게 하기
로드 지연 (10% 미만) LCP 요소의 요청이 늦게 시작한다 LCP 이미지에 loading="lazy" 금지, fetchpriority="high" 추가, HTML에서 발견되지 않으면 preload
로드 시간 (약 40%) 자원이 크거나 전달이 느리다 WebP·AVIF와 srcset, CDN, Cache-Control, 글자가 LCP면 font-display: swap
렌더 지연 (10% 미만) 내려받은 뒤에도 그리지 못한다 핵심 CSS 인라인, 비핵심 CSS·JS 지연, 긴 작업 쪼개기, 서버 렌더링

추적은 실험실 측정입니다. 이 서버의 성능 도구는 추적한 주소를 Chrome UX Report(CrUX) API에 보내 실사용자 값을 옆에 붙일 수 있고, 이 기능은 기본으로 켜져 있습니다. 사내 스테이징처럼 밖에 알리고 싶지 않은 주소를 추적할 때는 --no-performance-crux로 끕니다. 기본 추적 버퍼는 1.9.0부터 1.2GB이고, 1.10.0에서 큰 기록을 조각 단위로 읽는 파서가 들어갔습니다.

모달을 열고 닫을수록 메모리가 쌓인다는 제보

두 번째 제보는 눈으로 찾기 어려운 종류입니다. 상품 상세 모달을 열고 닫기를 반복하면 탭 메모리가 조금씩 오른다는 내용입니다(이 사례도 편집부가 만든 예시입니다). 메모리 도구는 이런 누수를 잡으려고 있고, 14개 가운데 13개가 --memoryDebugging을 켜야 나타납니다. 플래그 없이 쓸 수 있는 것은 스냅샷을 찍는 take_heapsnapshot 하나입니다. 설정 파일로 켜면 이렇습니다.

{
  "headless": true,
  "isolated": true,
  "memoryDebugging": true
}

스냅샷은 세 장을 찍습니다. 동작 전의 기준선, 의심 동작을 약 10번 반복한 뒤, 화면을 원래대로 되돌린 뒤입니다. 반복하는 이유는 작은 누수를 증폭해 눈에 띄게 만들기 위해서이고, 되돌린 뒤를 다시 찍는 이유는 정상적인 메모리 사용과 누수를 가르기 위해서입니다. 모달이 열려 있는 동안 메모리가 오르는 것은 당연합니다. 닫고 원상복구한 뒤에도 기준선 위에 남아 있어야 비로소 무언가가 붙잡고 있다는 증거가 됩니다. 모달을 열고 닫는 동작은 앞에서 본 take_snapshot의 uid로 click을 불러 수행합니다.

스킬의 참조 문서는 누수의 흔한 모양 다섯 가지를 적어 둡니다. 제거하지 않은 이벤트 리스너, 화면에서 떼어 냈지만 변수가 아직 가리키는 DOM 노드, 의도치 않은 전역 변수, 큰 객체를 붙잡은 클로저, 한도 없이 커지는 캐시나 배열입니다. 도구가 이 분류를 찾아 주지는 않습니다. 보고서가 가리키는 경로가 코드의 어느 줄로 이어지는지를 읽을 때 쓰는 참고표입니다.

스냅샷 세 장에서 붙잡은 쪽까지 거슬러 오르기

판정과 추적의 분기는 아래 그림과 같습니다. 위쪽 띠에서 세 장을 찍고, 가운데 띠에서 세 번째가 첫 번째보다 높은지를 보고, 높을 때만 아래 띠의 추적으로 내려갑니다.

스냅샷 세 장을 찍은 뒤 세 번째가 첫 번째보다 높은지 판정하고, 높으면 비교와 필터와 보유 경로로 거슬러 오르는 흐름도 그림 4. 세 번째가 기준선으로 돌아왔다면 누수가 아니고, 남아 있다면 붙잡은 쪽을 찾아 오른다

에이전트가 부르는 도구는 다음 순서입니다.

  1. take_heapsnapshot에 filePath를 주어 기준 스냅샷을 파일로 저장한다. 동작 반복 뒤, 원상복구 뒤에도 같은 방식으로 두 장을 더 저장한다.
  2. get_heapsnapshot_summary로 세 파일이 열리는지, 전체 크기가 어떻게 다른지 본다.
  3. compare_heapsnapshots에 기준 파일과 이후 파일을 주어 요약 차이를 얻고, 늘어난 클래스만 classIndex로 상세 조회한다.
  4. get_heapsnapshot_details나 get_heapsnapshot_class_nodes에 filterName을 주어 원인별로 거른다. 떼어 낸 DOM에 붙들린 객체, 이벤트 핸들러에 붙들린 객체, 클로저 컨텍스트에 갇힌 객체, 콘솔에 남은 객체가 구분된다.
  5. get_heapsnapshot_retainers와 get_heapsnapshot_retaining_paths에 노드 번호를 주어 누가 붙잡고 있는지 경로를 본다. 조사가 끝나면 close_heapsnapshot으로 서버가 쥔 메모리를 풀어 준다.

이 절차에서 지킬 것은 두 가지입니다. 원본 .heapsnapshot 파일을 에이전트가 직접 읽게 하지 않습니다. 파일이 매우 커서 토큰이 많이 들기 때문에 스킬은 요약·비교·경로 도구만 쓰라고 못박습니다. 또 떼어 낸 DOM이 보인다고 모두 버그는 아닙니다. 사이트가 일부러 만든 캐시일 수 있어서, 스킬은 참조를 지우기 전에 사용자에게 먼저 물으라고 합니다. 이 예시에서 경로가 모달 닫기 핸들러 하나로 이어졌다면, 사람은 그 핸들러가 removeEventListener 없이 window에 걸려 있다는 사실을 확인하고 고치면 됩니다.

도구도 계속 늘고 있습니다. 1.11.0은 닫힌 클로저가 아무도 읽지 못하는 값을 붙잡고 있는 컨텍스트를 순위로 보여 주는 analyze_heapsnapshot_contexts를 더했고, 비교 결과에는 페이지 나누기와 이름 길이 제한이 붙었습니다. 문서는 이 순위가 회수 가능한 정확한 바이트가 아니라 우선순위를 가리는 어림값이라고 밝힙니다. 1.12.0부터는 저장해 둔 스냅샷 파일을 브라우저 연결 없이도 분석합니다. 크롬을 닫은 뒤에도 파일만 있으면 조사를 이어 갈 수 있다는 뜻입니다.

도구 59개 중 이번 작업이 건드린 곳

이 글의 두 제보를 처리하는 동안 에이전트가 부른 도구는 범주 몇 곳에 모여 있습니다. 배포된 1.12.0의 도구 참조 문서는 11개 범주 59개를 나열합니다. 10월 23일에 main 브랜치에 가상 WebAuthn 인증기를 설정하는 configure_webauthn(--categoryWebauthn)이 합쳐져서, main 쪽 문서에는 12개 범주 60개로 나옵니다.

범주 수 기본 상태 이번 작업에서
입력 자동화 10 켜짐 click으로 모달 열고 닫기
탐색 자동화 6 켜짐 new_page, navigate_page
에뮬레이션 2 켜짐 emulate로 Fast 3G와 CPU 4배 느림
성능 3 켜짐 performance_start_trace, performance_analyze_insight
네트워크 2 켜짐 list_network_requests, get_network_request
디버깅 9 켜짐 take_snapshot, evaluate_script, list_console_messages
메모리 14 범주는 켜짐, 13개는 --memoryDebugging 필요 스냅샷 세 장, 비교, 보유 경로
확장 프로그램 5 꺼짐 (--categoryExtensions) 쓰지 않음
서드파티 2, WebMCP 2 4 꺼짐 (각각 전용 플래그, WebMCP는 Chrome 150 이상) 쓰지 않음
PWA 4 꺼짐 (--categoryPwa, 파이프 연결에서만) 쓰지 않음

디버깅 범주에는 이 글에서 쓰지 않은 lighthouse_audit도 있습니다. 접근성, SEO, 모범 사례, 에이전트 사용 적합성을 감사하고 성능은 제외하므로, 성능은 위의 추적 도구가 맡습니다. 도구가 너무 많아 컨텍스트가 부담스러우면 --slim이 있습니다. navigate, evaluate, screenshot 세 도구만 노출하고, “열어서 한 번 찍어 보기” 수준의 작업에 맞습니다.

같은 도구를 에이전트 없이 터미널에서 부르는 길도 있습니다. npm i chrome-devtools-mcp@latest -g로 설치하면 chrome-devtools 명령이 생기고, 첫 호출 때 백그라운드 서버와 브라우저가 자동으로 시작되어 이후 명령이 같은 브라우저를 이어서 씁니다. 페이지 단위 도구는 첫 인자로 pageId를 받습니다. 헤드리스 격리 모드가 기본이며, 결과는 읽기 쉬운 요약으로 나오고 --output-format=json을 주면 원본 JSON이 나옵니다.

chrome-devtools new_page "https://example.com"
chrome-devtools take_screenshot 1 --filePath screenshot.png
chrome-devtools lighthouse_audit 1 --mode snapshot
chrome-devtools stop   # 백그라운드 서버와 브라우저 종료

스킬은 이 글에서 쓴 debug-optimize-lcp와 memory-leak-debugging 외에 chrome-devtools(기본 사용법), chrome-devtools-cli, a11y-debugging, cookie-debugging, troubleshooting을 합쳐 일곱 개입니다. README는 스킬이 서버 버전과 짝이라서 서버나 CLI를 올릴 때마다 스킬도 다시 갱신하라고 안내합니다. 오래된 스킬이 바뀐 도구나 인자를 쓰라고 할 수 있기 때문입니다.

켜기 전에 정할 것들: 프로필, 주소, 통계, 설정 파일

이 도구가 하는 일은 모두 “브라우저 안의 모든 것을 에이전트에게 열어 주는” 일의 다른 얼굴입니다. README의 면책 항목은 브라우저 인스턴스의 내용이 MCP 클라이언트에 노출되어, 클라이언트가 그 안의 데이터를 검사하고 고칠 수 있다고 적습니다. 네트워크 요청 도구는 헤더와 본문을 돌려주고 설명에도 Cookie와 Set-Cookie가 언급되어 있으니, 인증 정보가 에이전트에게 그대로 넘어갈 수 있다고 보는 것이 맞습니다. 이를 가리는 --redactNetworkHeaders는 기본으로 꺼져 있습니다.

먼저 어떤 크롬에 붙을지 정합니다. 기본은 서버가 전용 프로필로 새 크롬을 띄우는 방식이고, --isolated를 주면 종료 때 지워지는 임시 프로필을 씁니다. 실행 중인 내 크롬에 붙는 방법도 둘 있습니다. --autoConnect는 Chrome 144 이상에서 chrome://inspect/#remote-debugging으로 원격 디버깅을 켜고 허용 대화상자에서 Allow를 눌러야 하며, 기본 프로필의 열린 창 전체가 에이전트에게 보입니다. --browser-url=http://127.0.0.1:9222는 디버깅 포트로 띄운 크롬에 붙는 방식인데, 문서는 포트가 열려 있는 동안 로컬의 어떤 앱이든 브라우저를 조종할 수 있다고 경고합니다. 별도 --user-data-dir로 평소 프로필과 떼어 놓고 민감한 사이트는 열지 않는 것이 안전합니다.

그다음은 서버 쪽 통제 옵션입니다. 설정 옵션 문서 기준으로 정리하면 다음과 같습니다.

  • --blockedUrlPattern은 일치하는 주소로의 이동과 하위 요청을 막고, --allowedUrlPattern은 일치하는 주소만 허용합니다(Chrome 149 이상).
  • --fileNavigations를 끄면 file: 주소 이동이 막힙니다. 파일 시스템 샌드박스는 아니라서 완전한 격리에는 운영체제 샌드박스가 따로 필요합니다.
  • --javascriptEvaluation을 끄면 evaluate_script와 javascript:·data: 이동이 막히지만, 페이지 자체 스크립트는 계속 실행됩니다. 이 글의 LCP 진단은 evaluate_script를 쓰므로 진단 세션에서는 켜 두어야 합니다.
  • --filesystemRoot(--workspace)는 파일 도구가 접근할 폴더를 정하고, 기본값은 운영체제 임시 폴더입니다.
  • --experimentalDevtools를 켜면 개발자 도구 화면(콘솔 포함)을 자동 조작할 수 있는데, 이 경로는 --javascriptEvaluation이 막지 못합니다.

옵션은 명령행 인자 대신 JSON 설정 파일로도 줄 수 있습니다. 탐색 순서는 --config 경로, 플러그인으로 실행될 때의 플러그인 데이터 폴더, 그리고 전역 파일(맥·리눅스는 ~/.config/cd4a/config.json)이고 먼저 찾은 하나만 쓰며 병합하지 않습니다. 1.12.0에서 들어온 --watchConfig를 켜면 파일을 고칠 때 서버를 다시 시작하지 않고도 주소 패턴과 도구 범주가 반영됩니다. 다만 이미 열려 있던 탭은 새 패턴을 어겨도 붙은 채로 남습니다.

{
  "headless": true,
  "isolated": true,
  "blockedUrlPattern": ["*://*.example.com/*"],
  "usageStatistics": false,
  "performanceCrux": false
}

설정 파일 자체가 가장 약한 고리입니다. 파일이 실행 파일 경로, 크롬 인자, 주소 패턴을 정하므로, 에이전트가 이 파일(또는 --config로 지정한 경로)을 고칠 수 있으면 제한을 스스로 풀 수 있다고 문서가 경고합니다. 파일과 그 상위 폴더는 에이전트가 쓸 수 없는 곳에 둡니다.

바깥으로 나가는 값은 세 가지입니다. 사용 통계는 Google이 도구 호출 성공률, 지연, 환경 정보를 수집하며 기본 켜짐이고, --no-usage-statistics 인자나 CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS 환경 변수로 끕니다. CI 환경 변수가 있으면 자동으로 꺼지며, Chrome 자체의 통계 설정과는 별개입니다. 앞서 본 CrUX 조회는 --no-performance-crux로 끕니다. npm의 새 버전 확인은 CHROME_DEVTOOLS_MCP_NO_UPDATE_CHECKS로 끕니다. 공식 지원 브라우저는 Google Chrome과 Chrome for Testing뿐이고, 다른 크롬 계열은 동작을 보장하지 않습니다.

  • 붙일 크롬이 작업 전용인지 확인한다(은행·메일·사내 도구에 로그인된 프로필이 아니어야 한다).
  • 점검 대상이 아닌 주소는 blockedUrlPattern으로 막고, 필요하면 allowedUrlPattern으로 허용 목록을 만든다.
  • 통계와 CrUX를 끌지 정해 설정 파일이나 인자에 적는다.
  • 설정 파일 위치가 에이전트의 쓰기 범위 밖인지 확인한다.
  • 스킬을 쓴다면 서버 버전을 올릴 때 같이 갱신한다.
#Chrome DevTools#MCP#Claude Code#Lighthouse#코딩 에이전트#오픈소스