Learn > Claude > Model Context Protocol (MCP)

Model Context Protocol (MCP)

Build MCP server, tool calling, event-driven, deployment.

  • MCP là giao thức chuẩn hóa kênh giao tiếp giữa ứng dụng AI (MCP Client) và các nguồn dữ liệu/công cụ ngoài (MCP Server), giúp loại bỏ gánh nặng viết mã tích hợp API thủ công.
  • Nguyên lý cốt lõi là Separation of Concerns: chuyển dịch định nghĩa tool schema và thực thi từ server ứng dụng sang MCP Server chuyên biệt — nhà cung cấp dịch vụ tự maintain, lập trình viên chỉ kết nối.
  • MCP và Tool Use là hai khái niệm bổ trợ nhau: MCP là hạ tầng cung cấp công cụ (ai build và chạy tool), Tool Use là năng lực suy luận của Claude để quyết định khi nào gọi tool nào.

TL;DRModel Context Protocol (MCP) là giao thức chuẩn hóa kết nối, hoạt động như một "USB-C cho AI": tách biệt tầng ứng dụng (MCP Client) và tầng kết nối dịch vụ (MCP Server). Thay vì tự code API wrapper thủ công cho từng hệ thống, tôi chỉ việc cắm Client vào các MCP Server đã được đóng gói sẵn tool, prompt và resource để cấp công cụ và dữ liệu cho Claude.


1. Bài toán tích hợp API thủ công — gánh nặng bảo trì (The Problem)

Khi tích hợp AI vào các hệ thống doanh nghiệp (GitHub, Slack, Jira, Database...), tôi luôn gặp phải ba rủi ro lớn liên quan đến chi phí bảo trì (maintenance cost)năng suất của team:

Cơn ác mộng Glue Code

Giả sử tôi đang xây một chat interface nơi user có thể hỏi Claude về dữ liệu GitHub của họ: "What open pull requests are there across all my repositories?"

Để Claude trả lời được, tôi cần cung cấp cho Claude các tools để truy cập GitHub API. Vấn đề là GitHub có hàng nghìn chức năng: repositories, pull requests, issues, projects, actions... Không có MCP, tôi phải:

  1. Tự viết hàng chục Tool Schema bằng định dạng JSON Schema — mỗi tool một bộ name, description, input_schema.
  2. Tự viết code thực thi (API wrapper) cho từng hàm: get_repos(), list_repos(), create_repos(), search_issues(), update_issue(), create_issue(), get_issue(), create_file()...
  3. Tự test và maintain toàn bộ đống code tích hợp đó.

Đây là một lượng công việc khổng lồ — và tất cả chỉ mới cho mỗi GitHub.

Rủi ro từ bên thứ ba (Third-party API changes)

Bất cứ khi nào GitHub thay đổi cấu trúc API hoặc deprecate endpoint cũ, tích hợp của tôi sẽ vỡ. Team dev phải liên tục túc trực để sửa lỗi và cập nhật schema — một vòng lặp bảo trì không có hồi kết.

Góc nhìn thực tế: quản lý dự án offshore VN/JP

Trong các dự án offshore Nhật – Việt tôi đã tham gia, tôi thấy rõ kịch bản này: team Việt Nam xây integration layer gọi API nội bộ của khách hàng Nhật (Backlog, Chatwork, kintone...). Mỗi lần khách đổi API version, team mất 1–2 sprint chỉ để sửa glue code — thời gian đó đáng lẽ dùng để phát triển feature mới. MCP ra đời chính để triệt tiêu lớp glue code này: ai sở hữu API thì người đó maintain integration.


2. MCP giải quyết như thế nào? (How MCP Works)

MCP thay đổi hoàn toàn cách tiếp cận bằng nguyên lý Phân tách trách nhiệm (Separation of Concerns): chuyển dịch gánh nặng định nghĩa tool và thực thi từ server ứng dụng của tôi sang các MCP Server chuyên biệt (dedicated MCP servers).

Kiến trúc 3 thành phần

Kiến trúc 3 tầng của Model Context Protocol Hệ thống của tôi (Client Environment) Claude (LLM) Suy luận & quyết định Tool Use MCP Client Điều phối request / response Model Context Protocol Chuẩn giao tiếp — truyền Tool Schemas & Results MCP Server Database MCP Server Filesystem MCP Server GitHub / Slack PostgreSQL / SQLite File System cục bộ GitHub / Slack API
Kiến trúc MCP: app của tôi (Client) không đụng tới GitHub/DB trực tiếp — mọi tích hợp được đẩy xuống các MCP Server chuyên biệt, nối với nhau qua một giao thức chuẩn.

MCP Client (Ứng dụng của tôi): Đóng vai trò là Client kết nối với mô hình Claude. Nó không cần biết chi tiết GitHub hoạt động ra sao — chỉ cần duy trì kết nối MCP đến Server.

MCP Server (Tác nhân trung gian): Là một ứng dụng gọn nhẹ chạy độc lập, đóng gói toàn bộ logic gọi API của dịch vụ ngoài và tự khai báo (expose) các công cụ dưới dạng một bộ schema chuẩn hóa. Mỗi MCP Server cung cấp 3 loại tài nguyên:

  • Tools — các hàm Claude có thể gọi (ví dụ get_repos()).
  • Prompts — các prompt template được đóng gói sẵn.
  • Resources — dữ liệu/tài liệu Claude có thể đọc.

Outside Service (Dịch vụ bên ngoài): GitHub, AWS, Google Calendar, Postgres Database, Slack...

Ví dụ cụ thể

Thay vì tôi tự viết schema cho hàm get_repos() rồi viết code gọi GitHub REST API, GitHub MCP Server đã dựng sẵn tất cả. Ứng dụng của tôi (MCP Client) chỉ cần kết nối tới Server này. Khi Claude cần tìm repo, luồng xử lý như sau:

  1. Claude quyết định gọi tool get_repos (đây là Tool Use — năng lực suy luận của model).
  2. Yêu cầu được gửi từ Claude → MCP Client → MCP Server.
  3. MCP Server thực thi logic gọi GitHub API, lấy dữ liệu.
  4. Kết quả trả ngược: MCP Server → MCP Client → Claude.
  5. Claude đọc kết quả và trả lời user.

Tôi không viết một dòng code GitHub nào — MCP Server lo hết.


3. Cơ chế truyền tải và các loại Message trong MCP (Transport & Message Types)

Dưới góc độ kiến trúc hệ thống, MCP được thiết kế cực kỳ linh hoạt để hoạt động trên nhiều môi trường khác nhau nhờ hai đặc tính cốt lõi:

Độc lập với phương thức truyền tải (Transport Agnostic)

