소식

실물 두 대가 스펙 위반을 찾아냈다

작성: makemind · 2026년 7월 31일

7월 마지막 주. 이번 주는 시뮬레이터가 없다. 검증도 보드가 없으면 통과하지 않는다.

이번 주 Signal

보드가 자기 화면을 건넸다.보드가 자기 화면을 건넨다」는 책상 위 STM32H723을 USB 시리얼로, ESP32를 mDNS로 찾아 Wi-Fi TCP로 붙였다. 두 보드가 각자 화면 정의를 내주고, 버튼을 누르면 LED가 실제로 켜진다. 클라이언트 코드는 두 경우에 한 글자도 다르지 않다 — 바뀌는 건 어느 브리지 프로그램을 띄우느냐뿐이다.

같은 칩에 세 단말이 붙었다.칩 하나에 붙이면」은 매장의 결제기 옆에 서버 하나를 세우고 태블릿·PC·주방 화면을 붙인다. 세 기기 어디에도 앱을 만들지 않았고, 카드 승인 경로는 한 줄도 건드리지 않았다.

도구·패키지 메모

이번 주의 진짜 소득은 기사가 아니라 찾은 결함이다. 실보드에 붙자 listResources()가 즉사했다.

type 'Null' is not a subtype of type 'String' in type cast

처음엔 보드를 의심했다. 그런데 MCP 스펙에서 resource 의 description 은 선택이고, 보드는 그걸 안 보냈을 뿐이다. 보드가 맞았다. mcp_client 1.1.1이 그 필드를 비-널로 캐스트하고 있었고, 2.1.0에는 이미 고쳐져 있었다.

왜 지금까지 안 보였나. listResources()를 부르는 소비자가 드물기 때문이다. initialize → tools/list → tools/call → resources/read만 도는 경로는 그 코드를 안 탄다. 스펙에서 선택인 필드를 필수로 받는 파서는, 스펙을 지킨 상대를 만나야만 죽는다. 그리고 그 만남은 대개 실물이 연결되는 날에 온다.

짧은 생각

시뮬레이터는 대개 우리가 짠 대로 답한다. 그래서 우리가 잘못 이해한 지점을 그대로 통과시킨다. 이번 주에 확인한 건 성능도 편의도 아니고 그거다 — 실물은 우리 착각에 동의해 주지 않는다.

다음 달

현장 단말로 내려간다. 대기줄, 창고 동선, 교대 인수인계, 전산이 끊긴 계산대.


makemind.dev 「소식」 — 매주 한 번, 그 주에 무엇이 올라갔고 만들면서 무엇이 걸렸는지.

Twitter