# MCP Apps là gì? Build app chạy ngay trong Claude và ChatGPT

[Ashita Prasad](https://homus.dev/speakers/ashita-prasad) · [AWS Developers](https://homus.dev/orgs/aws-developers)

> Build ba MCP app (form, dashboard Chart.js, PDF) chạy trong Claude Desktop bằng MCP Apps SDK, rồi deploy MCP server lên Amazon Bedrock AgentCore.

Topics: Dev Tools, AI UX, Agents

Canonical: https://homus.dev/talks/what-are-mcp-apps-building-apps-that-run-on-claude-chatgpt

## 1. Từ một bức tường chữ tới UI ngay trong chat

Ashita mở đầu bằng một câu hỏi: bạn đã bao giờ hỏi AI assistant của mình để lấy insight, rồi nhận về một bức tường chữ (a wall of text) chưa? Khi hỏi insight, bạn không muốn một đoạn mô tả bằng chữ. Bạn muốn thứ gì đó tương tác hơn, như chart, hay thậm chí một dashboard mà bạn lọc được.

Trên màn hình, chị cho xem nhanh cảnh đó: một cửa sổ chat với câu "get sales data", rồi ngay sau đó là một dashboard có biểu đồ cột chồng, biểu đồ tròn và biểu đồ thanh ngang nằm ngay trong khung trò chuyện (demo trong video đăng ngày 20/10/2026).

Lập luận của chị: chúng ta đã build những trải nghiệm người dùng tuyệt vời cho web suốt nhiều năm. Vậy tại sao không mang chúng vào trong chat luôn? Theo Ashita, đây là lúc MCP Apps tới "giải cứu" (video đăng ngày 20/10/2026).

![Thẻ tiêu đề What are MCP Apps? Building apps that run on Claude & ChatGPT!](https://homus.dev/photos/Wiun7ZGu-Ks-0054.jpg)

Thẻ tiêu đề của video: "What are MCP Apps?", bên dưới là dòng "Building apps that run on Claude & ChatGPT!" (video đăng ngày 20/10/2026).

## 2. MCP Apps là gì và bốn khối xây dựng

Theo Ashita (video đăng ngày 20/10/2026), MCP Apps là một extension của core MCP specification, lấy cảm hứng từ MCP UI và Apps SDK của OpenAI. Nó cho phép bạn thêm một lớp UI vào MCP mà agent có thể render, tạo ra những giao diện người dùng tương tác và điều khiển được ngay bên trong chat.

Nhờ MCP Apps, chị nói, MCP server của bạn có thể hiển thị dashboard tương tác, form, visualization và kết quả real-time trực tiếp trong cuộc trò chuyện (theo video đăng ngày 20/10/2026). Trang tài liệu MCP Apps trên modelcontextprotocol.io cũng mô tả tương tự: server trả về giao diện HTML tương tác (data visualization, form, dashboard) render thẳng trong chat (đọc ngày 27/10/2026).

![Slide MCP Apps với nhiều màn hình điện thoại: công thức nấu ăn, so sánh điện thoại, bản đồ đạp xe, chart cổ phiếu, nhà cho thuê, sự kiện, học tiếng Pháp](https://homus.dev/photos/Wiun7ZGu-Ks-0101.jpg)

Slide "MCP Apps" với các ví dụ minh hoạ trong một app chat: thẻ công thức nấu ăn, bảng so sánh hai điện thoại, bản đồ lộ trình đạp xe, chart giá cổ phiếu, danh sách nhà cho thuê, vé sự kiện và một bài quiz tiếng Pháp, mỗi thứ là một UI nằm trong câu trả lời (video đăng ngày 20/10/2026).

Theo chị (video đăng ngày 20/10/2026), một MCP app được ghép từ bốn khối xây dựng:

- **UI resource**: định nghĩa giao diện (video đăng ngày 20/10/2026).

- **Tool logic**: phần làm việc thật (video đăng ngày 20/10/2026).

- **Host**: nơi chạy tất cả (video đăng ngày 20/10/2026).

- **App view**: nơi người dùng thấy app "sống dậy" (video đăng ngày 20/10/2026).

Chị sẽ đi qua từng khối một.

## 3. Tạo MCP server và bài toán sales analytics

Trước khi vào từng khối, theo Ashita (video đăng ngày 20/10/2026), ta phải import class `McpServer` từ MCP TypeScript SDK chính thức. Class này là API cấp cao để build server, lo hết phần plumbing của giao thức MCP. Ta tạo server instance với một name và một version, rồi bọc việc khởi tạo đó trong một factory function, để nơi gọi có thể tạo server instance mới bất cứ lúc nào cần.

![File server.ts: import McpServer và hàm createServer](https://homus.dev/photos/Wiun7ZGu-Ks-0134.jpg)

File `server.ts`: import `McpServer` từ `@modelcontextprotocol/sdk/server/mcp.js`, rồi hàm `createServer()` tạo server tên `sample-mcp-apps-chatflow`, version `1.0.0` (video đăng ngày 20/10/2026).

```
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

export function createServer(): McpServer {
const server = new McpServer({
name: "sample-mcp-apps-chatflow",
version: "1.0.0",
});

return server;
}
```

Ví dụ xuyên suốt video là sales analytics. Ashita giải thích (video đăng ngày 20/10/2026): vì ta build MCP apps để hỗ trợ phân tích doanh số, app thứ nhất cần có là một input form, giúp lấy đúng dữ liệu sales theo metric, khoảng thời gian, năm và vùng bán hàng.

Chị nói tiếp: bạn có thể thấy MCP apps biến AI chat từ một phương tiện chỉ có chữ thành thứ gần với trải nghiệm của một app thật. Theo chị, khi agent gọi MCP tool, server sẽ không chỉ trả về dữ liệu hay kết quả, mà trả về cả một mini app HTML (video đăng ngày 20/10/2026).

![Form Select Metrics and Regions trong Claude Desktop, ba bang đã được chọn](https://homus.dev/photos/Wiun7ZGu-Ks-0243.jpg)

Sau câu "get sales data", tool `select-sales-metric` của server `sample-mcp-apps-chatflow` hiện form "Select Metrics & Regions": metric Total Revenue, Monthly, năm 2025, ba bang Maharashtra, Tamil Nadu, Karnataka đã được tick, nút Submit và dòng xanh "Added to chat context" (demo trong video đăng ngày 20/10/2026).

## 4. UI resource: một mini app gói trong một file HTML

Việc mở màn của phần build là tạo và đăng ký UI resource. Theo Ashita (video đăng ngày 20/10/2026), nó giống như bất kỳ web app nhỏ nào, viết thành các file HTML, CSS và TypeScript riêng: HTML định nghĩa cấu trúc, CSS lo phần style, TypeScript đảm nhận hành vi của app. Trên màn hình là ba file nguồn trong `src/`: `index.html`, `styles.css` và `mcp-app.ts`.

Lúc build, chị nói, tất cả được bundle thành một file HTML duy nhất, tự chứa, tức `sales-form.html`. Chính file này là resource ta sẽ đăng ký với server (video đăng ngày 20/10/2026).

Ta import `registerAppResource` và `RESOURCE_MIME_TYPE` từ MCP Apps SDK chính thức. Theo Ashita (video đăng ngày 20/10/2026), `registerAppResource` đăng ký HTML view của app như một UI MCP resource, để AI host biết phải render gì khi một tool tham chiếu tới nó. Resource thứ nhất có tên `sales-metric-input-ui`.

![File server.ts với registerAppResource cho sales-metric-input-ui](https://homus.dev/photos/Wiun7ZGu-Ks-0323.jpg)

Dòng import `registerAppResource, RESOURCE_MIME_TYPE` từ `@modelcontextprotocol/ext-apps/server` được đóng khung, bên dưới là lệnh đăng ký resource với description "Interactive sales metrics selector with regions, metrics, and time periods" và callback đọc `sales-form.html` (video đăng ngày 20/10/2026).

```
import { registerAppResource, RESOURCE_MIME_TYPE } from "@modelcontextprotocol/ext-apps/server";

const salesFormResourceName = `sales-metric-input-ui`;
const salesFormUri = `${RESOURCE_URI}/${salesFormResourceName}`;
registerAppResource(
server,
salesFormResourceName,
salesFormUri,
{
mimeType: RESOURCE_MIME_TYPE,
description: "Interactive sales metrics selector with regions, metrics, and time periods",
},
async () => ({
contents: [{
uri: salesFormUri,
mimeType: RESOURCE_MIME_TYPE,
text: await readAppHtml("sales-form.html"),
}],
}),
);
```

Mỗi UI resource có một resource URI riêng, khai báo trước, dùng để tham chiếu tới nó. Trong bài blog đi kèm video, URI này là `ui://sample-mcp-apps-chatflow/sales-metric-input-ui`, gắn với `RESOURCE_MIME_TYPE` có giá trị `text/html;profile=mcp-app` (bài viết của Ashita trên AWS Builder Center, đọc ngày 27/10/2026). Theo chị (video đăng ngày 20/10/2026), MIME type này giúp AI host nhận ra đây là UI của một MCP app chứ không phải một đoạn HTML text thông thường.

Để gộp HTML, CSS và TypeScript của app thành một file HTML tự chứa, mọi dependency được inline, Ashita dùng `vite-plugin-singlefile`. Lý do chị đưa ra (video đăng ngày 20/10/2026): trong MCP Apps, toàn bộ app phải đi trong một blob text duy nhất của resource. Khi host yêu cầu resource này, read callback chạy, nạp file `sales-form.html` tự chứa, và đó là thứ hiện ra thành UI tương tác trong chat.

## 5. Tool logic và metadata linkage

Khối tiếp theo là MCP tool logic. Theo Ashita (video đăng ngày 20/10/2026), ta dùng tiện ích `registerAppTool` để đăng ký những MCP tool có UI đi kèm. So với base SDK, hàm này cần UI metadata trong config, cho AI client biết host phải render view nào khi tool được gọi.

![File server.ts với registerAppTool cho select-sales-metric](https://homus.dev/photos/Wiun7ZGu-Ks-0535.jpg)

Tool `select-sales-metric` được đăng ký bằng `registerAppTool`: trong `_meta.ui.resourceUri` là `salesFormUri`, và kết quả trả về chỉ là một đoạn text "Select Sales Metric Tool executed. Select input in the MCP App UI." (video đăng ngày 20/10/2026).

```
import {registerAppTool} from "@modelcontextprotocol/ext-apps/server";

registerAppTool(
server,
"select-sales-metric",
{
title: "Select Sales Metric",
description: "Select sales regions, metrics, and reporting periods for analysis.",
_meta: {
ui: {
resourceUri: salesFormUri
},
},
},
async () => ({
content: [{
type: "text",
text: "Select Sales Metric Tool executed. Select input in the MCP App UI.",
}],
}),
);
```

Ashita lưu ý hai điều (video đăng ngày 20/10/2026). Thứ nhất, UI resource được nối với tool qua metadata linkage, tức trường `_meta`. Thứ hai, tool vẫn chạy mà không lỗi gì ngay cả khi host không hỗ trợ MCP Apps. Trong trường hợp đó, chỉ kết quả của tool, là đoạn text content "Select Sales Metric Tool executed. Select input in the MCP App UI.", được gửi về làm response.

## 6. Host và View: sandboxed iframe ngay trong chat

Khối thứ ba là host: AI client nơi agent của bạn chạy. Theo Ashita (video đăng ngày 20/10/2026), host gọi MCP tool và render UI được liên kết với tool đó. Danh sách các host đang hỗ trợ MCP Apps được cập nhật thường xuyên trên website chính thức, và chị khuyên mọi người vào xem.

![Trang Support matrix trên modelcontextprotocol.io với cột MCP Apps](https://homus.dev/photos/Wiun7ZGu-Ks-0600.jpg)

Trang Extension Support Matrix trên modelcontextprotocol.io trong video: cột MCP Apps có dấu tick cho Claude (web), Claude Desktop, VS Code GitHub Copilot, Microsoft 365 Copilot, Goose, Postman, MCPJam, ChatGPT, Cursor và vài client khác (theo video đăng ngày 20/10/2026; trang ghi rằng danh sách được cập nhật qua pull request nên thay đổi theo thời gian).

Theo chị (video đăng ngày 20/10/2026), Claude Desktop là một host phổ biến có hỗ trợ MCP Apps, và hôm nay chị dùng nó để test các MCP app sales analytics của mình.

Câu hỏi tiếp theo: host thực sự render UI resource ở đâu? Ashita gọi chỗ đó là **view**: một sandboxed iframe được render ngay trong AI chat. Theo chị (video đăng ngày 20/10/2026), sandbox về cơ bản là một ranh giới bảo mật. Iframe chạy với quyền bị giới hạn và không với tới được ứng dụng host. Vì vậy một MCP app không thể trực tiếp đọc hay thao túng phần chat xung quanh nó.

Mọi giao tiếp với host, chị nói, đi qua một messaging channel duy nhất, được định nghĩa rõ, nên mọi tương tác đều audit được (video đăng ngày 20/10/2026).

![Sơ đồ bốn khối: Tool Logic, UI Resources, Host, View và các mũi tên giao tiếp](https://homus.dev/photos/Wiun7ZGu-Ks-0703.jpg)

Tool Logic (MCP Server) nối tới UI Resources (`ui://`) qua "Metadata Linkage (_meta)"; Host (AI Client) nói chuyện với Tool Logic bằng "JSON-RPC over stdio or Streamable HTTP" và "Fetch UI Template" từ UI Resources; View (Sandboxed iframe) nói chuyện với Host bằng "JSON-RPC over postMessage" (video đăng ngày 20/10/2026).

## 7. Giao tiếp host và view: App, handler và handshake

Theo Ashita (video đăng ngày 20/10/2026), dùng các API postMessage chuẩn của trình duyệt, view có thể dễ dàng nói chuyện với host và ngược lại, theo giao thức JSON-RPC. Điểm hay, chị nói, là bạn không phải tự tay viết những lệnh postMessage này.

Theo chị (video đăng ngày 20/10/2026), trong file TypeScript đi kèm MCP app, chỉ cần import `App` từ MCP Apps SDK và tạo object client app phía view, object này sẽ nói chuyện với host thay cho UI của bạn. Trên màn hình, file `sales-form.ts` bắt đầu bằng dòng:

```
import { App } from "@modelcontextprotocol/ext-apps";
```

Tiếp theo, theo chị (video đăng ngày 20/10/2026), bạn đăng ký mọi event listener gắn với tương tác UI, và đăng ký các handler chạy khi host gửi tới một message thuộc một loại cụ thể, ví dụ `ontoolresult`, chạy khi MCP tool thực thi tool logic xong và trả kết quả về.

Cuối cùng, ta gọi `app.connect()`. Theo Ashita (video đăng ngày 20/10/2026), lệnh này nối một postMessage transport và thực hiện handshake khởi tạo UI (bài blog ghi là `ui/initialize`, đọc ngày 27/10/2026), dọn đường cho mọi giao tiếp giữa host và view.

Ba bước phía view mà Ashita đi qua: tạo object `App`, đăng ký listener và handler, rồi gọi `app.connect()` để bắt tay với host (theo video đăng ngày 20/10/2026).

## 8. Tool chỉ dành cho app và updateModelContext

Theo Ashita (video đăng ngày 20/10/2026), MCP apps còn dùng được cho việc điều phối tool rộng hơn (tool orchestration), khi một tool có thể kích hoạt các tool khác, làm mọi thứ tương tác hơn. Điều này cho phép những tương tác chỉ diễn ra ở UI, như nút refresh hay gửi form, với lựa chọn không lộ bất kỳ chi tiết nào của tool cho agent hay model.

Chị nói (video đăng ngày 20/10/2026) rằng cách này trao nhiều quyền kiểm soát hơn cho người dùng cuối: họ có thể chạy tool một cách deterministic, không phải trông vào AI model để thực hiện tool call.

Vậy là chị đăng ký một tool mới, chỉ app thấy được còn agent thì không, bằng cách đặt `visibility` trong `_meta.ui` thành chỉ có `"app"`. Theo Ashita (video đăng ngày 20/10/2026), vì tool này không lộ ra cho model, không có cách nào nó bị gọi nhầm, và ta kiểm soát hoàn toàn việc thực thi nó.

![File server.ts với registerAppTool get-sales-data, visibility app](https://homus.dev/photos/Wiun7ZGu-Ks-0900.jpg)

Tool `get-sales-data` có `visibility: ["app"]` kèm comment "hidden from the model"; handler gọi `getData(states, metric, period, year)` rồi trả về cả `content` dạng text (JSON.stringify của report) lẫn `structuredContent` (video đăng ngày 20/10/2026).

```
registerAppTool(
server,
"get-sales-data",
{
title: "Get Sales Data",
description: "Fetch sales report data.",
inputSchema: getSalesDataInputSchema.shape,
_meta: {
ui: {
resourceUri: salesFormUri,
visibility: ["app"] // hidden from the model
}
},
},
async ({ states, metric, period, year }) => {
const report = getData(states, metric, period, year);
return {
content: [{
type: "text",
text: JSON.stringify(report)
}],
structuredContent: report as unknown as Record,
};
},
);
```

Khi bấm nút Submit, tool này được kích hoạt bằng `app.callServerTool`. Theo chị (video đăng ngày 20/10/2026), khi chạy xong, nó trả kết quả ở cả dạng text lẫn dạng structured content. Trên màn hình, file `sales-form.ts` gọi:

```
const result = await app.callServerTool({
name: "get-sales-data",
arguments: {
states: selections.states,
metric: selections.metric,
period: selections.period,
year: selections.year,
},
});

report = (result.structuredContent as SalesReport | undefined) ?? null;
if (!report) {
log.error("get-sales-data returned no structuredContent:", result);
}
setStatus("✅ Data fetched successfully...");
```

Giờ phải cập nhật model context bằng dữ liệu này. Theo Ashita (video đăng ngày 20/10/2026), ta làm việc đó bằng `updateModelContext`, lệnh lặng lẽ cập nhật context bằng dữ liệu liên quan, gửi qua đường postMessage.

![File sales-form.ts với app.updateModelContext gửi content và structuredContent](https://homus.dev/photos/Wiun7ZGu-Ks-0952.jpg)

`app.updateModelContext` gửi cùng lúc `content` (một khối text dựng bằng `buildContextText(selections, report)`) và `structuredContent` chứa `selections` và `report` (video đăng ngày 20/10/2026).

```
await app.updateModelContext({
content: [{
type: "text",
text: buildContextText(selections,
report)
}],
structuredContent: {
selections,
report
},
});
```

Chị lưu ý (video đăng ngày 20/10/2026): ta gửi cả `content` lẫn `structuredContent`. `content` là bản text của dữ liệu, còn `structuredContent` là dữ liệu ở dạng có cấu trúc hơn, như JSON. Một host có thể nhận text nhưng không nhận structured content, nên ta mở đầu bằng một khối text đọc được, rồi gắn thêm payload có cấu trúc.

Với bước này, Ashita đã có MCP app Sales Form, giúp lấy dữ liệu cần thiết và đưa nó vào model context (demo trong video đăng ngày 20/10/2026). Giờ chị chuyển sang app tiếp theo, giúp trực quan hoá dữ liệu đó thành chart và biểu đồ.

## 9. App thứ hai: dashboard vẽ bằng Chart.js

Chị tạo resource mới và tool tương ứng (trên màn hình là resource `sales-visualization` đọc file `sales-visualization.html`, và tool `visualize-sales-data` với `visibility: ["model", "app"]`). Theo Ashita (video đăng ngày 20/10/2026), tool này nhận dữ liệu đầu vào do model xác định dựa trên context vừa được cập nhật, rồi chuyển tiếp payload có cấu trúc thành kết quả.

Cả input lẫn result đều được UI của app lắng nghe qua hai handler `ontoolinput` và `ontoolresult`. Theo chị (video đăng ngày 20/10/2026), dữ liệu có cấu trúc, sạch sẽ này chảy từ tool tới host rồi tới app: không parse chuỗi, không phải "cào" text trong response của tool. Cuối cùng ta dùng nó để render dashboard. Trên màn hình, file `sales-visualization.ts`:

```
function acceptPayload(payload: SalesReportPayload | undefined) {
if (!payload?.report) return;
state.report = payload.report;
state.selections = payload.selections ?? null;
renderDashboard();
}

app.ontoolinput = (params) => {
acceptPayload(params?.arguments as SalesReportPayload
| undefined);
};

app.ontoolresult = (params) => {
acceptPayload(params?.structuredContent as SalesReportPayload
| undefined);
};
```

Để vẽ chart, theo Ashita (video đăng ngày 20/10/2026), chỉ cần dùng Chart.js, thêm nó như một npm dependency bình thường, và `vite-plugin-singlefile` sẽ inline nó vào bundle một file.

Chị gõ prompt "visualize" để kích hoạt tool và cho xem dashboard được render. Trên màn hình, Claude Desktop hiện "Reading widget context", rồi tool `visualize-sales-data` render khung "Sales Visualization" cho Revenue, Monthly, 2025, ba bang MH, TN, KA (demo trong video đăng ngày 20/10/2026).

![Dashboard Sales Visualization trong Claude Desktop với bốn thẻ số và biểu đồ cột chồng theo tháng](https://homus.dev/photos/Wiun7ZGu-Ks-1143.jpg)

Dashboard Sales Visualization trong demo: bốn thẻ Total ₹1,295,239, Average ₹107,937, Trend giảm 28.5% và Top State Karnataka ₹508,903, bên dưới là "Monthly Revenue Breakdown" dạng cột chồng kèm đường Total, có nút chuyển Stacked Bar/Line (demo trong video đăng ngày 20/10/2026, số liệu mẫu).

Cuộn xuống, dashboard còn có biểu đồ tròn "State Distribution" và biểu đồ thanh ngang "State Comparison". Sau đó Claude viết một câu tóm tắt rằng doanh thu đạt đỉnh vào tháng Tư rồi đi xuống, Karnataka dẫn trước cả ba bang suốt năm, và hỏi có muốn bản PDF không (demo trong video đăng ngày 20/10/2026).

Theo Ashita (video đăng ngày 20/10/2026), vì view được build từ các NPM package thật, toàn bộ hệ sinh thái JavaScript đều dùng được cho app của bạn. Bạn có thể thêm Chart.js, PDF.js, hay cả những thư viện render cảnh 3D, video player, rich text editor, bản đồ: bất cứ thứ gì npm cài được và Vite bundle được.

## 10. App thứ ba: báo cáo PDF và nút tải về

App cuối cùng hiển thị báo cáo PDF được tạo ra cho phần sales analytics. Theo Ashita (video đăng ngày 20/10/2026), khi MCP tool chạy, PDF được tạo ở phía server, và nội dung PDF được truyền trong tool result. Trên màn hình, tool `show-sales-pdf-report` gọi `generateSalesPdf(selections, report, metricName)` rồi trả về `pdfBase64`, `fileName`, `fileSize` và `title` trong `structuredContent`.

Handler `ontoolresult` của app nhận dữ liệu PDF này, và nó được render trong app nhờ thư viện PDF.js (theo video đăng ngày 20/10/2026). Trong demo, sau câu "generate PDF", trình xem "Revenue - Monthly - 2025" hiện ngay trong chat với 2 trang, có biểu đồ "Monthly Revenue Breakdown" và bảng số theo tháng của từng bang (demo trong video đăng ngày 20/10/2026).

Theo chị (video đăng ngày 20/10/2026), một sandboxed iframe không tự ghi file được. Khi bấm nút Download PDF, app hỏi host, ở đây là Claude Desktop, và host hiện hộp thoại lưu file. Mọi thứ được xử lý qua `app.downloadFile`, nơi ta chỉ định blob của resource và MIME type.

![Hộp thoại Download file của host: This app wants to download a file to your device, sales-report-revenue-2025.pdf](https://homus.dev/photos/Wiun7ZGu-Ks-1250.jpg)

Host hiện hộp thoại "Download file": "This app wants to download a file to your device", tên file `sales-report-revenue-2025.pdf`, hai nút Cancel và Download (demo trong video đăng ngày 20/10/2026).

Trên màn hình, file `sales-pdf-report.ts` gắn việc tải về vào nút bấm:

```
downloadBtn.addEventListener("click", async () => {
if (!state.pdfBase64) return;
try {
const result = await app.downloadFile({
contents: [
{
type: "resource",
resource: {
uri: `file:///${state.fileName}`,
mimeType: "application/pdf",
blob: state.pdfBase64,
},
},
],
});
if (result?.isError) {
setStatus("Download was cancelled", "error");
} else {
setStatus("✅ PDF downloaded!", "success");
}
} catch (error) {
log.error("Download failed:", error);
setStatus("❌ Download failed", "error");
}
});
```

## 11. Deploy MCP server lên Amazon Bedrock AgentCore

Phần cuối là deploy MCP server lên cloud để ai cũng dùng được. Theo Ashita (video đăng ngày 20/10/2026), cách làm như sau:

- Đóng gói MCP server dùng Streamable HTTP thành một container Linux ARM64, phục vụ `POST /mcp` trên port 8000 (video đăng ngày 20/10/2026).

- AgentCore CLI biến container đó thành một runtime được quản lý, cô lập theo từng session, dùng CDK, CodeBuild và ECR (video đăng ngày 20/10/2026).

- Trỏ JWT authorizer của runtime tới một Cognito user pool có app client kiểu client credentials (video đăng ngày 20/10/2026).

- Khi đó, bất kỳ MCP client nào hỗ trợ remote HTTP server cũng gọi được nó từ bất cứ đâu bằng một bearer token (video đăng ngày 20/10/2026).

Bài blog đi kèm đi chi tiết hơn từng bước: Dockerfile cho `linux/arm64`, cài CLI `@aws/agentcore`, lệnh `agentcore create` và cấu hình runtime (bài viết của Ashita trên AWS Builder Center, đọc ngày 27/10/2026).

Bốn bước deploy Ashita kể, theo thứ tự (theo video đăng ngày 20/10/2026).

## 12. Tổng kết

Ashita khép lại phần MCP apps (video đăng ngày 20/10/2026): chị bắt đầu từ các khái niệm cốt lõi, rồi cho thấy những khái niệm đó ghép lại với nhau thế nào trong một chat flow tương tác thật, từ form chọn dữ liệu, dashboard chart, tới báo cáo PDF tải về được.

Chị nhắn: giờ tới lượt bạn build, và tự tạo những trải nghiệm phong phú hơn cho các ứng dụng AI của mình. Chị cảm ơn mọi người đã xem và chào tạm biệt.

## Nguồn và liên kết

- Tên gốc: What are MCP Apps? Building Apps that Run on Claude & ChatGPT
- Sự kiện: [YouTube](https://homus.dev/events/youtube)
- Video gốc: [https://www.youtube.com/watch?v=Wiun7ZGu-Ks](https://www.youtube.com/watch?v=Wiun7ZGu-Ks)

- Kênh YouTube AWS Developers (Ashita Prasad): [youtube.com/channel/UCT-nPlVzJI-ccQXlxjSvJmw](https://www.youtube.com/channel/UCT-nPlVzJI-ccQXlxjSvJmw)

- Bài viết đi kèm video của Ashita trên AWS Builder Center, có toàn bộ code và các bước deploy lên AgentCore (đọc ngày 27/10/2026): [What are MCP Apps? Building Apps that run on Claude & ChatGPT!](https://builder.aws.com/content/3KumnpioszB60y33kJPJogaYsK1/what-are-mcp-apps-building-apps-that-run-on-claude-and-chatgpt)

- Repo code mẫu của bài viết, "Sample MCP server that renders interactive sales analytics UIs inside Claude Desktop" (đọc ngày 27/10/2026): [github.com/ashitaprasad/sample-mcp-apps-claude](https://github.com/ashitaprasad/sample-mcp-apps-claude)

- Tài liệu MCP Apps trên [modelcontextprotocol.io](https://modelcontextprotocol.io) (đọc ngày 27/10/2026): [modelcontextprotocol.io/extensions/apps/overview](https://modelcontextprotocol.io/extensions/apps/overview)

- Extension Support Matrix, danh sách client hỗ trợ từng extension, cập nhật qua pull request (đọc ngày 27/10/2026): [modelcontextprotocol.io/extensions/client-matrix](https://modelcontextprotocol.io/extensions/client-matrix)

- MCP Apps SDK, package `@modelcontextprotocol/ext-apps` (đọc ngày 27/10/2026): [github.com/modelcontextprotocol/ext-apps](https://github.com/modelcontextprotocol/ext-apps)

- MCP TypeScript SDK, package `@modelcontextprotocol/sdk` (đọc ngày 27/10/2026): [github.com/modelcontextprotocol/typescript-sdk](https://github.com/modelcontextprotocol/typescript-sdk)

- vite-plugin-singlefile (đọc ngày 27/10/2026): [github.com/richardtallent/vite-plugin-singlefile](https://github.com/richardtallent/vite-plugin-singlefile)

- Chart.js (đọc ngày 27/10/2026): [chartjs.org](https://www.chartjs.org/) · PDF.js: [mozilla.github.io/pdf.js](https://mozilla.github.io/pdf.js/)

- Amazon Bedrock AgentCore (đọc ngày 27/10/2026): [aws.amazon.com/bedrock/agentcore](https://aws.amazon.com/bedrock/agentcore/)

Nguồn: https://homus.dev/talks/what-are-mcp-apps-building-apps-that-run-on-claude-chatgpt · cập nhật 2026-10-27