MCP Client và MCP Server có thể giao tiếp với nhau qua bất kỳ giao thức mạng hoặc kênh truyền dữ liệu nào (transport layer). Chúng không bị trói buộc vào một công nghệ mạng cụ thể:

  • Standard Input/Output (stdio): Đây là phương thức phổ biến nhất. Client và Server chạy trên cùng một máy, giao tiếp trực tiếp qua dòng đọc/ghi chuẩn (stdin/stdout). Tốc độ cực nhanh và bảo mật cao vì không cần mở cổng mạng ra ngoài.
  • WebSockets: Dùng khi Client và Server chạy ở hai máy chủ khác nhau, cần kết nối real-time hai chiều liên tục qua mạng.
  • HTTP / SSE (Server-Sent Events): Dùng cho mô hình client-server truyền thống qua web.

Các loại Message chính trong đặc tả MCP (MCP Message Types)

Khi Client kết nối thành công tới Server, chúng trao đổi thông tin bằng các cấu trúc message được định nghĩa sẵn trong đặc tả kỹ thuật (specification) của MCP. Hai cặp message quan trọng nhất cần nắm cho kỳ thi là:

  1. Truy vấn danh sách công cụ (Tool Discovery):
    • ListToolsRequest: Client hỏi Server: "Ông đang có những tools nào?"
    • ListToolsResult: Server trả về danh sách các tools kèm schema chi tiết (JSON Schema) của từng tool.
  2. Thực thi công cụ (Tool Execution):
    • CallToolRequest: Client yêu cầu Server: "Hãy chạy tool [X] với các tham số [Y] này hộ tôi."
    • CallToolResult: Server thực thi xong và trả về kết quả dữ liệu (hoặc báo lỗi).

4. Luồng xử lý dữ liệu hoàn chỉnh (The End-to-End Flow)

Hãy xem cách một câu hỏi của user: "Tôi có những repositories nào?" đi qua toàn bộ hệ thống tích hợp MCP. Đây là chu trình 12 bước khép kín từ user đến GitHub và trả lại Claude:

Chu trình chia làm 2 pha: Tool Discovery (bước 1–5, lấy danh sách tool) rồi Tool Execution (bước 6–12, chạy tool và trả lời).

Luồng xử lý end-to-end của MCP (sequence diagram) Năm tác nhân: Bạn, Ứng dụng (App), MCP Client, MCP Server (Bếp), AI (Claude). Pha 1 Tool Discovery gồm bước 1 tới 5; pha 2 Tool Execution gồm các bước còn lại. Bạn Ứng dụng (App) MCP Client MCP Server (Bếp) AI (Claude) Đọc file report.pdf giúp tôi Hỏi: Bếp có công cụ gì? list_tools() Trả về: [read_doc_contents, …] Danh sách công cụ Gửi câu hỏi + danh sách công cụ Chạy: read_doc_contents(file=report.pdf) Yêu cầu chạy tool call_tool(read_doc_contents, {file:report.pdf}) Trả về nội dung file PDF Nội dung file PDF Gửi nội dung PDF cho Claude Nội dung report.pdf là: … Claude thấy có tool read_doc_contents → quyết định gọi nó (Tool Use) Server thực thi: đọc nội dung file PDF Pha 1 · Tool Discovery (trên) — Pha 2 · Tool Execution (dưới)
Luồng end-to-end: câu hỏi của Bạn đi xuống App → MCP Client → MCP Server, quay lại Claude để suy luận (Tool Use), rồi lặp lại vòng thứ hai để chạy tool và trả kết quả. Bảng dưới liệt kê chi tiết từng bước.
# Luồng đi Message / Hành động
Pha 1 — Tool Discovery
1 User → App Server (tôi) "What repositories do I have?"
2 App → MCP Client Hỏi các tool khả dụng
3 Client → MCP Server ListToolsRequest — "Bạn có tool nào?"
4 Server → Client ListToolsResult — danh sách tool + JSON Schema (get_repos…)
5 App → Claude Gửi câu hỏi user + danh sách Tool Schemas
Pha 2 — Tool Execution
6 Claude → App Suy luận, quyết định gọi get_repos → trả tool use request
7 App → MCP Client Yêu cầu chạy tool get_repos
8 Client → MCP Server CallToolRequest — chạy get_repos
9 Server → GitHub API Gọi GitHub API thực tế
10 GitHub → Server → Client Trả repository data, đóng gói thành CallToolResult
11 App → Claude Gửi tool result về cho Claude (follow-up message)
12 Claude → App → User Soạn câu trả lời cuối: "Your repositories are…"

Chu trình này nhìn thì phức tạp, nhưng mỗi thành phần làm đúng một vai trò duy nhất. MCP Client đóng vai trò che giấu toàn bộ sự phức tạp trong việc kết nối với server, giúp app của tôi chỉ cần tập trung vào nghiệp vụ chính.


5. Phát triển MCP Server bằng Python SDK (Building an MCP Server)

Việc xây dựng một MCP Server trở nên cực kỳ đơn giản khi tôi sử dụng SDK chính thức của Anthropic (Python hoặc TypeScript). Thay vì phải viết các bộ JSON Schema khổng lồ và phức tạp bằng tay, tôi có thể định nghĩa các công cụ thông qua các decorators (bộ trang trí) và để SDK tự động xử lý phần việc nặng nhọc phía sau.

Khởi tạo MCP Server với FastMCP

FastMCP là một high-level framework nằm trong SDK của Anthropic, giúp việc khởi tạo Server chỉ tốn đúng 1 dòng code:

from mcp.server.fastmcp import FastMCP

# Khởi tạo một MCP Server tên là "DocumentMCP"
mcp = FastMCP("DocumentMCP", log_level="ERROR")

# Giả lập database tài liệu lưu tạm trong bộ nhớ (In-memory dict)
docs = {
    "deposition.md": "This deposition covers the testimony of Angela Smith, P.E.",
    "report.pdf": "The report details the state of a 20m condenser tower.",
    "plan.md": "The plan outlines the steps for the project's implementation."
}

Định nghĩa công cụ bằng Decorator (@mcp.tool)

Để đăng ký một hàm Python thông thường thành một công cụ mà Claude có thể hiểu và gọi, tôi chỉ cần bọc nó bằng decorator @mcp.tool.

SDK sẽ tự động đọc Python Type Hints (gợi ý kiểu dữ liệu) và các mô tả Pydantic Field để tự động sinh ra JSON Schema chuẩn gửi cho Claude.

1. Xây dựng công cụ đọc tài liệu (read_doc_contents)

from pydantic import Field

@mcp.tool(
    name="read_doc_contents",
    description="Read the contents of a document and return it as a string."
)
def read_document(
    doc_id: str = Field(description="Id of the document to read")
):
    if doc_id not in docs:
        # Ném lỗi trực tiếp bằng Python Exception, SDK tự dịch sang CallToolResult lỗi
        raise ValueError(f"Doc with id {doc_id} not found")
    
    return docs[doc_id]

2. Xây dựng công cụ sửa tài liệu (edit_document)

Công cụ này thực hiện thao tác tìm và thay thế (find-and-replace) chuỗi trong tài liệu:

