Hiểu kiến trúc MCP: Host, client, server, lớp vận chuyển và giao tiếp JSON-RPC. Tìm hiểu cách các thành phần kết hợp với nhau trước khi viết code.
Trước khi viết code, bạn cần có một mô hình tư duy về cách MCP hoạt động. Bài học này phác thảo kiến trúc — mọi thành phần, cách chúng giao tiếp và lý do tại sao nó được thiết kế như vậy.
Hãy nghĩ về nó giống như việc hiểu cách một web server hoạt động trước khi xây dựng trang web đầu tiên của bạn. Các khái niệm rất đơn giản và chúng sẽ giúp mọi thứ trong các bài học sau này trở nên dễ hiểu hơn.
Kiến trúc ba lớp
MCP có ba vai trò riêng biệt:
Host
Host là ứng dụng AI mà người dùng tương tác — Claude Desktop, Claude Code, ChatGPT hoặc bất kỳ công cụ nào tương thích với MCP.
Host:
Quản lý ngữ cảnh và cuộc hội thoại tổng thể
Quyết định kết nối với MCP server nào
Kiểm soát quyền (công cụ nào có thể được gọi, dữ liệu nào được truy cập)
Trình bày kết quả của công cụ cho người dùng
Hãy coi Host như người quản lý. Nó phân công công việc nhưng vẫn giữ quyền kiểm soát.
Client
Client nằm bên trong Host và xử lý giao tiếp giao thức. Mỗi Client duy trì kết nối 1:1 với một Server.
Client:
Gửi yêu cầu đến server (ví dụ: "gọi công cụ này với các tham số này")
Nhận phản hồi và thông báo
Xử lý đàm phán khả năng trong quá trình thiết lập kết nối
Quản lý vòng đời (khởi tạo → sử dụng → tắt)
Nếu Host kết nối với 3 MCP server (cơ sở dữ liệu, GitHub, hệ thống file), nó sẽ tạo ra 3 Client riêng biệt — một Client cho mỗi server.
Server
Server là những gì bạn xây dựng. Nó cung cấp các khả năng mà trợ lý AI có thể sử dụng.
Server:
Quảng cáo các khả năng của nó trong quá trình khởi tạo ("Tôi có những công cụ này, những tài nguyên này, những prompt này")
Thực thi các lệnh gọi công cụ khi được yêu cầu
Trả về dữ liệu từ các tài nguyên khi được hỏi
Cung cấp những prompt template theo yêu cầu
✅ Kiểm tra nhanh: Nếu Claude Desktop kết nối đồng thời với Postgres MCP server và Slack MCP server, sẽ tạo ra bao nhiêu MCP Client?
Đáp án: Hai — một kết nối Client cho mỗi Server. Mỗi Client duy trì mối quan hệ 1:1 với Server của nó.
Vòng đời kết nối
Mọi kết nối MCP đều tuân theo trình tự này:
📍 Nơi dán: Mở ChatGPT (chat.openai.com), Claude (claude.ai) hoặc Gemini (gemini.google.com) và bắt đầu một cuộc trò chuyện mới.
📋 Cách sao chép prompt này: Nhấp vào bất kỳ đâu bên trong khối màu xám, nhấn Cmd+A rồi Cmd+C (Mac) hoặc Ctrl+A rồi Ctrl+C (Windows). Hoặc sử dụng biểu tượng sao chép xuất hiện.
1. KHỞI TẠO
Client → Server: "Đây là phiên bản giao thức và khả năng của tôi"
Server → Client: "Đây là phiên bản của tôi và những gì tôi cung cấp"
Client → Server: "Đã khởi tạo" (xác nhận)
2. VẬN HÀNH
Client → Server: "Gọi công cụ X với tham số Y"
Server → Client: "Đây là kết quả"
(lặp lại khi cần)
3. TẮT
Client → Server: "Đóng kết nối"
(ngắt kết nối sạch)
✏️ Cách điền thông tin chi tiết của bạn: Thay thế mỗi [] và trình giữ chỗ trong ngoặc bằng thông tin cụ thể từ tình huống thực tế của bạn. Thông tin đầu vào mơ hồ sẽ tạo ra kết quả mơ hồ — hãy cụ thể.
👀 Những gì bạn sẽ thấy: Trong vòng vài giây, AI sẽ trả về phản hồi có cấu trúc dựa trên prompt ở trên. Hãy đọc kỹ và coi đó là bản nháp, không phải câu trả lời cuối cùng.
📌 Cách xử lý kết quả: Lưu phản hồi vào file Notes. Chọn đề xuất có hiệu quả cao nhất và thực hiện ngay trong tuần này — đừng cố gắng làm tất cả cùng một lúc.
⚠️ Nếu kết quả không ổn: Nếu các đề xuất có vẻ chung chung, hãy dán nội dung sau: "Hãy cụ thể hơn với ngữ cảnh thực tế của tôi. Bỏ qua những lời khuyên chung chung." Nếu nó bỏ qua các chi tiết quan trọng bạn đã cung cấp, hãy hỏi: "Bạn đã bỏ sót [X] trong ngữ cảnh của tôi — hãy thực hiện lại với điều đó làm ràng buộc chính."
Trong quá trình khởi tạo, server cho client biết chính xác những gì nó có thể làm. Điều này được gọi là đàm phán khả năng — server quảng cáo các công cụ, tài nguyên và prompt của nó, và client biết những gì có sẵn trước khi đưa ra bất kỳ yêu cầu nào.
JSON-RPC 2.0: Định dạng thông điệp
Về cơ bản, mọi thông điệp MCP đều là JSON-RPC 2.0. Đây là ví dụ về một lệnh gọi công cụ:
Bạn không cần tự viết JSON này — SDK sẽ xử lý nó. Nhưng hiểu định dạng sẽ giúp ích khi gỡ lỗi.
✅ Kiểm tra nhanh: Trong JSON-RPC 2.0, trường id có chức năng gì?
Đáp án: Nó khớp các yêu cầu với những phản hồi. Khi client gửi yêu cầu với id: 1, server sẽ bao gồm id: 1 trong phản hồi của nó để client biết nó đang trả lời yêu cầu nào.
Các lớp vận chuyển
Vận chuyển là cách client và server trao đổi thông điệp. MCP hỗ trợ hai lớp:
stdio (Đầu vào/Đầu ra chuẩn)
Lớp vận chuyển đơn giản nhất. Host khởi chạy Server như một tiến trình con, và chúng giao tiếp thông qua stdin và stdout:
Host → tạo tiến trình Server
Client ghi JSON vào stdin của Server
Server ghi JSON vào stdout của Client
Sử dụng khi: Server chạy cục bộ trên cùng một máy. Đây là mặc định cho Claude Desktop và Claude Code.
Ưu điểm: Không cần thiết lập mạng, không cần xác thực, khởi động tức thì.
Hạn chế: Chỉ một client duy nhất. Tiến trình server thuộc về một Host.
Lưu ý quan trọng: Không bao giờ sử dụng console.log() trong stdio server. Nó ghi vào stdout và làm hỏng luồng thông điệp JSON-RPC. Sử dụng console.error() (ghi vào stderr) để gỡ lỗi.
Streamable HTTP
Dành cho server từ xa. client kết nối qua HTTP, và server có thể truyền phản hồi trở lại:
Client → Gửi yêu cầu HTTP POST đến URL server
Server → Truyền phản hồi trở lại
Sử dụng khi: Server chạy trên một máy khác, nhiều client cần truy cập, hoặc bạn đang triển khai lên môi trường sản xuất.
Ưu điểm: Hoạt động trên mạng, hỗ trợ nhiều client, có thể thêm xác thực.
Hạn chế: Thiết lập phức tạp hơn — cần server HTTP, có thể cần TLS, xác thực.
Tính năng
stdio
Streamable HTTP
Độ phức tạp thiết lập
Tối thiểu
Vừa phải
Cần có mạng
Không
Có
Nhiều client
Không
Có
Xác thực
Không cần thiết
Cần thiết cho sản xuất
Tốt nhất cho
Phát triển cục bộ, người dùng đơn lẻ
Sản xuất, nhiều người dùng
3 thành phần cơ bản (Tổng quan)
MCP server cung cấp các khả năng thông qua 3 thành phần cơ bản. Chúng ta sẽ tìm hiểu chi tiết từng thành phần trong các bài học sau, nhưng đây là tổng quan:
Thành phần cơ bản
Được kiểm soát bởi
Chức năng của nó
Ví dụ
Tools
Mô hình (AI quyết định khi nào cần gọi)
Thực hiện các hành động, trả về kết quả đã tính toán
query_database, send_slack_message
Resources
Ứng dụng (client truy xuất)
Cung cấp dữ liệu và ngữ cảnh
Sơ đồ cơ sở dữ liệu, file cấu hình, tài liệu
Prompts
Người dùng (được chọn rõ ràng)
Template tương tác có thể tái sử dụng
"Phân tích truy vấn SQL này", "Xem xét yêu cầu PR này"
Điểm khác biệt chính: Các công cụ được mô hình AI gọi trong quá trình đàm thoại. Tài nguyên được client truy xuất để cung cấp ngữ cảnh. Các prompt được người dùng chọn làm điểm bắt đầu.
Tóm lại
Đây là toàn bộ quy trình khi bạn hỏi Claude "Thời tiết ở Tokyo như thế nào?":
Bạn nhập câu hỏi vào Claude Desktop (Host)
Claude nhận ra nó cần công cụ thời tiết từ MCP server được kết nối
Client gửi yêu cầu JSON-RPC: tools/call với get_weather và city: "Tokyo"
Yêu cầu được truyền qua stdio (cục bộ) hoặc HTTP (từ xa) đến server
Server gọi API thời tiết, định dạng kết quả
Server gửi phản hồi JSON-RPC trở lại thông qua đường truyền
Client nhận kết quả và chuyển tiếp cho Claude
Claude đưa ra câu trả lời: "Nhiệt độ 22°C và có mây ở Tokyo"
Người dùng không bao giờ nhìn thấy giao thức. Họ chỉ đặt câu hỏi và nhận được câu trả lời — với dữ liệu thực từ một dịch vụ bên ngoài.
Những điểm chính cần ghi nhớ
MCP có 3 lớp: Host (ứng dụng AI), client (trình xử lý giao thức) và server (code của bạn)
Mỗi client kết nối với chính xác một server (mối quan hệ 1:1)
Các kết nối tuân theo một vòng đời: khởi tạo → vận hành → tắt
Các thông điệp sử dụng JSON-RPC 2.0, nhưng SDK xử lý việc định dạng
Hai phương thức truyền tải: stdio cho phát triển cục bộ, HTTP có thể truyền dữ liệu cho môi trường sản xuất
Ba thành phần cơ bản: Tools (do mô hình điều khiển), Resources (do ứng dụng điều khiển), Prompts (do người dùng điều khiển)
Câu 1:
Khi nào nên sử dụng giao thức stdio thay vì Streamable HTTP?
GIẢI THÍCH:
Giao thức stdio chạy server như một tiến trình con của client, giao tiếp thông qua stdin/stdout. Nó lý tưởng cho việc phát triển cục bộ và các kịch bản người dùng đơn lẻ. HTTP truyền tải dữ liệu dành cho server từ xa, truy cập nhiều client và triển khai sản xuất. Nó đơn giản hơn, không yêu cầu thiết lập mạng và client khởi chạy server như một tiến trình con
Câu 2:
MCP sử dụng giao thức giao tiếp nào?
GIẢI THÍCH:
MCP sử dụng JSON-RPC 2.0, trong đó mỗi thông báo là một đối tượng JSON với tên phương thức, tham số và ID. Nó đơn giản hơn REST (không cần quản lý URL hoặc phương thức HTTP) và hoàn hảo cho giao tiếp hai chiều giữa các công cụ.
Câu 3:
Kiến trúc MCP gồm ba lớp nào?
GIẢI THÍCH:
Host là ứng dụng AI (như Claude Desktop) quản lý ngữ cảnh và kiểm soát các server kết nối. Client xử lý việc truyền tin giao thức và duy trì kết nối 1:1 với các server. Server cung cấp các khả năng — công cụ, tài nguyên và prompt — để AI sử dụng.
Theo Nghị định 147/2024/ND-CP, bạn cần xác thực tài khoản trước khi sử dụng tính năng này. Chúng tôi sẽ gửi mã xác thực qua SMS hoặc Zalo tới số điện thoại mà bạn nhập dưới đây: