Bỏ qua điều hướng

Hướng dẫn thêm giao diện cho MCP server với OpenAI

Triển khai MCP Apps để tích hợp UI tương tác vào ChatGPT: cấu hình Resource, metadata và đóng gói Single File HTML cho MCP server.

Tuan Tran Van
8 phút đọc
Mục lục (10 phần)
  1. Bước 1 — Tạo dự án và cài gói MCP Apps
  2. Bước 2 — Viết giao diện và nối với host bằng lớp App
  3. Bước 3 — Đóng gói giao diện thành một file HTML duy nhất (dành cho thành viên)
  4. Bước 4 — Đăng ký resource giao diện và gắn vào công cụ (dành cho thành viên)
  5. Bước 5 — Chạy server và xác nhận giao diện hiện ra (dành cho thành viên)
  6. Bước 6 — Kết nối vào ChatGPT và kiểm tra trong hội thoại (dành cho thành viên)
  7. Bảng tra nhanh metadata và API giao diện (dành cho thành viên)
  8. Xử lý sự cố thường gặp (dành cho thành viên)
  9. Bước tiếp theo (dành cho thành viên)
  10. Tài liệu tham khảo (dành cho thành viên)

Đi hết hướng dẫn này, bạn sẽ có một giao diện cho MCP server render ngay trong cửa sổ hội thoại ChatGPT: widget tương tác như bản đồ, biểu đồ động hay trình xem mô hình 3D, thay cho những dòng văn bản tĩnh.

Nền tảng là tiêu chuẩn MCP Apps. Nó dựng các thành phần giao diện trong một iframe bảo mật, cho phép người dùng thao tác thẳng trên dữ liệu thay vì chỉ nhận kết quả thô.

Trước khi bắt đầu, bạn cần Node.js 18 trở lên và đã quen với hai thành phần cơ bản Tools và Resources trong Model Context Protocol. Bạn cũng cần biết cách điều phối luồng dữ liệu giữa logic phía server và sandbox của host.

Mã nguồn hoàn chỉnh của dự án mẫu trong bài có sẵn trên GitHub: camnangai-public-sources/mcp-app-demo.

Widget giao diện tương tác do MCP server cung cấp hiển thị ngay trong khung hội thoại ChatGPT, bên cạnh phản hồi văn bản của mô hình

Bước 1 — Tạo dự án và cài gói MCP Apps

Kiến trúc MCP App tách bạch giữa logic xử lý dữ liệu và mã nguồn hiển thị: một bên là server Node.js/TypeScript, một bên là bundle giao diện chạy trong iframe. Cả hai nằm chung một dự án.

bash
mkdir mcp-app-demo && cd mcp-app-demo
npm init -y

Mở package.json và thêm "type": "module" để dùng được cú pháp ES module.

Cài các gói phụ thuộc:

bash
npm install @modelcontextprotocol/ext-apps @modelcontextprotocol/sdk express cors zod
npm install -D typescript tsx vite vite-plugin-singlefile @types/express @types/cors

expresscors là phụ thuộc chạy thật — server import chúng lúc khởi động — nên chúng thuộc dependencies, không phải devDependencies.

Thêm ba script vào package.json:

json
{
  "scripts": {
    "build": "vite build",
    "serve": "tsx server.ts",
    "dev": "INPUT=mcp-app.html npm run build && npm run serve"
  }
}

Đi hết hướng dẫn, cấu trúc dự án sẽ như sau:

text
mcp-app-demo/
├── package.json
├── tsconfig.json
├── vite.config.ts      # gộp giao diện thành một file HTML duy nhất
├── server.ts           # MCP server, đọc ./dist/mcp-app.html
├── mcp-app.html        # entry point của giao diện
└── src/
    └── mcp-app.ts      # logic phía giao diện

Thư viện ext-apps cung cấp các lớp cầu nối quản lý giao thức JSON-RPC qua postMessage, thiết lập kênh liên lạc an toàn giữa iframe và host ChatGPT.

Bước 2 — Viết giao diện và nối với host bằng lớp App

Frontend dùng lớp App từ SDK để đăng ký listener và truyền tin với host.

Cầu nối JSON-RPC qua postMessage giữa iframe giao diện và host ChatGPT: host đẩy kết quả tool xuống UI, UI gọi ngược tool phía server

  1. Tạo file src/mcp-app.ts.
  2. Khởi tạo kết nối và xử lý kết quả trả về từ tool:
typescript
import { App } from "@modelcontextprotocol/ext-apps";
 
const app = new App({ name: "My App", version: "1.0.0" });
app.connect();
 
// Xử lý dữ liệu từ thuộc tính structuredContent của kết quả tool
app.ontoolresult = (result) => {
  const data = result.structuredContent;
  if (data) {
    renderUI(data); // Logic hiển thị tùy chỉnh
  }
};
  1. Dùng app.callServerTool để kích hoạt hành động phía server khi người dùng tương tác trên UI.

Lớp App đóng gói phần truyền tin JSON-RPC qua postMessage, đảm bảo UI giao tiếp an toàn với host mà không vi phạm chính sách cùng nguồn gốc (Same-origin policy).

Đọc tiếp

Chia sẻ bài viết

X / TwitterFacebookLinkedIn