3-3. 토큰 최적화와 안정성 2026-03-05 ~ 03-16
토큰 최적화: electron-mcp-server와 같은 교훈
electron-mcp-server의 rc.5에서 토큰 최적화의 중요성을 뼈저리게 느꼈다. 같은 날(3월 5일), react-native-mcp에도 같은 전략을 적용했다.
컴팩트 텍스트 출력 rc.10
모든 트리 구조 응답을 JSON에서 인덴트 텍스트로 변환했다.
take_snapshot 토큰 절감: -90%
describe_ui 토큰 절감: -78%
query_selector 토큰 절감: -70%
React Native 특유의 최적화
웹과 다르게 React Native에는 accessibilityLabel, testID, nativeID 같은 RN 전용 props가 있다. 컴팩트 출력에서 이런 props를 우선적으로 표시하고, 스타일 같은 장황한 정보는 생략한다.
안정성: WebSocket 크래시 방어 rc.11
문제 발견
MCP 서버를 강제 종료(Ctrl+C)하면 React Native 앱이 같이 크래시되는 문제가 발견됐다.
원인: MCP 서버가 종료되면 WebSocket 연결이 끊기는데, 런타임에서 이미 닫힌 소켓에 메시지를 보내려고 하면 네이티브 단에서 예외가 발생한다. JS 레벨의 try/catch로는 잡히지 않는 네이티브 크래시였다.
해결: websocket-guard
websocket-guard.ts에서 WebSocket의 send, close 메서드를 래핑했다:
- 전송 전에
readyState를 확인 - 전송 실패 시 에러를 삼키고 재연결 대기열에 넣기
- 런타임의 모든 WebSocket 사용처에서 guard를 통해서만 전송
이 패치 후로 MCP 서버를 아무 때나 종료해도 앱은 살아 있고, 서버를 다시 시작하면 자동 재연결된다.
서버 Instructions: AI 가이드 rc.12 ~ rc.14
MCP 프로토콜에는 instructions라는 필드가 있다. 서버가 자기 자신을 AI에게 소개하는 텍스트이다.
처음에는 간단한 설명만 넣었는데, AI가 도구를 비효율적으로 쓰는 패턴을 발견했다:
- 매번
take_screenshot을 먼저 호출 → 이미지 토큰 낭비 - 좌표계를 모르고 tap → 엉뚱한 곳 클릭
- 간단한 확인에도 무거운 도구 사용
rc.12: 도구 설명 개선
8개 주요 도구의 설명을 다시 썼다. "이 도구는 무엇을 한다"에서 "이 상황에서 이 도구를 써라"로 바꿨다.
rc.13: 도구 우선순위 테이블
AI가 도구를 선택할 때 참고할 수 있는 우선순위 가이드를 instructions에 추가했다:
rc.14: iOS orientation 가이드
iOS 시뮬레이터의 좌표계 문제 때문에, instructions 맨 앞에 "iOS에서는 먼저 get_orientation을 확인하라"는 안내를 넣었다. AI가 이걸 읽고 먼저 orientation을 확인한 뒤 좌표를 계산하게 된다.
TypeScript Strict Null rc.12
rc.12에서 TypeScript strict null check를 활성화했다. 기존 코드에서 null | undefined 관련 타입 에러가 대거 발견됐다.
대부분은 옵셔널 체이닝(?.)이나 널 병합(??)으로 간단히 수정됐지만, Fiber 탐색 코드에서 fiber.child가 null인 경우를 제대로 처리하지 않은 곳이 몇 군데 있어서 실제 런타임 버그도 잡았다.
모노레포 init 커맨드 02-28
이 명령어 하나로 설정이 완료되도록 만들었다:
babel.config.js에 프리셋 추가- MCP 클라이언트 설정 파일 생성 (
.cursor/mcp.json등) - 필요한 네이티브 도구(adb/idb) 확인
단일 레포와 모노레포 모두 지원한다. 모노레포인 경우 package.json의 워크스페이스 설정을 읽어서 적절한 위치에 설정 파일을 생성한다.
6주의 결과
토큰을 90% 절감하고, WebSocket 크래시를 방어하고, AI 가이드를 정교하게 다듬어서 실사용 가능한 수준의 React Native MCP 서버를 완성했다.