10Model Context Protocol#
Tool tra_don_hang ở Chương 9 được định nghĩa ngay trong mã của ứng dụng hỗ trợ khách hàng. Nếu công ty có thêm một trợ lý nội bộ cho nhân viên kho và một agent lập trình cũng cần tra đơn hàng, mỗi ứng dụng lại viết lại tool đó theo cách riêng, với cách xác thực và định dạng dữ liệu riêng. Model Context Protocol (MCP) ra đời để giải quyết sự lặp lại này: nó là một giao thức mở chuẩn hoá cách ứng dụng LLM kết nối với nguồn dữ liệu và tool bên ngoài. Anthropic giới thiệu MCP vào tháng 11 năm 2024; giao thức được phát triển công khai và được nhiều công cụ, nền tảng khác hỗ trợ. Nội dung chương này theo đặc tả phiên bản 2026-07-28, phiên bản mới nhất tại thời điểm viết. MCP còn đang thay đổi nhanh, nên khi xây dựng thật cần đối chiếu với đặc tả hiện hành trên modelcontextprotocol.io.
10.1Bài toán tích hợp#
Giả sử có ứng dụng AI (trợ lý chat, IDE, agent nội bộ) và nguồn dữ liệu hoặc dịch vụ (Google Drive, GitHub, cơ sở dữ liệu nội bộ, hệ thống quản lý đơn hàng). Nếu mỗi ứng dụng tự viết tích hợp riêng cho mỗi dịch vụ, cần tích hợp, mỗi cái định nghĩa tool, xác thực và định dạng dữ liệu theo một cách. MCP định nghĩa một giao thức chung: mỗi dịch vụ viết một MCP server một lần, mỗi ứng dụng cài một MCP client một lần, và mọi ứng dụng dùng được mọi server. Số tích hợp giảm từ xuống .
Ý tưởng này lấy cảm hứng từ Language Server Protocol (LSP), giao thức chuẩn hoá cách trình soạn thảo mã nguồn giao tiếp với các công cụ hỗ trợ ngôn ngữ lập trình. Nhờ LSP, một công cụ hỗ trợ ngôn ngữ chỉ cần viết một lần là dùng được trong nhiều trình soạn thảo.
10.2Kiến trúc#
MCP có ba vai. Host là ứng dụng mà người dùng tương tác, như trợ lý chat, IDE hay agent. Host giữ toàn bộ hội thoại, gọi LLM, quản lý các client, và thực thi chính sách an toàn: xin phép người dùng, quyết định dữ liệu nào được gửi đi. Client nằm trong host, và mỗi client kết nối với đúng một server. Server cung cấp dữ liệu và tool cho client; nó có thể là một tiến trình chạy trên cùng máy hoặc một dịch vụ từ xa.