@mcp.tool(
    name="edit_document",
    description="Edit a document by replacing a string in the documents content with a new string."
)
def edit_document(
    doc_id: str = Field(description="Id of the document that will be edited"),
    old_str: str = Field(description="The text to replace. Must match exactly, including whitespace."),
    new_str: str = Field(description="The new text to insert in place of the old text.")
):
    if doc_id not in docs:
        raise ValueError(f"Doc with id {doc_id} not found")
    
    docs[doc_id] = docs[doc_id].replace(old_str, new_str)
    return f"Document {doc_id} updated successfully."

Lợi ích cốt lõi khi dùng SDK (Thay vì viết tay JSON Schema)

Dưới góc nhìn quản lý phát triển dự án, sử dụng SDK chính hãng giúp tối ưu hóa quy trình làm việcgiảm thiểu bug đáng kể nhờ:

  1. Không cần viết JSON Schema thủ công: Lập trình viên chỉ cần viết code Python thông thường. Định nghĩa tool schema chuẩn của Anthropic tự sinh ra tự động.
  2. Tự động Validation dữ liệu đầu vào (Type Checking): Nhờ Python Type Hints và Pydantic, SDK tự động kiểm tra xem tham số Claude truyền xuống có đúng kiểu str, int hay không trước khi chạy code của tôi. Nếu sai, nó tự báo lỗi về cho Claude mà không làm crash server.
  3. Tích hợp xử lý lỗi tự nhiên: Bất kỳ lỗi logic nào ném ra qua raise ValueError hay raise Exception trong Python đều được SDK bắt lại và chuyển thành kết quả lỗi (is_error=True) gửi về qua giao thức MCP, giúp Claude hiểu lý do lỗi để tự sửa sai hoặc báo lại cho user.

6. Kiểm thử và Gỡ lỗi với MCP Inspector (Testing & Debugging MCP)

Khi phát triển các MCP Server, lập trình viên cần một phương thức nhanh gọn để kiểm tra xem các tools, prompts và resources của mình có hoạt động đúng thiết kế hay không mà không cần phải cắm vào một ứng dụng client đầy đủ hay gọi trực tiếp tới Claude (tránh tốn chi phí và chậm trễ).

Để giải quyết bài toán này, SDK chính hãng cung cấp sẵn một công cụ gỡ lỗi trực quan trên trình duyệt gọi là MCP Inspector.

Cách khởi động Inspector

Đầu tiên, kích hoạt môi trường ảo Python của dự án, sau đó chạy lệnh:

mcp dev mcp_server.py

