MCP 앱스(MCP Apps)와 제너레이티브 UI: 에이전트 응답을 인터랙티브 화면으로
MCP 서버를 만들고 나면 반드시 부딪히는 벽이 하나 있다. 도구는 잘 도는데 결과를 사람에게 보여주는 일이 계속 어색하다는 점이다. 배포 목록 30개를 표로 받고 싶었을 뿐인데 에이전트는 불릿 12줄로 요약하고, 설정 값 하나를 바꾸려면 프롬프트를 다시 써야 하고, 판단 근거를 확인하려면 원본을 따로 열어야 한다. 나는 이 문제를 한동안 “프롬프트를 잘 쓰면 되는 문제”로 착각했다. 실제로는 텍스트라는 출력 형식 자체의 한계였고, 해법은 프롬프트가 아니라 UI를 프로토콜의 일부로 끌어들이는 것이었다.
이 글은 MCP Dev Summit Seoul 2026에서 공개된 발표 자료를 참고해 재구성한 기술 문서다1. 행사 요약이 아니라 에이전트 응답에 화면을 붙인다는 결정을 엔지니어링 관점에서 끝까지 따라가 본 기록이며, 인용한 출처와 스피커 정보는 말미 References에 정리했다.
1. 텍스트의 벽: 왜 에이전트 응답에 화면이 필요한가
1.1 텍스트 벽(Wall of Text) 문제
LLM의 기본 출력은 토큰 스트림(Token Stream), 즉 1차원 문자열이다. 사람이 소비하는 정보는 그렇지 않다. 비용 비교는 표이고, 추세는 그래프이고, 위치는 지도다. 이 2차원 구조를 문장으로 펼치는 순간 정보 밀도가 급락한다. 항목이 10개를 넘으면 독자는 표를 머릿속에서 다시 그려야 한다.
비유하자면 콜센터 상담원이 화면을 보지 않고 전화로만 안내하는 것과 같다. “세 번째 탭에서 두 번째 항목을 누르시고, 거기서 파란 버튼을…” 정확하지만 소비 비용이 크다. 같은 상담원이 화면을 함께 보며 짚어주면 전달량이 완전히 달라진다.
이를 한 문장으로 압축하면 이렇다. “Sometimes, in case of wall of text problem, a picture is worth a thousand words.” 텍스트 벽은 미관 문제가 아니라 전달 실패다2.
1.2 텍스트 응답에서 잃는 네 가지
| 손실 | 내용 | 텍스트에서 무슨 일이 벌어지는가 |
|---|---|---|
| 구조(Structure) | 관계·비교·비중 | “A는 23%, B는 41%로 B가 A보다…” 문장 나열로 재구성 비용 발생 |
| 조작(Manipulation) | 파라미터를 바꿔보는 탐색 | 값을 하나 바꾸려면 프롬프트를 다시 작성해야 함 |
| 확인(Verification) | 근거(Evidence) 검증 | 판단 근거가 서술문 뒤로 숨음. 검증하려면 원본을 따로 열어야 함 |
| 후속 행동(Follow-up) | 결정 즉시 실행 | 답변 → 재프롬프트 → 도구 호출의 왕복이 매번 발생 |

