3-3. 토큰 최적화 대작전 2026-03-05

문제: AI가 먹는 토큰이 너무 많다

rc.4까지의 MCP 서버는 모든 도구의 응답을 JSON으로 반환했다. 사람이 보기엔 괜찮은데, AI에게 보내면 토큰을 엄청나게 소모한다.

특히 take_snapshot이 심각했다. 접근성 트리의 JSON 출력이 간단한 Electron 앱에서도 219,053자가 나왔다. Claude의 컨텍스트 윈도우를 이 하나의 도구 응답이 다 잡아먹는 것이다.

도구 하나 호출했는데 20만 토큰이 날아가면, 그 뒤로 뭘 더 할 수가 없다

이건 DX 문제가 아니라 사용 불가 수준의 문제였다.

해결: 컴팩트 텍스트 출력

rc.5에서 모든 도구의 응답을 JSON에서 인덴트 텍스트로 바꿨다.

take_snapshot 변환 예시

Before (JSON, 219,053 chars):

{
  "nodes": [{
    "nodeId": "1",
    "role": {"type": "button"},
    "name": {"value": "로그인"},
    "properties": [
      {"name": "focused", "value": {"type": "boolean", "value": false}},
      {"name": "editable", "value": {"type": "string", "value": "none"}}
    ],
    "childIds": ["2"]
  }]
}

After (텍스트, 2,193~6,265 chars):

button "로그인" [ref=e1]
  text "로그인"
input "이메일" [ref=e2] editable
  value: ""

결과: -97~99% 토큰 절감

어떻게 줄였나

  1. JSON → 인덴트 텍스트 — 키, 따옴표, 괄호 등 JSON 구문이 차지하는 부분을 전부 제거
  2. 이름 없는 구조 노드 필터링compact 모드에서 generic 역할의 이름 없는 노드를 스킵
  3. interactive 모드 — 클릭 가능한 요소만 표시. AI가 "클릭할 곳"만 알면 되는 경우에 유용
  4. maxDepth 제한 — 트리 깊이를 제한해서 하위 구조를 생략

다른 도구들도 마찬가지

도구토큰 절감률
take_snapshot-97~99%
get_electron_window_info-60.7%
get_electron_process_structure-74.2%
list_console_messages-70~80%
list_network_requests-65~75%

모든 도구의 응답을 AI 친화적 텍스트로 바꿨다.

트러블슈팅: 스냅샷 누락 버그

rc.5 개발 중에 발견한 치명적 버그가 있었다.

Accessibility.getFullAXTree가 반환하는 노드 중에 ignored: true인 노드가 있는데, rc.4에서 이걸 처리하는 코드에 버그가 있어서 전체 트리가 비어 있는 경우가 있었다.

원인을 추적해보니, ignored 노드의 자식까지 전부 무시하는 로직이었다. 근데 ignored 노드의 자식 중에 ignored가 아닌 노드가 있을 수 있다. ignored 노드 자체는 건너뛰되, 그 자식은 상위 노드에 붙여야 한다.

이 버그는 rc.4에서는 JSON 출력이라 노드가 좀 빠져도 티가 안 났는데, rc.5에서 텍스트 출력으로 바꾸면서 빈 화면이 반환되어 발견됐다.

크로스 포트 타겟 분리

rc.5에서 메인 프로세스(9229)와 렌더러(9222)의 타겟을 명확하게 분리했다.

rc.4까지는 하나의 포트에서 모든 타겟을 찾으려 했는데, 실제로 Electron은 메인 프로세스와 렌더러가 다른 포트에서 디버깅 엔드포인트를 제공한다.

메인 프로세스: --inspect=9229 → http://127.0.0.1:9229/json
렌더러:        --remote-debugging-port=9222 → http://127.0.0.1:9222/json

이 두 포트를 자동으로 스캔해서, 메인 프로세스 도구(ipc, network-main, resource)는 9229로, 렌더러 도구(snapshot, click, fill)는 9222로 연결한다.

rc.5 배포

rc.4와 rc.5를 같은 날(3월 5일)에 배포했다. rc.4에서 리치 콘솔을 넣었다가 zod 번들링 이슈와 스냅샷 버그를 발견해서, 바로 rc.5로 전부 수정하고 토큰 최적화까지 포함시켰다.

하루에 두 번 배포한 건 좀 정신없었지만, MCP 도구 특성상 토큰 효율이 곧 사용성이니까 빨리 내는 게 맞았다.

1줄 요약

JSON → 인덴트 텍스트 변환으로 take_snapshot의 토큰을 97~99% 절감했고, 스냅샷 누락 버그를 수정하고, 메인/렌더러 포트를 자동 분리하는 rc.5를 같은 날 배포했다.