Lệnh mcp dev sẽ khởi động một development server cục bộ và cung cấp một đường dẫn URL (mặc định là http://127.0.0.1:6274). Mở URL này trên trình duyệt để truy cập giao diện MCP Inspector.

Giao diện và các bước kiểm thử

  1. Kết nối (Connect): Trên giao diện Web Inspector, nhấn nút Connect để khởi tạo kết nối bắt tay giữa Inspector (MCP Client giả lập) và MCP Server của tôi. Trạng thái sẽ chuyển từ "Disconnected" sang "Connected".
  2. Khám phá (Discovery): Vào tab Tools để xem toàn bộ danh sách các công cụ mà Server cung cấp (bản chất tương đương việc gửi ListToolsRequest).
  3. Chạy thử công cụ (Tool Execution): Chọn một tool cụ thể (ví dụ read_doc_contents). Giao diện sẽ tự động hiển thị các ô nhập liệu cho từng tham số đầu vào của tool dựa trên JSON Schema mà Server trả về. Nhập dữ liệu (ví dụ doc_id: 'plan.md') và nhấn Run Tool.
  4. Kiểm tra kết quả: Trình duyệt sẽ hiển thị trực quan kết quả dữ liệu trả về và trạng thái thành công/thất bại của cuộc gọi.

Tính chất duy trì trạng thái (State Persistence)

Một ưu điểm lớn của MCP Inspector phục vụ cho quá trình tích hợp hệ thống là Duy trì trạng thái (State Persistence):

  • Server MCP duy trì trạng thái bộ nhớ hoặc kết nối DB của nó xuyên suốt phiên kết nối (session).
  • Ví dụ luồng test liên tục: Tôi có thể gọi tool edit_document để thay thế một đoạn text trong tài liệu, sau đó gọi ngay tool read_doc_contents để kiểm tra. Nội dung mới sẽ được cập nhật chính xác. Điều này cho phép giả lập và test toàn bộ luồng nghiệp vụ phức tạp của Agent trước khi bàn giao.

7. Xây dựng MCP Client (Client Side)

Server đã chạy, giờ tới phía client — lớp để code ứng dụng của tôi giao tiếp được với MCP Server và gọi được các chức năng của nó.

Lưu ý thực tế: trong hầu hết dự án thật, tôi chỉ implement một phía — hoặc MCP Client, hoặc MCP Server, hiếm khi cả hai. Khóa này dựng cả hai chỉ để tôi thấy chúng ăn khớp với nhau thế nào.

Hai thành phần của phía client (đừng nhầm)

  • MCP Client — class tôi tự viết, bọc lại cho việc dùng session dễ hơn.
  • Client Sessionkết nối thật tới server, là thành phần có sẵn trong MCP Python SDK (tôi không tự viết).

Vì sao phải bọc Client Session trong class riêng? Vì Client Session cần quản lý tài nguyên (resource management) cẩn thận — kết nối đã mở thì bắt buộc phải dọn dẹp (cleanup) đúng cách khi dùng xong, nếu không sẽ rò rỉ kết nối. Bọc nó trong MCPClient giúp toàn bộ việc cleanup diễn ra tự động (thường qua async context manager) — tôi không phải nhớ đóng kết nối thủ công.

Client cắm vào ứng dụng ở đúng hai điểm

Nhìn lại luồng 12 bước ở mục 4: code CLI của tôi dùng client để (1) lấy danh sách tool gửi cho Claude, và (2) thực thi tool khi Claude yêu cầu. Đúng hai hàm cần implement:

list_tools() — lấy toàn bộ tool từ server

async def list_tools(self) -> list[types.Tool]:
    result = await self.session().list_tools()
    return result.tools

Rất gọn: truy cập session (kết nối tới server) → gọi method list_tools() có sẵn của SDK → trả về result.tools.

call_tool() — thực thi một tool cụ thể trên server

async def call_tool(
    self, tool_name: str, tool_input: dict
) -> types.CallToolResult | None:
    return await self.session().call_tool(tool_name, tool_input)

Truyền tool_nametool_input (do Claude cung cấp sau khi suy luận) xuống server, rồi trả về kết quả.

Nối hai đầu: hàm client ↔ message MCP

Hai hàm này chỉ là lớp mỏng gọi thẳng method của session — nhưng bên dưới, chính chúng phát ra cặp message đã học ở mục 3:

Hàm client (Python SDK) Message MCP phát ra Pha
self.list_tools() ListToolsRequestListToolsResult Tool Discovery
self.call_tool() CallToolRequestCallToolResult Tool Execution

Kiểm thử phía client

  • Test riêng client — file client có sẵn test harness ở cuối. Chạy trực tiếp:
    uv run mcp_client.py
    
    Nó sẽ kết nối tới MCP Server và in ra danh sách tool khả dụng (kèm description + input_schema).
  • Test toàn bộ luồng — chạy app chính:
    uv run main.py
    
    Thử hỏi: "What is the contents of the report.pdf document?" Hậu trường diễn ra đúng chu trình: (1) app dùng client lấy danh sách tool → (2) gửi Claude kèm câu hỏi → (3) Claude quyết định gọi read_doc_contents → (4) app dùng client thực thi tool đó → (5) kết quả trả về cho Claude → (6) Claude soạn câu trả lời cuối.

Góc nhìn thực tế

MCP Client chính là cầu nối giữa logic ứng dụng và chức năng của MCP Server — nó che giấu toàn bộ độ phức tạp của việc kết nối (đúng vai trò "che giấu phức tạp" ở mục 4). Việc tách một wrapper class chuyên lo vòng đời kết nối (connection lifecycle) là pattern tôi luôn khuyến khích trong dự án: mã nghiệp vụ không nên rải rác lệnh mở/đóng kết nối — gom hết vào một chỗ thì vừa gọn, vừa tránh lỗi rò rỉ tài nguyên khó truy vết.


8. Resources — phơi dữ liệu read-only cho client (MCP Resources)

Ngoài Tools, MCP Server còn cấp một loại tài nguyên nữa: Resources. Cách nhớ chuẩn nhất: Resource giống một GET request handler trong HTTP server — dùng để lấy thông tin (fetch), KHÔNG phải để thực hiện hành động. (Tool thì giống POST — làm gì đó, có side-effect.)

⚠️ Resource khác Tool ở chỗ nào? Ai điều khiển?

Đây là ranh giới quan trọng nhất, rất hay ra thi:

Tool Resource
Ai quyết định dùng Claude tự suy luận rồi gọi (model-controlled) Code của tôi (Our Code) chủ động lấy (application-controlled)
Dữ liệu tới Claude bằng cách Claude gọi tool → nhận CallToolResult Tôi inject dữ liệu thẳng vào prompt trước khi gửi
Ví dụ read_doc_contents (Claude gọi khi cần) @mention một tài liệu

Ví dụ feature @mention: user gõ @report.pdf trong câu hỏi → code của tôi đọc nội dung file và nhét thẳng (inject) vào prompt trong thẻ <document id="report.pdf">…</document> trước khi gửi cho Claude. Claude không cần gọi tool để lấy nội dung — nó đã nằm sẵn trong prompt. Đây chính là điểm phân biệt Resource (app chủ động cấp dữ liệu) với Tool (Claude chủ động đi lấy).

Cơ chế request-response

Resource theo mẫu request-response, với một cặp message mới (song song ListTools* / CallTool* ở mục 3):

  • ReadResourceRequest — client gửi kèm một URI để định danh resource cần đọc.
  • ReadResourceResult — server chạy hàm tương ứng và trả về dữ liệu.

Luồng của feature @mention (kết hợp cả hai loại resource bên dưới):

# Luồng đi Message / Hành động
1 User gõ ký tự @
2 Our Code → Client → Server ReadResourceRequest (docs://documents)
3 Server chạy list_docs(), trả danh sách tên doc ReadResourceResult → đổ vào autocomplete
4 User chọn @report.pdf
5 Our Code → Client → Server ReadResourceRequest (docs://documents/report.pdf)
6 Server chạy fetch_doc("report.pdf"), trả nội dung ReadResourceResult
7 Our Code inject nội dung vào prompt (<document>) rồi gửi Claude

Hai loại Resource

Phân biệt bằng URI có param hay không:

1. Direct Resource — URI tĩnh, không param

Dùng cho thao tác không cần tham số (vd: liệt kê toàn bộ doc cho autocomplete).

@mcp.resource(
    "docs://documents",
    mime_type="application/json"
)
def list_docs() -> list[str]:
    return list(docs.keys())

2. Templated Resource — URI có param

URI chứa param trong ngoặc nhọn {…}. Python SDK tự parse param từ URI rồi truyền vào hàm dưới dạng keyword argument.

@mcp.resource(
    "docs://documents/{doc_id}",
    mime_type="text/plain"
)
def fetch_doc(doc_id: str) -> str:
    if doc_id not in docs:
        raise ValueError(f"Doc with id {doc_id} not found")
    return docs[doc_id]

Chi tiết triển khai

  • Resource trả về kiểu dữ liệu bất kỳ: string, JSON, binary… mime_type chỉ là gợi ý cho client biết đang nhận loại dữ liệu gì: application/json (dữ liệu có cấu trúc), text/plain (văn bản), application/pdf (file nhị phân).
  • SDK tự serialize giá trị trả về — tôi cứ return list(...)/return dict(...), KHÔNG cần tự json.dumps thủ công.
  • Test: uv run mcp dev mcp_server.py → Inspector hiện 2 mục riêng: Resources (direct/tĩnh) và Resource Templates (có param — phải nhập giá trị param mới chạy thử được). Inspector cho thấy đúng cấu trúc response (kèm MIME type + dữ liệu đã serialize) mà client sẽ nhận.

Phía client: hàm read_resource

Ở mục 7, MCP Client đã có list_tools() + call_tool() (dành cho Tools). Để đọc resource, client cần thêm hàm thứ ba — read_resource — chính là thứ phát ra ReadResourceRequest trong sơ đồ trên, khép cặp với @mcp.resource phía server.

import json
from pydantic import AnyUrl

async def read_resource(self, uri: str) -> Any:
    result = await self.session().read_resource(AnyUrl(uri))
    resource = result.contents[0]

    if isinstance(resource, types.TextResourceContents):
        if resource.mimeType == "application/json":
            return json.loads(resource.text)

    return resource.text

Giải thích cấu trúc response:

  • AnyUrl(uri) — server định danh resource bằng URI (vd docs://documents). AnyUrl là kiểu bọc chuỗi URI cho đúng chuẩn (Pydantic yêu cầu).
  • result.contents[0] — server trả về một danh sách contents; ta lấy phần tử đầu vì mỗi lần thường chỉ đọc một resource. Mỗi item gồm: nội dung thật (text/data), mimeType (để biết cách parse), và metadata khác.
  • Rẽ nhánh theo mimeType (đây là lý do phải khai mime_type phía server ở trên):
    • application/jsonjson.loads để bung chuỗi thành object Python (vd list tên doc từ list_docs).
    • còn lại → trả text thô (vd nội dung file từ fetch_doc, text/plain).

Ví dụ khớp hai loại resource: read_resource("docs://documents") (Direct, JSON) trả về list Python để đổ vào autocomplete; read_resource("docs://documents/report.pdf") (Templated, text) trả nguyên nội dung file để inject vào prompt.

Test qua CLI:@ → hiện autocomplete → chọn bằng phím mũi tên + space → nội dung tài liệu chèn thẳng vào prompt → gửi model không cần tool call. Đây là trải nghiệm mượt hơn nhiều so với việc bắt Claude gọi tool riêng để lấy nội dung.

Góc nhìn thực tế

Trong dự án thật, tôi phân tuyến rõ: dữ liệu read-only ổn định (danh mục, cấu hình, nội dung tài liệu) thì để Resource cho app chủ động inject — vừa tiết kiệm một vòng tool-call, vừa đảm bảo Claude luôn có sẵn ngữ cảnh chuẩn. Còn thao tác có side-effect hoặc Claude cần tự quyết khi nào chạy thì mới để Tool. Chọn sai (nhét dữ liệu tra cứu vào Tool) làm tăng số vòng lặp gọi model — chậm và tốn token.


9. Prompts — câu lệnh mẫu pha sẵn (MCP Prompts)

Capability thứ ba của MCP Server (sau ToolsResources) là Prompts: các hướng dẫn (instruction) chất lượng cao, pha sẵn do chính tác giả server soạn và test kỹ, để client dùng lại thay vì tự viết prompt từ đầu. Coi như những template được chăm chút cho kết quả tốt hơn thứ user tự nghĩ ra.

Vì sao cần Prompt?

User hoàn toàn có thể tự bảo Claude làm việc — vd gõ Convert report.pdf to markdownchạy được, kết quả tạm ổn. Nhưng nếu tác giả server cung cấp một prompt đã test & eval kỹ (xử lý edge case, theo best practice) thì user ra kết quả ổn định và chất lượng hơn hẳn — mà không cần bản thân giỏi prompt engineering. Tác giả server bỏ công craft/test/eval một lần, mọi user hưởng lợi.

⚠️ Bộ ba control model — "ai kích hoạt?" (điểm thi quan trọng)

Đây là mảnh ghép hoàn thiện bức tranh MCP Server. Mỗi capability có một người điều khiển khác nhau:

Capability Ai kích hoạt Ví dụ
Tool Claude (model-controlled) Claude tự quyết gọi read_doc_contents
Resource Code của tôi (application-controlled) @mention inject nội dung vào prompt
Prompt User (user-controlled) User gõ /format chọn câu lệnh

→ Prompt là cái duy nhất user chủ động chọn, thường qua slash command (/).

Ví dụ: command /format

Workflow của một format command (convert tài liệu sang markdown):

  1. User gõ / → hiện danh sách command khả dụng.
  2. Chọn format + nhập doc_id.
  3. Claude dùng prompt pha sẵn để đọc và reformat tài liệu.
  4. Trả về markdown sạch (header, list, table đúng chuẩn).

Định nghĩa Prompt bằng @mcp.prompt

Cùng pattern decorator với @mcp.tool / @mcp.resource:

@mcp.prompt(
    name="format",
    description="Rewrites the contents of the document in Markdown format."
)
def format_document(
    doc_id: str = Field(description="Id of the document to format")
) -> list[base.Message]:
    prompt = f"""
Your goal is to reformat a document to be written with markdown syntax.

The id of the document you need to reformat is:
<document_id>
{doc_id}
</document_id>

Add in headers, bullet points, tables, etc as necessary.
Use the 'edit_document' tool to edit the document. After the document
has been reformatted...
"""
    return [
        base.UserMessage(prompt)
    ]

Điểm cần nhớ:

  • Hàm trả về một list các message (base.UserMessage(...)) — được gửi thẳng cho Claude. Có thể nhét nhiều UserMessage + AssistantMessage để dựng hội thoại phức tạp hơn.
  • {doc_id} được nội suy (interpolate) vào template — SDK điền giá trị user nhập vào chỗ trống.
  • Prompt có thể ra lệnh cho Claude dùng Tool (ở đây bảo Claude gọi edit_document) → Prompt điều phối được cả Tool.

Phía client: list_prompts + get_prompt

Đây là bước cuối hoàn thiện MCP Client. Sau list_tools/call_tool (Tools) và read_resource (Resources), client cần thêm 2 hàm cho Prompts.

list_prompts — liệt kê prompt khả dụng (để đổ lên menu khi user gõ /):

async def list_prompts(self) -> list[types.Prompt]:
    result = await self.session().list_prompts()
    return result.prompts

get_prompt — lấy một prompt cụ thể, có xử lý nội suy biến (variable interpolation):

async def get_prompt(self, prompt_name, args: dict[str, str]):
    result = await self.session().get_prompt(prompt_name, args)
    return result.messages
  • args là một dict → xuống server trở thành keyword arguments của hàm prompt. Vd prompt format_document cần doc_id: client gửi args = {"doc_id": "plan.md"} → giá trị được nội suy vào chỗ {doc_id} trong template.
  • get_prompt trả về result.messages — list message đã điền sẵn biến, sẵn sàng gửi cho Claude.

Test CLI:/ → prompt hiện thành command → chọn format → chọn document → gửi trọn prompt cho Claude → Claude nhận instruction + doc_id rồi tự dùng tool (edit_document) để fetch và xử lý nội dung.

Workflow tổng của Prompt (5 nhịp): viết & eval prompt → định nghĩa bằng @mcp.prompt phía server → client request bất kỳ lúc nào → args client cung cấp thành kwargs của hàm → hàm trả về messages đã format sẵn cho model.

Tới đây MCP Client đã đủ 5 hàm, chia theo capability: Tools (list_tools/call_tool), Resources (read_resource), Prompts (list_prompts/get_prompt).

Luồng lệnh /format của MCP Prompts (sequence diagram) Năm tác nhân: Bạn, Ứng dụng (App), MCP Client, MCP Server, AI (Claude). Pha trên dùng list_prompts để liệt kê lệnh; pha dưới dùng get_prompt để ráp bộ tin nhắn hoàn chỉnh rồi gửi Claude. Bạn Ứng dụng (App) MCP Client MCP Server AI (Claude) Gõ "/" list_prompts() Hỏi các lệnh có sẵn Trả về: ["format", …] Hiện menu lệnh mẫu Chọn "/format" + file "plan.md" get_prompt("format", {doc_id: plan.md}) Yêu cầu ráp lệnh Trả bộ tin nhắn đã ráp "plan.md" Bộ tin nhắn hoàn chỉnh Gửi bộ tin nhắn sang Claude Claude nhận lệnh mẫu chi tiết, bắt đầu xử lý file "plan.md" Liệt kê lệnh · list_prompts (trên) — Ráp lệnh · get_prompt (dưới)
Luồng lệnh /format: list_prompts() lấy danh sách lệnh đổ vào menu (pha trên); sau khi user chọn, get_prompt() gửi doc_id để server ráp bộ tin nhắn đã nội suy biến, rồi App gửi trọn bộ sang Claude (pha dưới). Mũi tên nét đứt là chiều trả về.

4 lợi ích cốt lõi

  • Consistency — user ra kết quả đáng tin, lần nào cũng vậy.
  • Expertise — đóng gói kiến thức chuyên môn (domain knowledge) vào prompt.
  • Reusability — nhiều client application dùng chung một prompt.
  • Maintenance — sửa prompt ở một chỗ, mọi client được nâng cấp theo.

Test

MCP Inspector cho xem chính xác các message sẽ gửi tới Claude, gồm cả cách biến ({doc_id}) được nội suy vào template → kiểm chứng prompt đúng trước khi user bắt đầu phụ thuộc vào nó.

Prompt phát huy tốt nhất khi chuyên biệt cho domain của server: server quản lý tài liệu thì có prompt format/summarize/analyze; server phân tích dữ liệu thì có prompt sinh report/visualization. Mục tiêu: prompt craft kỹ tới mức user thích dùng nó hơn tự viết.


10. Ai viết MCP Server? Và ba câu hỏi dễ nhầm

Ai là người phát triển các MCP Server?

Bất kỳ ai cũng có thể xây dựng MCP Server. Xu hướng tối ưu nhất là chính nhà cung cấp dịch vụ (service providers) sẽ phát hành và duy trì MCP Server cho dịch vụ của họ. Ví dụ: AWS phát hành MCP Server cho các dịch vụ Cloud, GitHub cho repositories, Slack cho messaging. Lập trình viên chỉ cần tải về và kết nối — không cần tự viết lại từ đầu.

MCP khác gì so với việc gọi API trực tiếp?

Tiêu chí Gọi API trực tiếp Dùng MCP
Tool schema Tự viết từng cái Server cung cấp sẵn
Code thực thi Tự viết API wrapper Server đã implement
Xác thực (Auth) Tự quản lý Server xử lý
Bảo trì khi API đổi Tôi phải sửa Nhà cung cấp sửa

⚠️ MCP có phải là Tool Use không? (Điểm thi quan trọng)

Đây là misconception phổ biến nhất mà bài học nhấn mạnh — và gần như chắc chắn sẽ xuất hiện trong đề thi CCA-F:

  • MCPTool Use là hai khái niệm bổ trợ nhau nhưng hoàn toàn khác biệt.
  • MCP (Model Context Protocol):giao thức kết nối — trả lời câu hỏi "Ai xây dựng và thực thi các tool đó?". MCP giúp di chuyển phần triển khai code ra ngoài ứng dụng chính.
  • Tool Use (Function Calling):năng lực suy luận của mô hình — trả lời câu hỏi "Claude chọn tool nào, truyền tham số gì?". Đây là cơ chế Claude đọc description của tool rồi quyết định có gọi hay không.

Câu tóm gọn để nhớ: MCP là hạ tầng cung cấp công cụ, Tool Use là cách Claude sử dụng các công cụ đó. MCP servers cung cấp tool schemas và functions đã được định nghĩa sẵn cho tôi; Tool Use là cách Claude thực sự gọi những tools đó.


11. Bức tranh lớn: Tools vs Skills vs MCP — ai maintain cái gì?

Khép lại, ta quay về câu hỏi then chốt xuyên suốt khóa MCP: ai chịu trách nhiệm maintain integration?

Cơ chế Dùng cho Ai maintain
Tools (Custom) Hệ thống nội bộ (DB, tracker, API riêng) Tôi
Skills Quy trình (template, checklist, SOP) Tôi
MCP Service bên thứ ba (GitHub, Slack, AWS...) Nhà cung cấp

Câu ngắn gọn mà tôi ghi nhớ từ khóa Claude Platform 101:

Tools = đồ của tôi · Skills = quy trình của tôi · MCP = đồ của người khác.

Đây là lý do MCP tồn tại song song với custom tools và skills — mỗi cái trị một bài toán khác nhau.


Liên quan trong lộ trình

  • Đào sâu hands-on — dựng MCP server bằng FastMCP, viết client, resources & prompts từng dòng code: MCP với Claude API (Phần 6).
  • MCP trong Claude Code — cách cắm sẵn MCP server (GitHub, Cloudflare…) vào công cụ hằng ngày: Claude Code 101.

Từ khoá cần thuộc

🔴 Core:

  • Model Context Protocol (MCP) — giao thức chuẩn hóa kết nối AI với các nguồn dữ liệu/công cụ ngoài.
  • MCP Client — phía ứng dụng kết nối với Claude, chịu trách nhiệm nhận yêu cầu và điều hướng đến MCP Server.
  • MCP Server — ứng dụng độc lập định nghĩa sẵn và thực thi các tools, prompts, resources; kết nối trực tiếp với Outside Service.
  • MCP ≠ Tool Use — MCP là hạ tầng cung cấp (ai build tool), Tool Use là năng lực suy luận (Claude chọn tool nào).
  • Transport Agnostic — tính chất độc lập phương thức truyền tải (stdio, WebSockets, HTTP/SSE).
  • ListToolsRequest / ListToolsResult — cặp message phục vụ quá trình khám phá công cụ (Tool Discovery).
  • CallToolRequest / CallToolResult — cặp message phục vụ quá trình thực thi công cụ (Tool Execution).
  • FastMCP — high-level framework của Python SDK dùng để khởi tạo MCP Server nhanh chóng.
  • @mcp.tool — decorator dùng để đăng ký một hàm Python thành một MCP Tool khả dụng cho Claude.
  • MCP Inspector (mcp dev) — công cụ gỡ lỗi và kiểm thử MCP Server trực quan trên giao diện trình duyệt.
  • Client Session — kết nối thật tới MCP Server, là thành phần có sẵn trong MCP Python SDK (không tự viết).
  • list_tools() / call_tool() — hai hàm cốt lõi của MCP Client: lấy danh sách tool gửi cho Claude (Tool Discovery) và thực thi tool khi Claude yêu cầu (Tool Execution).
  • Resources — cơ chế MCP Server phơi dữ liệu read-only (giống GET handler); app chủ động lấy và inject vào prompt (application-controlled), khác Tool (Claude tự gọi, model-controlled).
  • ReadResourceRequest / ReadResourceResult — cặp message đọc resource; request kèm một URI định danh resource.
  • Direct vs Templated Resource — URI tĩnh không param (docs://documents) vs URI có param (docs://documents/{doc_id}, SDK tự parse param → keyword argument).
  • @mcp.resource / mime_type — decorator đăng ký resource; mime_type là gợi ý kiểu dữ liệu (application/json, text/plain, application/pdf), SDK tự serialize giá trị trả về.
  • read_resource() — hàm client (thứ ba, sau list_tools/call_tool) để đọc resource: gọi session().read_resource(AnyUrl(uri)), lấy contents[0], rồi rẽ nhánh theo mimeType (application/jsonjson.loads, còn lại → text thô).
  • Prompts — capability thứ ba của MCP Server: các instruction/template pha sẵn đã được tác giả server test & eval, để user dùng lại (thường qua slash command) thay vì tự viết prompt.
  • Control model trio — Tool = model-controlled (Claude gọi), Resource = application-controlled (code inject), Prompt = user-controlled (user chọn qua /command). Nhớ trọn bộ ba này là điểm thi hay gặp.
  • @mcp.prompt / base.UserMessage — decorator đăng ký prompt; hàm trả về list message (base.UserMessage/AssistantMessage) gửi thẳng cho Claude, với biến trong template được nội suy (interpolate).
  • list_prompts() / get_prompt() — hai hàm client cho Prompts: list_prompts trả result.prompts (đổ lên slash menu); get_prompt(name, args) gửi args (dict → kwargs) để server nội suy biến, trả về result.messages sẵn sàng cho Claude. → MCP Client đủ 5 hàm: list_tools/call_tool · read_resource · list_prompts/get_prompt.

🟡 Important:

  • Separation of Concerns (Phân tách trách nhiệm) — nguyên lý cốt lõi: tách logic ứng dụng AI và logic tích hợp hệ thống.
  • Glue Code (Mã tích hợp) — phần code trung gian viết thủ công để nối API ngoài vào ứng dụng; MCP ra đời để triệt tiêu loại code này.
  • Tools = đồ của tôi · Skills = quy trình của tôi · MCP = đồ của người khác — câu phân biệt 3 cơ chế.
  • stdio (Standard Input/Output) — phương thức truyền tải phổ biến nhất của MCP trên môi trường local.
  • Type Hints / Pydantic Field — các cơ chế trong Python dùng để tự động validate kiểu dữ liệu đầu vào và sinh Tool Schema mô tả chi tiết tham số cho Claude.
  • State Persistence (Duy trì trạng thái) — tính chất lưu giữ bộ nhớ/trạng thái của MCP Server xuyên suốt phiên kết nối, cho phép kiểm thử chuỗi hành động liên tục.
  • MCP Client (wrapper class) & Resource Management — class tự viết bọc quanh Client Session để tự động cleanup kết nối khi dùng xong, tránh rò rỉ tài nguyên; đóng vai cầu nối giữa logic ứng dụng và MCP Server.

🟢 Good-to-know:

  • Outside Service — dịch vụ đầu cuối (GitHub, Slack, Databases...) được tích hợp qua MCP Server.
  • Service Providers — nhà cung cấp dịch vụ tự phát hành MCP Server cho dịch vụ của họ.
  • WebSockets / SSE (Server-Sent Events) — các giao thức truyền tải mạng khả dụng cho kết nối MCP từ xa.
  • In-memory dictionary — kiểu dữ liệu lưu trữ tạm bộ nhớ dùng để giả lập tài liệu trong các ví dụ lập trình server.
  • http://127.0.0.1:6274 — địa chỉ URL mặc định của local MCP Inspector.

Nguồn: Introduction to Model Context Protocol (Anthropic Academy) — Copyright Anthropic. Phần đề thi thử cho khoá này nằm ở tab "Đề thi thử".

Câu hỏi thường gặp

Model Context Protocol (MCP) là gì?
MCP là giao thức chuẩn hóa kết nối giữa ứng dụng AI (MCP Client) và các nguồn tài nguyên dữ liệu hoặc công cụ ngoài (MCP Server). Thay vì tự viết hàng chục tool schema và API wrapper, lập trình viên chỉ cần kết nối Client với các MCP Server chuyên biệt đã được định nghĩa sẵn.
MCP giải quyết bài toán gì cho nhà phát triển?
MCP loại bỏ gánh nặng viết mã tích hợp (glue code) và bảo trì API cho bên thứ ba. Khi API của dịch vụ ngoài thay đổi, nhà cung cấp tự cập nhật MCP Server — lập trình viên không phải sửa một dòng code nào trong ứng dụng chính.
Sự khác biệt giữa MCP và Tool Use là gì?
MCP là giao thức định nghĩa cách đóng gói và giao tiếp công cụ (ai cung cấp và chạy công cụ). Tool Use là khả năng lập luận của Claude để quyết định khi nào cần gọi công cụ nào và truyền tham số gì. MCP cung cấp hạ tầng, Tool Use sử dụng hạ tầng đó.
Prompt trong MCP là gì và khác Tool, Resource ra sao?
Prompt là các câu lệnh/template hướng dẫn pha sẵn, do tác giả MCP Server soạn và test kỹ, để user dùng lại thay vì tự viết prompt. Điểm phân biệt nằm ở "ai kích hoạt": Tool do Claude tự gọi (model-controlled), Resource do code ứng dụng inject (application-controlled), còn Prompt do user chủ động chọn — thường qua slash command như /format (user-controlled). Hàm prompt trả về một danh sách message được gửi thẳng cho Claude.
Resource trong MCP khác gì với Tool?
Resource là cơ chế phơi dữ liệu read-only (giống GET request handler), do code ứng dụng chủ động lấy rồi inject thẳng vào prompt trước khi gửi cho Claude (application-controlled). Tool thì do chính Claude suy luận và quyết định gọi khi cần (model-controlled). Ví dụ feature @mention nạp nội dung tài liệu qua Resource nên Claude không phải gọi tool để lấy.
Direct Resource và Templated Resource khác nhau ra sao?
Direct Resource có URI tĩnh không chứa tham số, ví dụ docs://documents, dùng cho thao tác không cần tham số. Templated Resource có tham số trong URI, ví dụ docs://documents/{doc_id} — Python SDK tự parse tham số từ URI và truyền vào hàm dưới dạng keyword argument.
MCP Client và Client Session khác nhau như thế nào?
Client Session là kết nối thật tới MCP Server và có sẵn trong MCP Python SDK. MCP Client là class do lập trình viên tự viết, bọc quanh Client Session để dùng cho tiện và tự động dọn dẹp (cleanup) kết nối khi xong, tránh rò rỉ tài nguyên. Client cung cấp hai hàm chính: list_tools() để lấy danh sách tool gửi cho Claude, và call_tool() để thực thi tool khi Claude yêu cầu.
Ai viết và duy trì các MCP Server?
Bất kỳ ai cũng có thể xây dựng MCP Server. Xu hướng tối ưu là chính nhà cung cấp dịch vụ (ví dụ AWS, GitHub, Slack) tự phát hành và duy trì MCP Server cho dịch vụ của họ — lập trình viên chỉ cần tải về và kết nối.

Đề thi thử (35 câu)

Đề thi thử tự biên soạn, bám sát đề thi chứng chỉ thật — trích 20 câu đầu dưới đây. Bản tương tác — chấm điểm, đáp án & giải thích từng câu — nằm ở tab “Đề thi thử” trên trang.

  1. MCP Architecture What is the primary architectural purpose of the Model Context Protocol (MCP)?

    • A. To automatically cache system prompts and context on Anthropic's servers.
    • B. To establish a standardized communication layer that provides AI models with context and tools without custom integration code.
    • C. To train local small language models on user-provided datasets.
    • D. To enable persistent client-side memory storage across different Claude chat sessions.
  2. MCP Architecture In the MCP architecture, where do tool definitions (schemas) and execution logic primarily reside?

    • A. Inside the client application (MCP Client).
    • B. In Claude's core training weights.
    • C. On the dedicated MCP Server.
    • D. On Anthropic's central database servers.
  3. MCP vs Tool Use How does Model Context Protocol (MCP) differ from traditional Tool Use (Function Calling)?

    • A. MCP is a communication protocol for defining and executing tools, whereas Tool Use is the LLM's cognitive ability to decide when and how to call those tools.
    • B. Tool Use requires the developer to use beta clients, while MCP only works with stable clients.
    • C. MCP is used for image input, whereas Tool Use is only used for text-based tasks.
    • D. There is no difference; they are identical terms for the same concept.
  4. MCP Transport What does the term 'transport agnostic' imply regarding the Model Context Protocol?

    • A. MCP can only function when using local Unix domain sockets.
    • B. MCP clients and servers can communicate over various channels (such as stdio, WebSockets, or HTTP) depending on configuration.
    • C. MCP is bound strictly to the standard HTTPS protocol for remote communication.
    • D. It means the protocol does not support transmitting file or image data.
  5. MCP Messages Which pair of messages is exchanged between the MCP client and server during the Tool Discovery phase?

    • A. CallToolRequest and CallToolResult
    • B. ListToolsRequest and ListToolsResult
    • C. GetSchemaRequest and GetSchemaResult
    • D. InitializeRequest and InitializeResult
  6. MCP Request Flow In the end-to-end flow of an MCP-based user query, which component is responsible for directly executing the tool and calling the external service (such as the GitHub API)?

    • A. Claude (LLM)
    • B. The MCP Client
    • C. The MCP Server
    • D. The application host server
  7. Building MCP Servers How does the FastMCP SDK simplify tool registration compared to manual JSON schema authoring?

    • A. It automatically generates the tool schema for Claude using Python decorators, type hints, and Pydantic field descriptions.
    • B. It translates Python functions into JavaScript client code for execution.
    • C. It removes the need to define any function parameters or arguments.
    • D. It deploys the server code directly into Anthropic's hosted cloud sandbox.
  8. Building MCP Servers How does FastMCP handle Python exceptions (such as ValueError or KeyNotFound) thrown inside tool execution logic?

    • A. It crashes the server process, requiring a manual service restart.
    • B. It silently ignores them and returns an empty text block to Claude.
    • C. It catches the exceptions and automatically translates them into structured error responses (CallToolResult with is_error=True) for Claude.
    • D. It prompts the end user to solve the error in their browser window.
  9. Building MCP Servers What is the primary function of Pydantic's 'Field(description=...)' when used in FastMCP function parameters?

    • A. To specify the memory allocation limits for that variable.
    • B. To supply Claude with semantic context about what the specific parameter expects, guiding its tool calling decision.
    • C. To register the API authentication tokens.
    • D. To configure local logging levels on the application host.
  10. Debugging & Testing Which CLI command launches the built-in, browser-based MCP Inspector for debugging a Python MCP server?

    • A. mcp test mcp_server.py
    • B. mcp dev mcp_server.py
    • C. mcp inspect mcp_server.py
    • D. mcp run mcp_server.py
  11. Debugging & Testing How does the MCP Inspector handle state management between multiple consecutive tool calls?

    • A. It restarts the server process on every call, making it completely stateless.
    • B. It maintains the server's session state in memory, allowing changes made by one tool (e.g., write/edit) to persist for subsequent calls.
    • C. It saves modifications to a temporary git branch on the filesystem.
    • D. It pushes state modifications to Anthropic's central remote database.
  12. Debugging & Testing In the MCP Inspector web interface, what is the very first step required before you can list or test any tools?

    • A. Provide a valid Anthropic API key in the configuration tab.
    • B. Click the Connect button to initialize the handshake and connection to the server.
    • C. Import a custom JSON test suite.
    • D. Select WebSockets as the transport protocol.
  13. Building MCP Clients The MCP client side is composed of two main parts. Which pair correctly describes them?

    • A. A custom MCP Client class we write, and a Client Session that is the actual connection provided by the MCP SDK.
    • B. A FastMCP server instance and a Pydantic validation layer.
    • C. The MCP Inspector and a WebSocket transport handler.
    • D. Two separate Claude models: one for reasoning and one for tool execution.
  14. Building MCP Clients Why is the SDK's Client Session typically wrapped inside a custom MCP Client class?

    • A. Because the Client Session cannot send requests on its own without inheritance.
    • B. To handle careful resource management, ensuring connections are properly cleaned up when finished.
    • C. To encrypt the tool schemas before sending them to Claude.
    • D. Because the SDK forbids calling the session directly from application code.
  15. Building MCP Clients What does the client's list_tools() method return after awaiting the session call?

    • A. A raw JSON string that must be parsed manually.
    • B. The list of tools taken from the result (result.tools).
    • C. A single tool chosen automatically by Claude.
    • D. The full CallToolResult object including execution output.
  16. Building MCP Clients In the client's call_tool(tool_name, tool_input) method, where do the tool_name and tool_input values originate?

    • A. They are hardcoded inside the MCP Server.
    • B. They are provided by Claude after it reasons about which tool to use and with what arguments.
    • C. They are randomly generated by the Client Session.
    • D. They are read directly from the end user's raw text without any model involvement.
  17. Building MCP Clients Which two client operations enable the application to integrate an MCP server into the Claude workflow?

    • A. Compiling the server code and deploying it to the cloud.
    • B. Getting the list of available tools to send to Claude, and executing tools when Claude requests them.
    • C. Caching Claude's responses and streaming them to the browser.
    • D. Authenticating the user and encrypting the network transport.
  18. MCP Resources In an MCP server, resources are most analogous to which concept from a traditional HTTP server?

    • A. POST request handlers that perform actions and mutate state.
    • B. GET request handlers that expose and fetch read-only data.
    • C. Middleware that authenticates incoming requests.
    • D. WebSocket handlers that stream live events.
  19. MCP Resources What is the key control difference between an MCP Resource and an MCP Tool?

    • A. A Resource is decided and invoked by Claude, while a Tool is injected by the application.
    • B. A Resource is fetched by the application code and injected into the prompt, while a Tool is invoked by Claude's own reasoning.
    • C. Both are always invoked automatically by the MCP server with no client involvement.
    • D. A Resource can only return binary data, while a Tool can only return text.
  20. MCP Resources Which message pair does an MCP client use to fetch a resource identified by a URI?

    • A. ListToolsRequest and ListToolsResult
    • B. CallToolRequest and CallToolResult
    • C. ReadResourceRequest and ReadResourceResult
    • D. GetResourceRequest and GetResourceResponse

…và 15 câu nữa trong bản đề thi thử đầy đủ (35 câu) — mở tab “Đề thi thử” trên trang để làm toàn bộ, có chấm điểm & giải thích.