Đặc tả nêu mấy nguyên tắc thiết kế. Server phải rất dễ xây, vì phần điều phối phức tạp nằm ở host. Các server có thể ghép với nhau, mỗi server làm một việc. Và server không được đọc toàn bộ hội thoại, cũng không "nhìn thấy" các server khác: server chỉ nhận phần thông tin cần thiết, toàn bộ lịch sử hội thoại ở lại trong host, và mọi tương tác giữa các server đều do host kiểm soát. Nguyên tắc cuối là nền tảng an toàn của giao thức, vì nhờ nó một server không đáng tin cậy không đọc được dữ liệu mà host không chủ động gửi cho nó.
10.3Các thành phần#
Server cung cấp ba loại thành phần, khác nhau ở chỗ ai quyết định sử dụng chúng.
| Thành phần | Nội dung | Ai quyết định dùng |
|---|---|---|
| Tools | các hàm có thể thực thi, kèm lược đồ tham số | mô hình, qua function calling (Mục 9.3) |
| Resources | dữ liệu để đọc, mỗi resource có một URI, như nội dung tệp hay bản ghi cơ sở dữ liệu | ứng dụng hoặc người dùng chọn đưa vào ngữ cảnh |
| Prompts | các mẫu prompt và quy trình có sẵn, có tham số | người dùng, thường qua một lệnh trong giao diện |
Ở chiều ngược lại, đặc tả phiên bản 2026-07-28 định nghĩa một tính năng phía client là elicitation: server yêu cầu thêm thông tin từ người dùng trong lúc xử lý, chẳng hạn xin xác nhận trước một thao tác hoặc hỏi tham số còn thiếu. Hai tính năng phía client của các phiên bản trước, roots (cho server biết thư mục nào được phép truy cập) và sampling (cho server nhờ host gọi LLM), được đánh dấu là sẽ bị loại bỏ ở phiên bản này; đặc tả khuyên truyền thư mục qua tham số hoặc cấu hình, và gọi thẳng API của nhà cung cấp LLM thay vì dùng sampling.
10.4Lớp dữ liệu và lớp truyền tải#
MCP chia giao thức thành hai lớp. Ở lớp dữ liệu, mọi thông điệp dùng định dạng JSON-RPC 2.0: yêu cầu có method, params và id; phản hồi có result hoặc error cùng id tương ứng. Một lời gọi tool và phản hồi của nó trông như sau (rút gọn):
{"jsonrpc": "2.0", "id": 7, "method": "tools/call",
"params": {"name": "tra_don_hang", "arguments": {"ma_don": "DH1024"},
"_meta": {"io.modelcontextprotocol/protocolVersion": "2026-07-28"}}}
{"jsonrpc": "2.0", "id": 7,
"result": {"resultType": "complete",
"content": [{"type": "text", "text": "Đơn DH1024 dự kiến giao 15:00 hôm nay."}],
"isError": false}}
Các phương thức chính là tools/list và tools/call cho tools, resources/list và resources/read cho resources, prompts/list và prompts/get cho prompts, cùng server/discover để server công bố các phiên bản giao thức, khả năng và danh tính của nó.
Phiên bản 2026-07-28 làm MCP trở thành giao thức phi trạng thái (stateless). Các phiên bản trước yêu cầu một bước bắt tay initialize để hai bên thống nhất phiên bản và khả năng, sau đó duy trì một phiên làm việc. Ở phiên bản mới, bước bắt tay bị bỏ: mỗi yêu cầu tự mang phiên bản giao thức và khả năng của client trong trường _meta, như ở ví dụ trên, nên mỗi yêu cầu độc lập với các yêu cầu khác. Thay đổi này giúp server từ xa dễ mở rộng theo chiều ngang và đặt được sau bộ cân bằng tải như một dịch vụ web thông thường. Khi server cần thêm thông tin từ client trong lúc xử lý, chẳng hạn cần người dùng xác nhận, nó trả về một kết quả tạm có resultType là "input_required" kèm các yêu cầu cụ thể; client thu thập thông tin rồi gửi lại yêu cầu ban đầu kèm câu trả lời. Mẫu này gọi là yêu cầu nhiều lượt (multi round-trip request), thay cho cơ chế server chủ động gửi yêu cầu tới client của các phiên bản trước.
Ở lớp truyền tải, đặc tả định nghĩa hai cách truyền thông điệp. Với stdio, host khởi chạy server như một tiến trình con trên cùng máy và trao đổi thông điệp qua luồng vào ra chuẩn; cách này hợp với server truy cập tài nguyên cục bộ như tệp, Git hay cơ sở dữ liệu trên máy. Với Streamable HTTP, client gửi yêu cầu HTTP POST tới địa chỉ của server, và phản hồi có thể là một JSON hoặc một luồng sự kiện khi server cần gửi tiến độ; cách này dùng cho server từ xa, với cơ chế xác thực dựa trên OAuth. Cách truyền HTTP+SSE của các phiên bản đầu đã bị thay bằng Streamable HTTP từ phiên bản 2025-03-26 và hiện ở trạng thái sắp bị loại bỏ.
10.5Xây dựng MCP server và kết nối#
Các SDK chính thức (Python, TypeScript và nhiều ngôn ngữ khác) lo phần giao thức, nên người viết server chỉ cần khai báo hàm. Ví dụ dưới đây dùng SDK Python, theo phong cách khai báo bằng decorator của thư viện, để đưa tool tra đơn hàng ở Chương 9 thành một server dùng chung.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("don-hang")
@mcp.tool()
def tra_don_hang(ma_don: str) -> str:
"""Tra trạng thái của một đơn hàng theo mã đơn, dạng DH kèm 4 chữ số."""
don = csdl.tim_don(ma_don) # truy cập hệ thống nội bộ
return f"Đơn {ma_don}: {don.trang_thai}, dự kiến giao {don.du_kien}."
@mcp.resource("chinh-sach://doi-tra")
def chinh_sach_doi_tra() -> str:
"""Nội dung chính sách đổi trả hiện hành."""
return doc_tep("chinh_sach_doi_tra.md")
if __name__ == "__main__":
mcp.run() # mặc định chạy qua stdio
SDK sinh lược đồ tham số từ chữ ký hàm và lấy mô tả từ docstring, vì vậy docstring ở đây đóng đúng vai trò mô tả tool ở Mục 9.3 và cần được viết cẩn thận như thế. Để dùng server này, host được cấu hình lệnh khởi chạy nó (với stdio) hoặc địa chỉ của nó (với Streamable HTTP). Giao diện của SDK thay đổi theo phiên bản đặc tả, nên cần đọc tài liệu của đúng phiên bản SDK đang dùng.
10.6An toàn khi dùng MCP#
Đặc tả nêu ba nguyên tắc an toàn mà mọi bản cài đặt phải tuân theo. Nguyên tắc thứ nhất là người dùng đồng ý và kiểm soát: người dùng phải hiểu và đồng ý với mọi truy cập dữ liệu và mọi thao tác, và giữ quyền kiểm soát dữ liệu nào được chia sẻ, hành động nào được thực hiện. Nguyên tắc thứ hai là quyền riêng tư dữ liệu: host phải có sự đồng ý rõ ràng của người dùng trước khi đưa dữ liệu của họ cho server, và không được chuyển dữ liệu của resource đi nơi khác khi chưa được đồng ý. Nguyên tắc thứ ba là an toàn của tool: tool tương đương với thực thi mã tuỳ ý và phải được đối xử thận trọng, host phải xin phép người dùng trước khi gọi bất kỳ tool nào, và mô tả về hành vi của tool, như các chú thích (annotations), phải được coi là không đáng tin trừ khi đến từ server đáng tin.
Điểm cuối có lý do cụ thể. Mô tả của tool được đưa thẳng vào ngữ cảnh của mô hình, nên một server độc hại có thể giấu chỉ dẫn trong mô tả tool để điều khiển mô hình, chẳng hạn yêu cầu mô hình đọc một tệp khoá bí mật rồi gửi nội dung qua tham số của một tool khác. Kiểu tấn công này là một dạng prompt injection (Chương 11), đôi khi được gọi là đầu độc tool (tool poisoning). Một server hôm nay lành tính cũng có thể đổi mô tả tool ở phiên bản sau. Vì vậy chỉ nên cài server từ nguồn tin cậy, đọc mô tả tool trước khi cho phép, ghim phiên bản server, giới hạn quyền của mỗi server ở mức tối thiểu, và giữ bước xin phép người dùng cho các thao tác có tác dụng phụ.
10.7Tóm tắt#
MCP giảm số tích hợp giữa ứng dụng và dịch vụ từ xuống bằng cách chuẩn hoá giao tiếp giữa host, client và server. Server cung cấp tools do mô hình chọn dùng, resources do ứng dụng hoặc người dùng chọn đưa vào ngữ cảnh, và prompts do người dùng gọi. Thông điệp dùng JSON-RPC 2.0, truyền qua stdio cho server cục bộ hoặc Streamable HTTP cho server từ xa, và từ phiên bản 2026-07-28 mỗi yêu cầu tự mang phiên bản giao thức nên không còn bước bắt tay. Server không thấy hội thoại hay các server khác, nhưng mô tả tool của nó đi thẳng vào ngữ cảnh của mô hình, nên một server độc hại vẫn có thể điều khiển mô hình qua đó.
Nguy cơ cuối cùng đó không riêng gì MCP. Bất cứ văn bản nào lọt vào ngữ cảnh, từ tài liệu truy xuất, kết quả tool tới email của người lạ, đều có thể chứa chỉ dẫn mà mô hình làm theo. Chương 11 xét nguy cơ này cùng những rủi ro khác của ứng dụng LLM.
Tự kiểm tra
4 câu. Chọn đáp án để xem ngay lời giải thích.
1MCP giảm số tích hợp giữa ứng dụng và dịch vụ từ bao nhiêu xuống bao nhiêu?
Vì sao: Mỗi dịch vụ viết một MCP server, mỗi ứng dụng cài một MCP client (Mục 10.1).2Trong kiến trúc MCP, phát biểu nào đúng?
Vì sao: Host giữ toàn bộ hội thoại và kiểm soát mọi tương tác giữa các server (Mục 10.2).3Thay đổi lớn của đặc tả MCP phiên bản 2026-07-28 là gì?
Vì sao: Server cần thêm thông tin thì trả kết quả tạm với resultType "input_required" (Mục 10.4).4Vì sao mô tả tool của một MCP server phải được coi là không đáng tin nếu server không đáng tin?
Vì sao: Đây là một dạng prompt injection, đôi khi gọi là đầu độc tool (Mục 10.6).
Đã trả lời 0/4