특히 확인의 손실은 조용히 위험하다. 컴퓨터 비전 워크플로우에서는 이 상황이 더 날카롭다. “정확한 탐지가 틀린 답일 수 있다(A Correct Detection Can Still Be the Wrong Answer)” — 신뢰도는 높은데 그 작업에는 틀렸거나, 객체는 맞는데 연관 관계가 틀렸거나, 검토할 근거가 아예 없는 경우다. 세 경우 모두 눈으로 확인할 자료를 요청자에게 주지 않은 것에서 나온다3.
1.3 그래서 제너레이티브 UI(Generative UI)
제너레이티브 UI(Generative UI) 는 내용과 구성이 런타임에 AI 에이전트에 의해 결정되는 UI를 말한다. 개발자가 화면을 미리 그려두는 정적 대시보드가 아니라, 그 순간의 데이터와 의도에 맞춰 에이전트가 어떤 화면을 보여줄지 고른다.
정의에서 중요한 단어는 런타임(Runtime) 이다. 템플릿 엔진이 미리 정의된 화면 중 하나를 고르는 것과 다르다. 에이전트가 결과의 형태를 보고 어떤 표현(표·차트·폼·승인 패널)이 적합한지 결정한다는 뜻이다.
2. 제너레이티브 UI의 두 갈래: 선언적 vs 개방형
2.1 선언적 UI(Declarative UI)
에이전트가 구조화된 JSON 스키마를 반환하면 호스트(클라이언트)가 자기 고유의 네이티브 컴포넌트로 렌더링하는 방식이다. 이 계열의 대표 규격으로 json-render와 A2UI를 들 수 있다4.
- 에이전트가 내놓는 것은 “표를 그려라”, “3개 옵션 중 하나를 고르게 하라” 같은 의미 수준의 서술이다.
- 실제 픽셀은 호스트가 소유한다. 호스트가 다크 모드면 다크 모드로 그려진다.
- 표현 범위가 호스트가 제공하는 컴포넌트 카탈로그로 제한된다. 이 제한이 곧 안전장치이자 제약이다.
2.2 개방형 UI(Open-ended UI): MCP 앱스
반대편은 원시 HTML을 리소스로 그대로 배송하는 방식이다. MCP 앱스(MCP Apps)가 여기 속하며, 그 지향은 “max expressiveness”, 즉 표현력의 상한이 없다는 데 있다4.
- 서버가 마크업·스타일·스크립트를 한 문서로 묶어 보낸다.
- 클라이언트는 그것을 샌드박스 처리된 iframe에서 그대로 실행한다.
- 상상할 수 있는 어떤 인터랙션도 구현할 수 있다. 대신 HTML/CSS/JS 전체가 신뢰 경계 안으로 들어온다.
2.3 트레이드오프 비교
두 방식은 대체재가 아니라 서로 다른 비용 구조를 가진다. 선택 기준은 “무엇을 만들 수 있는가”보다 “무엇을 감당할 수 있는가”에 가깝다.
| 축 | 선언적 UI | 개방형 UI (MCP 앱스) |
|---|---|---|
| 표현력 | 호스트 컴포넌트 카탈로그 범위 | 사실상 무제한 |
| 보안 부담 | 낮음 (호스트가 그리므로 임의 코드 실행 없음) | 높음 (서드파티 코드 실행) |
| 이식성 | 높음 (호스트가 스타일·동작을 결정) | 호스트 구현에 따라 렌더 결과가 달라짐 |
| 룩앤필 일관성 | 호스트 UI와 자연스럽게 동일 | 호스트가 격리·봉합해야 함 |
| 클라이언트 지원 | 구현체별 지원 상황 상이 | 확장 지원 여부에 의존 |
| 구현 비용 | 스키마만 만들면 됨 | 프런트엔드 빌드·번들링 파이프라인 필요 |
| 디버깅 | 스키마 검증 문제로 좁혀짐 | 브라우저 런타임 디버깅 필요 |
실무 감각으로 요약하면 “호스트가 이미 잘 그릴 수 있는 것은 선언적으로, 도메인 지식이 있어야만 그릴 수 있는 것은 개방형으로” 간다. 비용 비교 표는 어느 호스트든 그릴 수 있으니 선언적이 맞고, GPU 클러스터 토폴로지나 노드별 자원 스케줄 히트맵은 도메인 특화 시각화이므로 개방형이 맞다.

3. MCP 앱스 확장의 위치와 계보
3.1 공식 MCP 확장 io.modelcontextprotocol/ui
MCP 앱스는 프로토콜 코어에 새로 추가된 메시지가 아니라 공식 MCP 확장(Official MCP Extension)이다. 확장 식별자는 io.modelcontextprotocol/ui이고, 서버가 채팅 안에서 직접 렌더링되는 인터랙티브 HTML 인터페이스를 반환할 수 있게 해준다4.
이 지위가 실무에서 중요한 이유는 두 가지다.
- 코어 호환성: 기존 Tool/Resource 구조와 역량 협상을 그대로 두고 역량만 얹는다. 새 전송 계층도 새 프로토콜도 아니다.
- 변동성: 확장은 코어보다 빠르게 진화하므로 지금 배운 규약이 내년에 그대로라 가정하면 안 된다. 그래서 뒤에서 폴백(Fallback) 설계를 필수 원칙으로 다룬다.
3.2 계보: MCP-UI와 OpenAI Apps SDK
MCP 앱스는 하늘에서 떨어진 규격이 아니다. MCP-UI와 OpenAI Apps SDK 위에 구축되었고, OpenAI와 Anthropic의 MCP 코어 메인테이너들이 MCP-UI 창시자들과 함께 저술했다4.
- 채팅 클라이언트 진영이 각자 다른 UI 규약을 밀었다면 서버 구현이 다시 $N \times M$으로 갈라졌을 것이다. 두 진영이 같은 리소스 규약에 합의한 것은 서버 한 번 구현으로 여러 호스트를 지원할 여지다.
- 동시에 SDK 계보를 이어받았다는 사실은 초기 규약이 특정 호스트의 구현 관례에 끌려갈 수 있다는 뜻이기도 하다. 표준 문서와 실제 클라이언트 구현을 항상 따로 확인해야 하는 이유다.
3.3 기존 프리미티브와의 관계
가장 중요한 통찰은 UI도 결국 리소스(Resource)다라는 점이다. 서버는 이미 리소스를 제공하는 컴포넌트이고, MCP 앱스는 그 리소스가 데이터가 아니라 실행 가능한 문서일 수 있게 확장한 것이다. 따라서 MCP 앱스는 Tool/Resource 프리미티브를 대체하지 않는다. 툴이 호출되고, 툴이 리소스를 지목하고, 호스트가 그 리소스를 뷰로 띄운다. 새로운 것은 호스트가 그 리소스를 어떻게 격리해 실행하는가에 대한 규약이다.
4. 아키텍처: Tool·Resource·Host·View
4.1 네 주체의 역할
| 주체 | 책임 |
|---|---|
| Tool | UI 리소스를 선언하고, 툴 호출 결과를 반환한다 |
| Resource | HTML·CSS·JavaScript를 제공한다 |
| Host | 툴을 호출하고, 리소스를 로드하고, 결과를 뷰에 전달한다 |
| View | 리소스를 샌드박스 iframe에서 실행한다 |
기존 MCP 토폴로지(Host–Client–Server)와 비교하면 View가 새로 등장한다는 점이 핵심이다. View는 서버도 클라이언트도 아니다. 호스트 안에서 격리 실행되는 서드파티 프런트엔드 코드다5.

