챗봇이 HTML을 내뱉기 시작했다

MCP를 좀 써본 사람이라면 누구나 같은 벽에 부딪힌다. “텍스트만으로는 부족하다”는 벽.

도구 호출 결과로 차트를 그리고 싶다. 폼을 띄우고 싶다. 캔버스에서 편집하게 하고 싶다. 근데 MCP 서버는 JSON만 반환한다. 그걸 유저가 직접 복사해서 다른 도구에 붙여넣어야 했다. 이게 에이전트 UX의 결정적 병목이었다.

이제 방법이 생겼다. MCP Apps 프로토콜. 모델컨텍스트프로토콜이 UI까지 확장됐다.

Claude가 Excalidraw를 채팅창에 바로 띄운다. ChatGPT가 실시간 코호트 히트맵을 보여준다. VS Code가 PDF 뷰어를 툴 결과로 렌더링한다. 이 모든 게 하나의 확장 스펙으로 통일됐다.

뭘 만들 수 있게 된 거지?

  • 차트/시각화 — cohort 히트맵, 고객 세그먼테이션 산점도, 실시간 시스템 모니터
  • 편집 캔버스 — Excalidraw 다이어그램, Three.js 3D 씬, 지도 뷰어 (CesiumJS)
  • 폼/대시보드 — 예산 할당기, 시나리오 모델러, 예측 시뮬레이터
  • 미디어 뷰어 — PDF 페이지별 로딩, 악보 렌더링, 실시간 자막, 비디오
  • 크리에이티브 — GLSL 셰이더 편집기, QR 생성기, TTS 데모

핵심은 하나다: 지금껏 JSON으로만 반환되던 툴 결과물이, 이제 인터랙티브 UI로 유저 앞에 렌더링된다. 유저는 복사/붙여넣기 없이 그 자리에서 보고, 클릭하고, 수정한다.

왜 MCP여야 했나

MCP는 이미 표준이다. Claude, ChatGPT, VS Code, Goose, Postman, MCPJam — 주요 AI 클라이언트가 MCP를 지원한다. MCP Apps는 이 인프라를 그대로 활용한다.

대안은 없었냐고? 두 가지 길이 있었다:

  • OpenAI Apps SDK: 오픈AI만의 독점 포맷. 다른 클라이언트에서 안 된다.
  • 커스텀 iframe 삽입: 매번 수동 구현. 표준도 없고, 보안도 제각각.

MCP Apps는 이걸 프로토콜 레벨에서 해결한다. 한 번 만들면 모든 호스트에서 동작한다. OpenAI Apps SDK로 만든 게 있다면 migrate-oai-app 스킬로 자동 변환도 된다.

동작 방식 — 생각보다 단순하다

기존 MCP와의 차이는 단 한 가지다. 툴이 ui:// 리소스를 선언할 수 있다는 점.

1. 툴 정의 시 HTML 인터페이스를 ui:// 리소스로 등록
2. LLM이 툴 호출
3. 호스트가 ui:// 리소스를 fetch → 샌드박스 iframe에 렌더링
4. UI ↔ 호스트 간 양방향 통신 (PostMessageTransport)
   - 호스트 → UI: 툴 결과 데이터 전달
   - UI → 호스트: 다른 툴 호출 요청

핵심은 PostMessageTransport다. UI가 샌드박스 안에 갇혀 있지만, 호스트와 메시지를 주고받으며 필요한 데이터를 요청하거나 다른 툴을 호출할 수 있다. 브라우저의 postMessage API를 추상화한 MCP 레벨의 통신 채널이다.

이 구조의 강점은 보안과 유연성을 동시에 잡는다는 점이다. UI는 샌드박스 안에서 실행되므로 악의적인 코드가 호스트를 공격할 수 없다. 반면 필요한 데이터는 통제된 채널로 주고받을 수 있다.

SDK 구성 — 네 개의 패키지

MCP Apps SDK는 역할별로 깔끔하게 분리되어 있다:

패키지 용도
@modelcontextprotocol/ext-apps UI 빌더용 — App 클래스, PostMessageTransport
@modelcontextprotocol/ext-apps/react React 훅 — useApp, useHostStyles
@modelcontextprotocol/ext-apps/app-bridge 호스트 임베더용 — 샌드박스 iframe 통신
@modelcontextprotocol/ext-apps/server MCP 서버에서 UI 리소스 등록

React만 되는 건 아니다. 예제 템플릿이 Vue, Svelte, Preact, Solid, Vanilla JS로 다 준비되어 있다. 자기 스택에 맞는 걸 고르면 된다.

직접 써보기

시작은 간단하다. npm 한 줄이면 끝:

npm install -S @modelcontextprotocol/ext-apps

전체 레포를 클론해서 로컬에서 예제를 돌려볼 수도 있다:

git clone https://github.com/modelcontextprotocol/ext-apps.git
cd ext-apps
npm install && npm start
# → http://localhost:8080/ 에서 16개 예제 실행

더 빠른 길도 있다. 이 레포는 4개의 Agent Skills를 제공한다. AI 코딩 에이전트한테 “MCP App 만들어줘”라고 말하면 바로 스캐폴딩해준다:

  • create-mcp-app — 새 MCP App 스캐폴딩
  • migrate-oai-app — OpenAI Apps SDK → MCP Apps 변환
  • add-app-to-server — 기존 MCP 서버에 UI 추가
  • convert-web-app — 웹 앱을 하이브리드 MCP App으로

MCP 지원 클라이언트(Claude Desktop, VS Code 등)에 등록하는 법은 간단하다:

{
  "mcpServers": {
    "map": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-map", "--stdio"]
    }
  }
}

이게 왜 중요한가

나는 이걸 보고 에이전트의 UX 패러다임이 바뀐다고 생각했다.

지금까지 AI 에이전트는 “도구를 호출하고 결과를 텍스트로 보여주는” 단계였다. 유저는 결과를 읽고, 이해하고, 필요하면 따로 앱을 열어서 처리해야 했다. 이건 에이전트라기보다 똑똑한 검색 엔진에 가깝다.

MCP Apps는 이걸 “도구가 UI를 직접 렌더링하고 유저가 그 자리에서 인터랙션하는” 단계로 끌어올린다. 유저는 채팅창을 떠날 필요가 없다. 모든 게 그 안에서 일어난다.

이게 에이전트가 애플리케이션을 대체하는 첫 번째 실제 신호라고 본다.

아직 갈 길은 멀다. 모든 호스트가 MCP Apps을 지원하는 건 아니다. 표준이 안정화되는 데는 시간이 걸릴 거다. 하지만 방향은 명확하다. AI는 더 이상 “말하는 기계”가 아니다. 무언가를 보여주고, 조작하게 하는 플랫폼이 되고 있다.

Drewgent에서도 이걸 활용할 방법을 고민 중이다. codebase-memory 그래프 쿼리 결과를 바로 시각화하거나, wordpress MCP의 편집 결과를 미리보기로 띄우거나. MCP Apps 시대가 열렸다. 늦게 뛰어드는 것보다 지금 시작하는 게 낫다.

관심 있으면 modelcontextprotocol/ext-apps 레포를 방문해보길. 2.6k 스타, 660 커밋, 16개 예제, 4개 스킬. 시작하기에 충분한 자료가 있다.

끝.