3-1. 런타임 인젝션과 Fiber 트리 2026-02-07 ~ 02-19
런타임 아키텍처
MCP 서버가 React Native 앱의 내부에 접근하려면, 앱 안에서 돌아가는 "에이전트"가 필요하다. 이 에이전트가 런타임이다.
런타임은 20개 이상의 모듈로 구성되어 있다:
fiber-helpers.ts— React Fiber 트리 탐색fiber-serialization.ts— Fiber 노드를 직렬화mcp-state.ts— 컴포넌트 state 읽기state-hooks.ts— useState, Zustand 등 hook state 추출mcp-render.ts— 렌더링 추적mcp-network.ts— 네트워크 모니터링xhr-patch.ts,fetch-patch.ts— XHR/fetch 가로채기mcp-query.ts— CSS 유사 셀렉터 엔진mcp-measure.ts— 엘리먼트 측정 (UIManager)mcp-accessibility.ts— 접근성 트리console-hook.ts— console.log 캡처websocket-guard.ts— WebSocket 크래시 방어
React Fiber 접근
REACT_DEVTOOLS_GLOBAL_HOOK
React는 DevTools를 위해 글로벌 훅을 제공한다. window.__REACT_DEVTOOLS_GLOBAL_HOOK__에 등록하면 React가 Fiber 트리에 접근할 수 있는 인터페이스를 제공한다.
런타임이 앱 시작 전에 이 훅을 등록한다. React DevTools가 하는 것과 같은 방식이다.
Fiber 트리 탐색
Fiber 노드는 링크드 리스트 구조이다. child → sibling → return 포인터로 트리를 탐색한다.
각 Fiber 노드에서 읽을 수 있는 정보:
type— 컴포넌트 이름 (Button,TextInput등)memoizedProps— 현재 propsmemoizedState— 현재 state (hooks 체인)stateNode— 네이티브 뷰 인스턴스_debugSource— 소스 코드 위치 (파일명, 라인 번호)
State 읽기: Hook 체인 파싱
useState의 값을 읽으려면 Fiber의 memoizedState를 파싱해야 한다. React의 hooks는 링크드 리스트로 저장된다:
첫 번째 useState의 값은 "홍길동", 두 번째는 30. 이 체인을 순서대로 읽으면 컴포넌트의 모든 state를 가져올 수 있다.
Zustand 같은 외부 상태 관리 라이브러리도 결국 React의 hooks를 통해 연결되니까, 같은 방법으로 읽을 수 있다.
트러블슈팅: Fiber 직렬화 폭발
Fiber 노드를 그냥 JSON.stringify하면 순환 참조 때문에 폭발한다. return 포인터가 부모를 가리키니까.
그리고 Fiber에는 사용자가 관심 없는 내부 필드가 수십 개 있다. updateQueue, lanes, flags 같은 것들.
fiber-serialization.ts에서 사용자에게 의미 있는 필드만 추출하고, 순환 참조를 끊고, 트리 깊이를 제한하는 직렬화 로직을 만들었다.
CSS 유사 셀렉터 엔진
query_selector 도구는 웹의 CSS 셀렉터처럼 React Native 컴포넌트를 찾는다:
DOM이 없으니 직접 셀렉터 파서와 매처를 구현했다. Fiber 트리를 탐색하면서 셀렉터에 맞는 노드를 찾는다.
지원하는 셀렉터:
- 타입:
Button,Text,View - 속성:
[title='로그인'],[testID='email-input'] - ID:
#email(testID 기반) - 자식:
View > Text - 자손:
View Text
네트워크 모니터링: XHR/Fetch 패치
React Native의 네트워크 요청을 가로채서 모니터링한다.
fetch도 마찬가지로 패치한다. 이렇게 하면 앱이 어떤 HTTP 클라이언트를 쓰든(axios, fetch, XHR) 모든 네트워크 요청이 기록된다.
network_mock: 네트워크 모킹
단순 모니터링을 넘어서, 특정 URL의 응답을 바꿔치기할 수도 있다.
에러 상황 테스트할 때 유용하다. 서버를 건드리지 않고 AI가 직접 에러 응답을 주입해서 앱의 에러 핸들링을 검증할 수 있다.
Babel 프리셋으로 런타임을 주입하고, React DevTools 글로벌 훅을 통해 Fiber 트리에 접근하여 컴포넌트 state까지 읽는 구조를 구현했다.