4.2 툴 호출 한 번의 전체 흐름
기존 MCP 흐름에 UI 계층이 얹히는 지점을 표시하면 다음과 같다.
MCP 앱스 툴 호출 시퀀스:
1. LLM ──tools/call──► Host ──tools/call──► MCP Server (도메인 로직)
2. Host ◄── CallToolResult ──┐
├ content: "LLM용 텍스트"
├ structuredContent: "View용 JSON"
└ _meta.ui.resourceUri: "ui://my-mcp-app" ← UI 선언
3. Host ──resources/read──► MCP Server ── HTML 문서(text/html;profile=mcp-app)
4. Host: 샌드박스 iframe 생성 + 문서 주입 ──► View
5. View ──ui/initialize──► Host ──툴 결과 전달──► View (렌더링·인터랙션)
6. View ──툴 호출 요청──► Host ──► MCP Server (뷰가 스스로 툴 호출)
7. View ──ui/resource-teardown──► Host (뷰 정리)
1~2번이 결과 반환, 3~4번이 화면 자원 로딩, 5~6번이 뷰의 실행과 상호작용, 7번이 라이프사이클의 종료 지점이다.
4.3 이중 페이로드: content와 structuredContent
툴 호출 결과는 두 소비자에게 동시에 배달된다5.
| 필드 | 소비자 | 내용 |
|---|---|---|
content |
LLM | 자연어 텍스트. “무엇이 일어났는지”의 서술 |
structuredContent |
View | 렌더링용 JSON. 원본 데이터 구조 |
이 분리는 폴백(Fallback) 전략의 근간이다. UI를 지원하지 않는 클라이언트에서도 content가 있으므로 툴은 정상 동작한다. 그래서 세 가지 원칙이 강제된다.
content에는 항상 사람이 읽을 수 있는 완결된 텍스트를 넣는다. UI는 가산점이지 유일한 통로가 아니다.structuredContent에는 뷰가 필요로 하는 원본 데이터를 넣는다. 문장 요약을 넣으면 뷰가 쓸 수 없다.- 두 페이로드가 서로 다른 사실을 말하면 그건 버그다. 뷰에 3건이 보이는데
content가 2건이라고 하면, LLM과 사람이 서로 다른 현실을 보게 된다.
아래는 툴이 UI 리소스를 선언하고 두 페이로드를 반환하는 형태를 개념적으로 표현한 스케치다. 실제 SDK의 함수명·필드 배치는 구현체마다 다르므로 규약의 모양만 참고하자.
// 툴 선언 (개념 스케치)
{
"name": "list_deployments",
"description": "네임스페이스의 배포 목록을 조회한다",
"_meta": {
"ui": {
"resourceUri": "ui://ops-console/deployments",
"csp": { "connect": ["https://telemetry.internal.example"] }
}
}
}
// 툴 호출 결과 (개념 스케치)
{
"content": [
{ "type": "text",
"text": "prod 네임스페이스에서 배포 3건을 찾았다. 2건은 정상, 1건은 이미지 태그가 latest다." }
],
"structuredContent": {
"namespace": "prod",
"items": [
{ "name": "api", "replicas": 6, "tag": "v2.4.1", "status": "healthy" },
{ "name": "worker", "replicas": 4, "tag": "v1.9.0", "status": "healthy" },
{ "name": "batch", "replicas": 1, "tag": "latest", "status": "degraded" }
]
}
}
4.4 리소스 서빙 규약
| 항목 | 규약 |
|---|---|
| URI 스킴 | ui:// (예: ui://my-mcp-app) |
| MIME 타입 | text/html;profile=mcp-app |
| 문서 구성 | 마크업·스타일·스크립트를 한 문서로 번들 |
| 에셋 | 빌드 타임에 전부 인라인 (외부 CDN 참조 없음) |
| 네트워크 | 기본 deny-all CSP |
| 허용 도메인 | _meta.ui.csp로 화이트리스트 |
“빌드 타임에 모든 에셋을 인라인한다” 는 규칙이 눈에 띈다5. 프런트엔드 개발자에게는 제약으로 느껴지지만 서버 입장에서는 합리적이다. 외부 CDN에서 스크립트를 가져오는 순간 문서의 실행 내용을 서버가 통제할 수 없게 되고, deny-all 기본값도 무의미해진다. 결과적으로 MCP 앱은 번들러가 필수인 프런트엔드 산출물이 된다.
4.5 View는 모델이 아니라 브라우저 코드다
- 모델이 아니라 브라우저 JavaScript를 실행한다. 추론도 자연어 생성도 하지 않는다.
- 호스트에 접근할 때는 하나의
app객체를 통하고,window.postMessage위에 MCP의 JSON-RPC를 실어 교환한다. - 툴 호출 결과를 수신하고 스스로 툴을 호출할 수도 있다. (“다음 페이지” 버튼이 툴을 다시 부른다.)
- 라이프사이클은
ui/initialize에서 시작해ui/resource-teardown으로 끝난다5.
5. 유스케이스별 설계 가이드
생성형 UI가 실제로 쓰이는 패턴은 여섯 가지로 정리된다6. “무엇을 그리는가”가 아니라 “누가 무엇을 결정하는가” 기준으로 묶으면 설계가 명확해진다.
| 유스케이스 | 대표 컴포넌트 | 결정 주체 | 보완하는 손실 |
|---|---|---|---|
| 데이터 탐색·비교 | 표·차트·지도 | 사용자(탐색) | 구조 |
| 멀티옵션 설정 | 폼·설정 패널 | 사용자(입력) | 조작 |
| 실시간 모니터링 | 대시보드·상태 카드 | 시스템(갱신) | 구조·확인 |
| What-if 분석·시뮬레이션 | 인터랙티브 그래프 | 사용자(파라미터) | 조작 |
| 다단계 워크플로우 | 스테퍼·승인 패널 | 사용자(승인) | 후속 행동 |
| 인터랙티브 설명 | 인터랙티브 다이어그램·퀴즈 카드 | 사용자(이해) | 확인 |
5.1 읽기 중심: 탐색·모니터링·설명
데이터를 바꾸지 않고 보여주기만 하는 패턴이다. 안전하므로 파일럿에 적합하다.
- 탐색·비교는 선택 상태를 뷰가 소유한다. 서버를 다시 부르지 않고 클라이언트에서 처리할 수 있는 필터는 그렇게 처리한다.
- 모니터링은 갱신 주기가 생명이다. 뷰가 툴을 주기적으로 재호출하는 방식이 가장 단순하지만 호출 예산을 반드시 계산해 둔다.
- 인터랙티브 설명(다이어그램·퀴즈 카드)은 서버 부하가 거의 없고 보안 위험도 낮아 첫 도입 사례로 적합하다.
5.2 쓰기 중심: 설정·승인·워크플로우
상태를 바꾸는 패턴이다. UI가 편의 기능이 아니라 위험 통제 장치가 된다.
- 설정 폼은 값을 모으는 것까지가 뷰의 일이다. 검증·적용은 반드시 서버(툴)가 다시 한다.
- 승인 패널은 “무엇을 승인하는지”를 한 화면에 모아야 한다. 텍스트 승인은 승인 대상과 결과가 같은 메시지에 섞여 감사(Audit)가 어렵다.
- 스테퍼(Stepper)는 각 단계가 독립된 툴 호출이 되도록 쪼갠다. 거대한 툴 호출 하나로 5단계를 처리하면 중간 실패 시 롤백 지점이 사라진다.
5.3 계산 중심: What-if 시뮬레이션
파라미터를 바꿔 결과를 즉시 보는 패턴이다. 순수 계산이면 뷰 안에서 끝내고, 비용·자원 산정처럼 서버 지식이 필요하면 툴 재호출로 처리한다. 규칙은 하나다. 모델이 계산할 것과 뷰가 계산할 것을 나눈다. LLM에게 숫자 계산을 시키지 않고, 결정적 계산은 뷰의 코드나 서버 툴이 맡고 LLM은 해석과 다음 행동 제안을 맡는다.
6. 보안: 신뢰할 수 없는 HTML과 샌드박스 경계
6.1 위협 모델: UI 리소스가 곧 공격면
개방형 UI의 대가는 명확하다. 서버가 배송한 HTML은 제3자 코드이고, 그것이 사용자 브라우저에서 실행된다. 개념적으로 다음 위험이 생긴다5.
- 데이터 유출: 뷰가 호스트가 보유한 다른 컨텍스트를 읽어 외부로 전송하려는 시도
- 승인 UI 위조: 승인 패널을 서버가 그린다면, 서버가 “이미 승인됨”처럼 보이는 화면을 그릴 수 있다
- 클릭재킹·유도: 뷰 안의 조작이 사용자 의도와 다른 툴 호출로 이어지는 흐름
- 권한 상승: 뷰가 원래 의도하지 않은 툴을 호출
가장 미묘한 것은 두 번째다. 승인 패널을 뷰가 그리는 순간 승인의 시각적 표현과 승인의 권위가 분리된다. 뷰는 신호를 만들 뿐이고, 권위는 호스트와 서버가 가져야 한다.
6.2 격리 계층
| 계층 | 장치 | 방어 대상 |
|---|---|---|
| 실행 격리 | 샌드박스 iframe | 호스트 DOM·스토리지 직접 접근 |
| 네트워크 | 기본 deny-all CSP | 임의 도메인 통신·유출 |
| 허용 목록 | _meta.ui.csp 화이트리스트 |
필요한 도메인만 최소 개방 |
| 자원 통제 | 빌드 타임 에셋 인라인 | 외부 스크립트 삽입 |
| 메시지 중계 | 호스트가 뷰↔서버 메시지 전부 중계 | 감사 지점 단일화, 직접 통신 차단 |
마지막 항목이 아키텍처적으로 가장 우아하다. 모든 메시지가 호스트를 통과한다는 것은 호스트가 단일 감사 지점(Single Audit Point)이 된다는 뜻이다. 뷰가 어떤 툴을 어떤 인자로 호출했는지 호스트 레벨에서 전수 기록할 수 있다.
6.3 운영 통제 체크리스트
- UI 리소스도 코드 리뷰·정적 스캔 대상에 포함한다. 프런트엔드 산출물이라고 예외를 두지 않는다.
- CSP 화이트리스트는 최소 집합으로 유지한다. 편의를 위해 넓히면 격리 계층 하나가 무력화된다.
- 승인 결과는 서버가 재검증한다. 뷰가 보낸 “승인됨” 플래그를 신뢰하지 않는다.
- 뷰가 호출 가능한 툴 집합을 화이트리스트로 제한한다. 파괴적 툴은 호스트 승인 경로로만 접근하게 한다.
- 감사 로그에 뷰 식별자·툴·인자·사용자 결정을 함께 남긴다.
- UI 문서의 버전과 해시를 기록한다. 리소스가 바뀌면 그 화면에서 내려진 결정의 신뢰도가 달라진다.
7. 확장 프리미티브 지도와 도입 판단
7.1 네 역량의 분업
컴퓨터 비전 워크플로우를 MCP 역량에 매핑하면 네 확장 프리미티브의 역할이 이렇게 나뉜다3.
- Tools는 일을 호출한다 (Tools invoke work)
- Resources는 데이터와 증거를 나른다 (Resources carry data and evidence)
- Tasks는 긴 작업을 추적한다 (Tasks track long work)
- Apps는 시각적 검토를 지원한다 (Apps support visual review)
7.2 확장 프리미티브 전체 지도
CV 라이프사이클 10단계에 네 역량을 매핑하면 다음과 같다. Apps가 언제 붙는지를 보는 것이 이 글의 목적에 맞다3.
| # | 단계 | 사용 역량 | 대상 |
|---|---|---|---|
| 01 | Capture | Tools | camera · stream · files |
| 02 | Curate | Tools, Resources | dataset · version · split |
| 03 | Label | Tools, Resources, Apps | annotation · review |
| 04 | Train | Tools, Tasks | weights · long job |
| 05 | Evaluate | Tools, Resources, Tasks, Apps | metrics · slices · errors |
| 06 | Deploy | Tools | workflow · device · API |
| 07 | Infer | Tools, Resources, Tasks | image · video · batch |
| 08 | Monitor | Tools, Resources | latency · drift · incidents |
| 09 | Investigate | Tools, Resources, Apps | compare · explain · trace |
| 10 | Review | Resources, Apps | approve · correct · feed back |
표에서 읽어야 할 패턴은 두 가지다.
- Apps는 첫 단계에 없다. 검토 대상이 생기는 03 Label 단계부터 등장한다. UI는 파이프라인의 시작이 아니라 판단이 필요한 지점에 붙고, 뷰가 그릴 데이터(증거)인 Resources와 항상 함께 온다.
- 앞 5단계와 뒤 5단계의 성격이 다르다. 앞은 역량 구축(data → model candidate), 뒤는 운영과 학습(prediction → next dataset question)이다. 도입 순서를 정할 때 뒤쪽(운영·검토)이 먼저인 경우가 많다. 이미 데이터가 있고 사람의 판단이 병목인 경우가 흔하기 때문이다.
7.3 무엇이 여전히 MCP 밖에 있는가
공개된 Vision MCP 서버들을 조사해 보면 MCP가 실제로 표준화하는 것과 그렇지 않은 것이 구분된다7.
| 구분 | 내용 |
|---|---|
| 표준화하는 것 | 툴 발견, 미디어·데이터셋이 URI/참조로 들어오는 경로, 구조화된 결과·클립·크롭·아티팩트 반환 |
| 표준화하지 않는 것 | 비즈니스 수용과 프로덕션 승인 권한, 서빙·런타임 모니터링, 최종 승인 행동, 보안 경계와 배포 정책, 데이터셋 수명주기, 데이터 거버넌스 규칙 |
결론은 명확하다. MCP 앱은 “검토의 인터페이스”이지 “승인의 권위”가 아니다. 화면이 승인 버튼을 그려줄 수는 있어도, 그 승인이 프로덕션에 효력을 갖게 하는 것은 MCP 바깥의 권한 시스템이다. 6장의 “승인 권위를 호스트·서버에 두라”는 원칙이 여기서 한 번 더 확인된다.
7.4 성숙도와 도입 판단
MCP 앱스는 확장(Extension) 이라는 지위를 가지며, 그 함의는 다음과 같다.
| 항목 | 함의 |
|---|---|
| 규약 안정성 | 코어보다 변동이 빠르다. 초기 규약을 하드코딩하지 않는다 |
| 클라이언트 지원 | 호스트별 지원 격차가 존재한다. 지원 매트릭스를 직접 확인해야 한다 |
| 생태계 | MCP-UI·OpenAI Apps SDK 자산을 재사용할 수 있다 |
| 폴백 | 필수. content에 텍스트를 항상 넣으면 UI 미지원 환경에서도 동작한다 |
도입 판단은 세 질문으로 압축된다. 첫째, 텍스트로 충분한가? 그렇다면 UI를 만들지 않는다. 대부분의 사내 툴은 여기서 끝난다. 둘째, 표현이 호스트 카탈로그로 커버되는가? 그렇다면 선언적 UI로 간다. 셋째, 도메인 특화 인터랙션이 필요한가? 그렇다면 개방형 UI를 검토하되 프런트엔드 빌드·보안 리뷰·클라이언트 지원 확인 비용을 예산에 넣는다.
실무 적용: 사내 도구를 MCP 앱으로 전환하기
앞의 내용을 사내 프로덕션 AI 플랫폼(사내 MCP 서버·에이전트 도구 운영, Azure·Kubernetes 기반 배포, LLM/RAG 서비스 운영) 맥락으로 내려본다.
8.1 전환 판단 표
어떤 툴을 어떤 방식으로 보여줄지를 툴 인벤토리에 그대로 적용한다.
| 판단 축 | 텍스트 응답 유지 | 선언적 UI | 개방형 UI (MCP Apps) |
|---|---|---|---|
| 응답 형태 | 문장으로 충분 (상태 확인, 단일 값) | 표·목록·단순 폼 | 도메인 특화 시각화, 복잡한 인터랙션 |
| 사용자 편집 필요성 | 없음 | 값 입력·선택 | 다단계 편집, 그래프 조작 |
| 근거 검증 필요성 | 낮음 | 중간 (표·차트로 확인) | 높음 (이미지·토폴로지·히트맵 검토) |
| 클라이언트 지원 | 무관 | 비교적 넓음 | 확장 지원 호스트 필요 |
| 보안 부담 | 없음 | 낮음 | 높음 (샌드박스·CSP·리뷰) |
| 구현 비용 | 0 | 스키마 정의 | 프런트엔드 번들 파이프라인 |
| 권장 순서 | 기본값 | 2순위 | 3순위 (검증 후) |
우선순위 규칙은 단순하다. 텍스트로 충분하면 텍스트, 표현이 카탈로그로 커버되면 선언적, 도메인 지식이 있어야만 그릴 수 있으면 개방형. 이 순서를 뒤집으면 비용이 먼저 터진다.
8.2 승인·설정 패널 패턴
사내에서 수요가 가장 큰 것이 “배포 승인”과 “설정 변경”이다. 다음 5단계를 표준 패턴으로 쓴다.
- 계획과 실행을 분리한다.
plan_deployment와apply_deployment를 별도 툴로 만든다. 뷰는 계획 툴의 결과만 그린다. - 계획 툴이 패널 데이터를
structuredContent로 반환한다. 이미지 태그, 레플리카 수, 리소스 요청량, 변경 항목 diff를 구조로 담는다. - 뷰는 선택·수정만 담당한다. 적용 버튼은 승인 요청(툴 호출)을 만들 뿐, 스스로 상태를 바꾸지 않는다.
- 서버가 재검증 후 실행한다. 인자 유효성, 권한, 정책 위반을 다시 확인한다. 뷰가 보낸 값은 “제안”일 뿐이다.
content에 텍스트 요약을 항상 넣는다. UI를 못 쓰는 클라이언트에서도 사람이 읽고 승인할 수 있어야 한다.
핵심은 뷰가 그리는 승인 화면과 실제 권한 검증이 분리된다는 점이다. 3단계에서 뷰는 신호만 만들고 4단계에서 서버가 권위를 행사한다5.
8.3 대시보드·모니터링 연동
가장 흔한 실수는 기존 대시보드를 iframe에 통째로 넣으려는 것이다. CSP가 기본 deny-all이라 외부 도메인을 열어야 하고 격리 계층이 약해지며, 대시보드 인증 토큰이 뷰에 노출되거나 iframe 안에서 로그인 흐름이 깨지고, 무거운 대시보드가 응답 지연을 키운다.
권장 패턴은 “요약 카드 + 딥링크” 다.
| 대상 | 뷰에 넣을 것 | 딥링크로 뺄 것 |
|---|---|---|
| 서비스 상태 | 상태 카드, 에러율 스파크라인, SLO 잔여 예산 | 상세 대시보드, 로그 탐색 |
| 배포 현황 | 네임스페이스별 배포 표, 이상 항목 강조 | 배포 이력, 롤백 콘솔 |
| RAG 품질 | 최근 질의 성공률, 검색 실패 상위 질의 | 청크 뷰어, 평가 리포트 |
| 비용 | 일별 추이 미니 차트, 예산 대비 사용률 | 리소스별 상세 청구 |
| 클러스터 자원 | GPU 할당률, 대기 중 워크로드 수 | 노드 상세, 스케줄러 이벤트 |
Kubernetes·Azure 배포 시 운영 노트를 함께 둔다.
- MCP 서버는 다른 사내 서비스와 같이 컨테이너 이미지 + Ingress로 배포한다. UI 리소스는 이미지에 빌드 타임에 인라인되므로 정적 파일 서버가 따로 필요 없다.
- CSP 화이트리스트에는 사내 텔레메트리 도메인만 넣는다. 퍼블릭 CDN은 넣지 않는다.
- 뷰의 툴 호출·렌더 실패를 Application Insights 등으로 계측한다. 뷰는 호스트 내부에서 돌기 때문에 실패가 조용히 사라지기 쉽다.
8.4 파일럿 시나리오와 성공 지표
처음부터 여러 툴을 UI로 바꾸지 않는다. 위험이 낮고 효과가 측정되는 세 개만 고른다.
| 시나리오 | 방식 | 위험 | 기대 효과 | 핵심 지표 |
|---|---|---|---|---|
| A. 배포 승인 패널 | 개방형 UI | 중간 | 오승인 감소, 승인 소요 단축 | 승인 소요 시간, 오승인율, 롤백 건수 |
| B. RAG 검색 결과 탐색기 | 선언적 UI | 낮음 | 근거 확인 시간 단축 | 근거 확인까지 걸린 왕복 횟수 |
| C. 인프라 비용 What-if | 개방형 UI | 낮음 | 의사결정 품질 향상 | 시나리오 비교 횟수, 재질의 횟수 |
지표는 UI 도입 전후를 비교할 수 있어야 하므로 도입 전 한 달치 베이스라인을 먼저 기록한다. 함께 측정할 항목은 다음 네 가지다.
- 왕복 프롬프트 수 감소: 같은 작업을 끝내는 데 필요한 프롬프트 수. UI의 가장 직접적인 효과다.
- UI 폴백 비율:
content만 소비된 비율. 높으면 지원 호스트가 부족하거나 UI 가치가 낮다는 신호다. - 태스크 완료율 / 뷰 에러율: 툴 호출 후 실제로 작업을 끝냈는지, 렌더·툴 재호출이 실패하지 않았는지. 뷰 에러는 조용한 실패를 잡는 유일한 지표다.
8.5 도입 체크리스트
설계 단계
- 툴 인벤토리를 8.1 표에 넣어 텍스트/선언적/개방형을 분류했는가
- 개방형으로 간 툴마다 “텍스트 폴백”이
content에 들어가는가 - 툴 결과의 두 페이로드(
content·structuredContent)가 서로 모순되지 않는가 - 계획/실행 툴이 분리되어 있는가
- UI 없이도 툴이 정상 동작하는가 (지원 호스트 확인 전 기본 동작)
보안 단계
- UI 리소스가 코드 리뷰·정적 스캔 대상에 포함되었는가
- CSP 화이트리스트가 최소 집합인가
- 승인 결과를 서버가 재검증하는가
- 뷰가 호출 가능한 툴이 화이트리스트로 제한되었는가
- 감사 로그에 뷰 식별자·툴·인자·사용자 결정이 남는가
운영 단계
- 뷰 렌더 실패·툴 호출 실패가 텔레메트리로 수집되는가
- UI 문서 버전(해시)이 배포 버전과 함께 기록되는가
- 클라이언트 지원 매트릭스를 문서화하고 주기적으로 갱신하는가
- 파일럿 성공 지표(8.4)의 베이스라인을 확보했는가
8.6 무엇부터 할 것인가
| 단계 | 작업 | 노력 | 효과 |
|---|---|---|---|
| 1주차 | 툴 인벤토리 분류(8.1), 베이스라인 지표 수집 시작 | 낮음 | 높음 (판단 근거 확보) |
| 2~3주차 | 안전한 읽기 툴 1개를 선언적 UI로 전환 (시나리오 B) | 낮음 | 중간 |
| 4~6주차 | 승인 패널 파일럿 (시나리오 A), 감사·재검증 경로 구축 | 중간 | 높음 |
| 7주차 이후 | 뷰 텔레메트리 대시보드, 지원 매트릭스 문서화 | 낮음 | 중간 |
순서의 요지는 “읽기 → 쓰기, 선언적 → 개방형” 이다. 승인 패널(쓰기)을 먼저 하면 보안 요구사항이 한꺼번에 몰려와 프로젝트가 멈춘다.
References
-
행사 정보 — MCP Dev Summit Seoul 2026 (Linux Foundation). 행사 페이지: https://events.linuxfoundation.org/mcp-dev-summit-seoul/, 스케줄: https://mcpseoul2026.sched.com/ ↩
-
“Operating an AI Infrastructure Through MCP Apps on Agents” — 문현경(HyounKyoung “Jimmy” Moon), AI Agentic Lead, 래블업(Lablup). MCP Dev Summit Seoul 2026. 세션 필요성(텍스트 벽) 슬라이드. ↩
-
“When AI Agents Need Eyes: What MCP Can and Cannot Standardize for Computer Vision” — Seowoo Han, Computer Vision Engineer, B GARAGE · Codex Ambassador. MCP Dev Summit Seoul 2026. MCP 역량(Tools·Resources·Tasks·Apps)과 컴퓨터 비전 라이프사이클 매핑 슬라이드. ↩ ↩2 ↩3
-
같은 세션 — Generative UI 정의(선언적: json-render·A2UI / 개방형: MCP Apps)와 MCP Extension(
io.modelcontextprotocol/ui, MCP-UI·OpenAI Apps SDK 계보) 슬라이드. ↩ ↩2 ↩3 ↩4 -
같은 세션 — Architecture(Tool·Resource·Host·View,
_meta.ui.resourceUri,ui://스킴, MIMEtext/html;profile=mcp-app, deny-all CSP와_meta.ui.csp,content·structuredContent이중 페이로드, 샌드박스 iframe,window.postMessage기반 JSON-RPC,ui/initialize~ui/resource-teardown) 및 Features 슬라이드. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 -
같은 세션 — Use Cases 슬라이드. 데이터 탐색·비교, 멀티옵션 설정, 실시간 모니터링, What-if 분석, 다단계 워크플로우, 인터랙티브 설명의 여섯 패턴. 슬라이드가 인용한 참고 문서: https://developers.openai.com/plugins/build/chatgpt-ui ↩
-
같은 세션 — 공개 Vision MCP 지형과 “MCP가 표준화하지 않는 것” 슬라이드. 조사 기준 시점은 발표 자료에 명시된 2026-08-12이며, 지형은 빠르게 변하므로 인용 시 재확인이 필요하다. ↩
댓글남기기