장치가 화면을 건넨다 — 보드 두 대가 각자 자기 정의를 준다
5 분앞 글에서 창이 두 개라고 했다. 사람이 기계를 직접 다루는 창은 MCP가 겨냥한 자리가 아니었고, 빠진 것은 화면이라고 했다.
이 글은 그 화면을 어디서 가져오느냐다.
전제 하나를 바꾼다
보통은 호스트가 화면을 안다. 어떤 장치가 어떤 값을 주는지, 그 값을 어떤 위젯으로 그릴지, 어떤 버튼이 어떤 명령을 보낼지를 앱이 알고 있다. 그래서 장치가 하나 늘면 앱을 고친다.
바꾸는 전제는 이것이다. 화면을 호스트가 아니라 장치가 정의한다.
장치는 이미 MCP 서버로서 자기 기능을 도구로 노출한다. 여기에 하나를 더한다 — 자기 화면을 선언적으로 서술한다. 클라이언트는 그 서술을 받아 네이티브로 그린다. 브라우저도, 내장 웹엔진도 필요 없다.
그러면 클라이언트는 무엇을 그릴지 미리 알 필요가 없다. 처음 보는 장치도 붙는 순간 다룰 수 있다.
책상 위의 두 대
이걸 말로 하면 그럴듯하게 들리고, 그래서 실물로 확인했다.
보드 두 대다. STM32H723은 USB 시리얼로 붙고, ESP32는 Wi-Fi로 붙는다. 발견 방식도 다르다 — 하나는 포트를 열어 찾고, 하나는 네트워크에서 찾는다. 전기적으로도 프로토콜 전송로도 서로 남남이다.
각 보드에 브리지가 붙어 자기 기능을 도구로 내놓고, 자기 화면을 리소스로 내놓는다. 그리고 클라이언트는 양쪽에 대해 동일하다. 보드별 분기가 없다.
화면이 뜬다. 버튼을 누르면 책상 위의 LED가 실제로 켜진다.
이 샘플에는 규칙이 하나 걸려 있다 — 보드가 없으면 통과시키지 않는다. 시뮬레이션으로 대체하지 않고, 어느 포트를 찾았는지 밝히고 실패로 끝낸다. 하드웨어 없이 "검증"되는 하드웨어 이야기는 검증된 것이 아니기 때문이다.
잡힌 것 하나 — 보드가 옳았다
이 샘플을 만들면서 실보드가 즉사한 적이 있다. 리소스 목록을 읽는 순간 타입 오류로 죽었다.
원인은 보드가 아니었다. 클라이언트 라이브러리가 스펙을 어기고 있었다. 리소스의 설명 필드는 MCP 스펙에서 선택인데, 라이브러리가 그것을 반드시 있는 값으로 읽고 있었다. 설명을 안 붙인 보드는 규격대로였고, 읽는 쪽이 틀렸다.
같은 라이브러리를 쓰는 다른 샘플 넷은 그 목록을 읽지 않아 멀쩡했다. 실물을 붙였을 때만 드러나는 자리다.

화면이 곧 로직이다
"화면을 내준다"고 하면 그림만 넘긴다는 뜻으로 들린다. 그렇지 않다.
서술 안에는 세 가지가 함께 들어간다.
- 바인딩 — 장치의 상태가 화면의 값으로 흘러든다
- 액션 — 상태 변경, 도구 호출, 묶음 실행, 그리고 조건 분기
- 구독 — 장치의 상태 변화를 계속 받는다
이 셋을 엮으면 제어가 된다. 온도 노드의 값을 구독하고, 그 값이 화면으로 흘러들고, 조건 분기가 임계를 판정해서, 팬 노드의 도구를 부른다. 센서와 팬을 각각 붙이기만 하면 되고, 둘을 잇는 코드를 따로 짜지 않는다.
제어를 위해 별도의 언어를 배우는 게 아니다. 화면을 선언하면 제어가 따라온다.
여기까지가 한 장치
한 장치가 자기 화면을 건네고, 그 화면이 곧 조작면이라는 데까지 왔다.
그런데 현장에는 장치가 하나만 있는 경우가 드물다. 조타실에는 발전기와 밸러스트와 연료가 같이 있고, 온실에는 센서와 밸브가 같이 있다.
여러 장치를 한 화면에 모으는 이야기는 두 글 뒤다. 그 전에, 이 구조에 설치라는 단위가 없다는 것을 먼저 적는다.
확인 과제
예제에 장치를 하나 더 붙여 보세요. 고친 파일을 모두 적어 보세요. 호스트가 그 목록에 있으면 안 됩니다.