Debugging a black box: 36 renders against Claude, and the part where my own data was wrong
개요
MCP App 개발 중 발생하는 렌더링 실패 문제를 해결하기 위해 Claude.ai 웹 환경에서 36번의 실험을 진행한 경험을 공유하며, 디버깅 방법론과 잘못된 데이터 해석 사례를 제시합니다.
주요 내용
- MCP App 렌더링 실패 문제: 기술적인 오류 없이 HTML 위젯이 렌더링되지 않는 현상으로, 개발자가 서버가 명세에 맞게 동작함을 확인했음에도 불구하고 문제가 발생합니다.
- _meta.ui.domain 필드의 역할: 이 필드는 iframe의 샌드박스 오리진 안정성을 제어하며, 클라이언트가 연결한 URL과 일치하는 엔드포인트 URL을 해싱해야 올바르게 동작합니다. 불일치 시 렌더링에 실패합니다.
- 디버깅 방법론:
1. JavaScript가 필요 없는 시그널 제공: 모든 위젯 상단에 no-JS 스타일 블록(STATIC MARKER)을 추가하여 문서가 프레임 내에서 렌더링되었는지 여부를 직관적으로 확인할 수 있습니다.
2. 단일 변수만 변경: 다른 모든 요소는 동일하게 유지하고 테스트 중인 단일 필드만 변경하여 원인을 명확히 규명합니다.
3. 제어 환경 구축: 실제 대상에 적용하기 전, 로컬에서 명세에 맞는 하네스를 통해 앱의 동작을 확인합니다.
4. 프록시 측정 후 보정: iframe 높이를 렌더링 성공 여부를 판단하는 프록시로 사용하고, 실제 렌더링 결과와 비교하여 측정 기준을 보정합니다.
- 측정 결과 및 문제점:
- _meta.ui.domain 필드를 잘못 설정할 경우 iframe이 마운트되지 않는 것을 확인했습니다.
- 특정 시점에 6/10, 이후 0/18의 렌더링 실패가 발생했으나, 서버 로그에는 성공적인 리소스 읽기가 기록되어 원인이 호스트 측에 있음을 시사했습니다.
- 실험 중 _meta.ui.domain의 동작 방식에 대한 자신의 이해가 잘못되었음을 두 차례 발견했습니다. 하나는 "render당 생성"이라고 잘못 판단한 오리진 생성 방식이었고, 다른 하나는 페이지 로딩 실패를 렌더링 실패로 오인한 경우였습니다.
- 실용적인 조언:
- 위젯에 영구적으로 no-JS 정적 요소를 포함시켜 렌더링 실패와 마운트 실패를 구분합니다.
- _meta.ui.domain은 필요한 경우에만 설정하고, 클라이언트가 연결한 엔드포인트 URL을 정확히 해싱합니다.
- ui:// URI는 번들 변경 시 버전을 관리하고 이전 버전도 계속 제공합니다.
- 호스트 렌더링 버그는 호스트 트래커에 보고합니다.
- mcp-app-debug 도구를 활용하여 디버깅을 지원합니다.
시사점
MCP App 렌더링 문제는 _meta.ui.domain 필드의 정확한 설정과 no-JS 시그널, 단일 변수 변경, 보정된 프록시 측정을 포함한 체계적인 디버깅 접근 방식을 통해 효과적으로 진단할 수 있으며, 섣부른 데이터 해석은 잘못된 결론으로 이어질 수 있습니다.
댓글
GitHub Discussions