MCP 서버에서 이제 시각적 UI가 가능해졌습니다
Source: Dev.to

MCP 서버는 이제 Claude Desktop 채팅 창에서 직접 인터랙티브 UI를 렌더링할 수 있습니다. 단순 텍스트 응답이 아니라 실제 HTML, JavaScript, 지도, 차트 등 모든 것이 가능합니다.
변경 사항
@modelcontextprotocol/ext-apps 라이브러리는 MCP 도구가 시각 UI를 반환하도록 합니다. 도구를 호출하면 텍스트만 받는 것이 아니라 대화에 인라인으로 렌더링되는 인터랙티브 iframe을 받게 됩니다.
이는 AI 어시스턴트가 단순히 설명하는 것이 아니라 실제로 보여줄 수 있음을 의미합니다.
Resources
Source: …
작동 방식
아키텍처는 두 부분으로 구성됩니다: 데이터를 가져오고 UI를 선언하는 서버와 이를 렌더링하는 클라이언트‑사이드 앱.
서버 측
UI 메타데이터가 포함된 도구를 HTML 리소스에 연결하여 등록합니다:
import { registerAppTool, registerAppResource } from "@modelcontextprotocol/ext-apps/server";
const resourceUri = "ui://iss-tracker/mcp-app.html";
// UI 리소스(번들된 HTML) 등록
registerAppResource(server, resourceUri, "text/html", () => APP_HTML);
// UI 메타데이터와 함께 도구 등록
registerAppTool(server, "where_is_iss", {
description: "실시간 지도에 ISS 위치 표시",
uiResourceUri: resourceUri,
csp: {
connectDomains: ["https://*.openstreetmap.org", "https://unpkg.com"],
resourceDomains: ["https://*.openstreetmap.org", "https://unpkg.com"],
},
execute: async () => {
const [iss, path, geo] = await Promise.all([
fetch("https://api.wheretheiss.at/v1/satellites/25544").then(r => r.json()),
fetch(`https://api.wheretheiss.at/v1/satellites/25544/positions?timestamps=${timestamps}`).then(r => r.json()),
fetch("http://ip-api.com/json/").then(r => r.json()),
]);
return { iss, path, user: { latitude: geo.lat, longitude: geo.lon, city: geo.city } };
},
});
csp 필드는 매우 중요합니다—UI가 접근해야 하는 외부 도메인을 선언합니다. 이를 지정하지 않으면 Leaflet 타일과 스크립트가 차단됩니다.
클라이언트 측
UI는 도구 결과를 받아서 렌더링합니다:
import { App } from "@modelcontextprotocol/ext-apps";
const app = new App({ name: "ISS Tracker", version: "1.0.0" });
app.ontoolresult = (result) => {
const data = result.structuredContent;
// 데이터를 사용해 UI 업데이트
updateMap(data.iss, data.user);
};
app.connect();
핵심 주의사항: 동적 스크립트 로딩
정적 <script> 태그는 srcdoc iframe에서 작동하지 않습니다. 외부 라이브러리를 동적으로 로드해야 합니다:
async function loadLeaflet(): Promise<void> {
if (typeof L !== "undefined") return;
// CSS 로드
const cssLink = document.createElement("link");
cssLink.rel = "stylesheet";
cssLink.href = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css";
document.head.appendChild(cssLink);
// JS 로드
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js";
script.onload = () => resolve();
script.onerror = () => reject(new Error("Failed to load Leaflet"));
document.head.appendChild(script);
});
}
많은 개발자가 이 부분에서 난관을 겪었습니다—Leaflet은 이렇게 주입하지 않으면 로드되지 않습니다.
직접 해보세요
git clone https://github.com/JasonMakes801/iss-tracker-mcp
bun install && bun run build
Claude Desktop 설정에 추가 (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"iss-tracker": {
"command": "/path/to/bun",
"args": ["/path/to/iss-tracker/dist/index.js", "--stdio"]
}
}
}
- Claude Desktop을 재시작합니다.
- 다음과 같이 물어보세요: “ISS는 어디에 있나요?”
다음은 무엇인가요
지도는 시작에 불과합니다. 대시보드, 차트, 양식, 데이터 시각화—HTML로 만들 수 있는 모든 것이 이제 AI 대화 안에서 실현될 수 있습니다.
당신은 이것으로 무엇을 만들고 싶나요?
