Khóa học
Trong thế giới AI, Model Context Protocol (MCP) nhanh chóng trở thành chủ đề nóng. MCP là một tiêu chuẩn mở giúp các mô hình AI như Claude 4 có một cách nhất quán để kết nối với các công cụ, dịch vụ và nguồn dữ liệu thời gian thực bên ngoài. Khả năng kết nối này tạo nên bước đột phá khi cho phép các mô hình ngôn ngữ lớn (LLM) đưa ra phản hồi phù hợp hơn, cập nhật hơn và có thể hành động bằng cách bắc cầu giữa AI và các hệ thống.
Trong hướng dẫn này, chúng ta sẽ tìm hiểu FastMCP 2.0, một framework mạnh mẽ giúp xây dựng máy chủ MCP riêng chỉ với vài dòng mã. Chúng ta sẽ học về các thành phần cốt lõi của FastMCP, cách xây dựng cả máy chủ và khách MCP, và cách tích hợp chúng mượt mà vào quy trình làm việc của bạn. Nếu bạn mới làm quen với MCP, hãy xem Hướng dẫn Model Context Protocol kèm dự án demo để tìm hiểu thêm.
FastMCP 2.0 là gì?
FastMCP 2.0 là một framework Python mã nguồn mở được thiết kế để giúp việc xây dựng máy chủ và khách Model Context Protocol (MCP) trở nên đơn giản và hiệu quả. Chỉ với vài dòng mã, nhà phát triển có thể tạo các máy chủ MCP tùy chỉnh và kết nối chúng với ứng dụng AI của mình, như trình soạn thảo mã hay trợ lý chatbot.
FastMCP 2.0 kế thừa FastMCP 1.0, hiện được gọi là MCP Python SDK, và cung cấp một bộ công cụ hoàn chỉnh để làm việc trong hệ sinh thái MCP.
Điểm khác biệt của FastMCP 2.0 là bộ tính năng toàn diện vượt xa đặc tả cốt lõi của MCP. Nó tối ưu hóa việc triển khai, xác thực, proxy phía khách và phía máy chủ, và thậm chí cho phép tạo máy chủ từ các REST API.
Các thành phần cốt lõi của FastMCP 2.0
FastMCP 2.0 được xây dựng xoay quanh ba thành phần thiết yếu: Tools, Resources và Prompts.
1. Tools
Tools là các hàm Python được mở ra cho LLM thông qua giao thức MCP. Bằng cách trang trí một hàm với @mcp.tool, bạn cho phép mô hình AI gọi hàm đó trong cuộc hội thoại. Điều này cho phép LLM thực hiện các hành động trong thế giới thực, như truy vấn cơ sở dữ liệu, gọi API, hoặc chạy tính toán.
from fastmcp import FastMCPmcp = FastMCP(name="UtilityServer")@mcp.tooldef convert_usd_to_eur(amount: float, rate: float = 0.91) -> float: """Converts a given amount in USD to EUR using the provided rate.""" return round(amount * rate, 2)
2. Resources
Resources cung cấp cho LLM hoặc ứng dụng khách quyền truy cập chỉ đọc vào dữ liệu, như tệp, bản ghi cơ sở dữ liệu, cấu hình hoặc nội dung được tạo động. Ví dụ:
from fastmcp import FastMCPmcp = FastMCP(name="WeatherResourceServer")@mcp.resource("config://weather-settings")def get_weather_settings() -> dict: """Provides weather configuration.""" return { "default_units": "metric", "default_location": "Berlin", "features_enabled": ["forecast", "alerts"] }@mcp.resource("resource://welcome-message")def welcome_message() -> str: """Returns a dynamic greeting for users based on time of day.""" from datetime import datetime hour = datetime.now().hour if hour < 12: return "Good morning! Here's your weather update." elif hour < 18: return "Good afternoon! Need a forecast?" else: return "Good evening! Let's check the weather."
3. Prompts
Prompts là các mẫu thông điệp có tham số, có thể tái sử dụng để định hướng phản hồi của LLM. Bằng cách định nghĩa prompt dưới dạng hàm, bạn đảm bảo có hướng dẫn nhất quán, giàu ngữ cảnh mà khách có thể gọi.
Các prompt này cần thiết để thực thi nhiều công cụ theo trình tự và hướng dẫn LLM thực hiện một số tác vụ bằng các công cụ và tài nguyên sẵn có.
from fastmcp import FastMCPfrom fastmcp.prompts.prompt import PromptMessage, TextContentmcp = FastMCP(name="TutorPromptServer")@mcp.promptdef explain_math_concept(concept: str) -> PromptMessage: """Creates a message asking an AI tutor to explain a math concept simply.""" text = f"Can you explain the math concept of '{concept}' in a way that's easy for a 12-year-old to understand?" return PromptMessage(role="user", content=TextContent(type="text", text=text))
Xây dựng AI ArXiv Explorer với FastMCP 2.0 và Tavily
Trong phần này, chúng ta sẽ xây dựng một máy chủ MCP "ArXiv Explorer". Máy chủ này sẽ gồm hai công cụ: một công cụ trích xuất liên kết và tiêu đề các bài báo nghiên cứu, và công cụ thứ hai để tóm tắt các bài báo. Bên cạnh các công cụ này, máy chủ cũng sẽ bao gồm resources và prompts để hỗ trợ tạo một báo cáo tổng hợp về chủ đề đã chọn.
1. Thiết lập
Trước khi bắt đầu, bạn cần có khóa API Tavily. Bạn có thể lấy miễn phí khóa với 1.000 yêu cầu mỗi tháng tại tavily.com. Sau đó, cài đặt các thư viện Python cần thiết:
pip install fastmcp tavily-python
2. Xây dựng máy chủ "ArxivExplorer"
Đầu tiên, chúng ta sẽ tạo tệp Python cho máy chủ. Tệp này bao gồm:
- Khởi tạo: Tạo một thể hiện FastMCP với tên máy chủ "ArxivExplorer".
- Resource: Decorator
@mcp.resourcemở hàmarxiv_topicscủa chúng ta như một nguồn dữ liệu chỉ đọc. Ứng dụng AI khách có thể lấy các chủ đề này để có ý tưởng nghiên cứu nếu người dùng chưa chắc chắn. - Tools: Decorator
@mcp.toolbiến các hàm Python thông thường thành các hành động mà LLM có thể thực thi. - search_arxiv: Công cụ này dùng Tavily API để giới hạn tìm kiếm trong một tên miền cụ thể (arxiv.org), đảm bảo chỉ lấy các bài báo khoa học liên quan từ arxiv.org.
- summarize_paper: Công cụ này dùng
qna_searchcủa Tavily, được tối ưu để cung cấp câu trả lời trực tiếp, súc tích, rất phù hợp để tạo bản tóm tắt. - Prompt: Decorator
@mcp.prompttạo một mẫu có thể tái sử dụng. Đây không chỉ là một prompt đơn giản; nó là một kế hoạch chiến lược hướng dẫn LLM cách sử dụng các công cụ của máy chủ theo trình tự để thực hiện một tác vụ phức tạp. - Giao vận HTTP:
mcp.run(transport="http")là một dòng quan trọng. Thay vì dùng “stdio” cho tiến trình cục bộ, nó khởi chạy một máy chủ web. Điều này cho phép bất kỳ client nào trên mạng (hoặc cùng máy) kết nối tới máy chủ của chúng ta qua URL, biến nó thành một công cụ thực sự từ xa và có thể chia sẻ.
server.py:
import osfrom typing import Dict, Listfrom fastmcp import FastMCPfrom tavily import TavilyClient# --- Configuration ---TAVILY_API_KEY = os.environ.get("TAVILY_API_KEY")if not TAVILY_API_KEY: raise ValueError("Please set the TAVILY_API_KEY environment variable.")tavily = TavilyClient(api_key=TAVILY_API_KEY)mcp = FastMCP(name="ArxivExplorer")print("✅ ArxivExplorer server initialized.")# --- Dynamic Resource: Suggested AI research topics ---@mcp.resource("resource://ai/arxiv_topics")def arxiv_topics() -> List[str]: return [ "Transformer interpretability", "Efficient large-scale model training", "Federated learning privacy", "Neural network pruning", ]print("✅ Resource 'resource://ai/arxiv_topics' registered.")# --- Tool: Search ArXiv for recent papers ---@mcp.tool(annotations={"title": "Search Arxiv"})def search_arxiv(query: str, max_results: int = 5) -> List[Dict]: """ Queries ArXiv via Tavily, returning title + link for each paper, and *only* ArXiv results. """ resp = tavily.search( query=f"site:arxiv.org {query}", max_results=max_results ) return [ {"title": r["title"].strip(), "url": r["url"]} for r in resp.get("results", []) ]# --- Tool: Summarize an ArXiv paper ---@mcp.tool(annotations={"title": "Summarize Paper"})def summarize_paper(paper_url: str) -> str: """ Returns a one-paragraph summary of the paper at the given URL. """ prompt = f"Summarize the key contributions of this ArXiv paper: {paper_url}" return tavily.qna_search(query=prompt)print("✅ Tools 'Search Arxiv' and 'Summarize Paper' registered.")# --- Prompt Template: Explore a topic thoroughly ---@mcp.promptdef explore_topic_prompt(topic: str) -> str: return ( f"I want to explore recent work on '{topic}'.\n" f"1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n" f"2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n" f"3. Combine all summaries into an overview report." )print("✅ Prompt 'explore_topic_prompt' registered.")if __name__ == "__main__": print("\n🚀 Starting ArxivExplorer Server...") mcp.run(transport="http")
3. Xây dựng ứng dụng khách tương tác
Chúng ta cần kiểm thử các tính năng và endpoint của máy chủ MCP trước khi tích hợp vào ứng dụng AI. Với mục đích này, FastMCP đã cung cấp một API đơn giản để kết nối máy chủ MCP và kiểm thử tất cả chức năng của nó.
Tệp client bao gồm:
- Giao vận HTTP:
StreamableHttpTransportđược thiết kế đặc biệt để kết nối tới máy chủ FastMCP chạy ở chế độ HTTP. - Trợ giúp unwrap_tool_result: Đây là tiện ích quan trọng. Khách FastMCP không trả về dữ liệu thô; nó trả về các đối tượng có cấu trúc. Hàm này kiểm tra an toàn đối tượng phản hồi và trích xuất dữ liệu Python bạn thực sự cần.
- Quy trình: Hàm chính thực thi một bộ kiểm thử hoàn chỉnh.
- Ping máy chủ để đảm bảo nó đang trực tuyến.
- Liệt kê tất cả tools, resources và prompts hiện có.
- Đọc resource
arxiv_topicsvà phân tích kết quả chính xác. - Gọi tool
search_arxivvà dùng hàm trợ giúp để mở gói danh sách bài báo. - Xâu chuỗi các công cụ bằng cách lấy URL từ kết quả tìm kiếm đầu tiên và truyền cho tool
summarize_paper. - Cuối cùng, lấy
explore_topic_prompt, hiển thị tập lệnh hướng dẫn sẵn sàng gửi cho LLM.
client.py:
import astimport asyncioimport pprintfrom fastmcp import Clientfrom fastmcp.client.transports import StreamableHttpTransport# --- Configuration ---SERVER_URL = "http://localhost:8000/mcp" # adjust if hosted elsewherepp = pprint.PrettyPrinter(indent=2, width=100)def unwrap_tool_result(resp): """ Safely unwraps the content from a FastMCP tool call result object. """ if hasattr(resp, "content") and resp.content: # The content is a list containing a single content object content_object = resp.content[0] # It could be JSON or plain text if hasattr(content_object, "json"): return content_object.json if hasattr(content_object, "text"): try: # Use ast.literal_eval for safely evaluating a string containing a Python literal return ast.literal_eval(content_object.text) except (ValueError, SyntaxError): # If it's not a literal, return the raw text return content_object.text return respasync def main(): transport = StreamableHttpTransport(url=SERVER_URL) client = Client(transport) print("\n🚀 Connecting to FastMCP server at:", SERVER_URL) async with client: # 1. Ping to test connectivity print("\n🔗 Testing server connectivity...") await client.ping() print("✅ Server is reachable!\n") # 2. Discover server capabilities print("🛠️ Available tools:") pp.pprint(await client.list_tools()) print("\n📚 Available resources:") pp.pprint(await client.list_resources()) print("\n💬 Available prompts:") pp.pprint(await client.list_prompts()) # 3. Fetch the topics resource print("\n\n📖 Fetching resource: resource://ai/arxiv_topics") res = await client.read_resource("resource://ai/arxiv_topics") topics = ast.literal_eval(res[0].text) print("Today's AI topics:") for i, t in enumerate(topics, 1): print(f" {i}. {t}") # 4. Test the search tool print("\n\n🔍 Testing tool: search_arxiv") raw_search = await client.call_tool( "search_arxiv", {"query": "Transformer interpretability", "max_results": 3}, ) search_results = unwrap_tool_result(raw_search) for i, paper in enumerate(search_results, 1): print(f" {i}. {paper['title']}\n {paper['url']}") # 5. Test the summarize tool on the first result if search_results: first_url = search_results[0]["url"] print("\n\n📝 Testing tool: summarize_paper") raw_summary = await client.call_tool( "summarize_paper", {"paper_url": first_url} ) summary = unwrap_tool_result(raw_summary) print("\nSummary of first paper:\n", summary) # 6. Test the prompt generator print("\n\n🚀 Testing prompt: explore_topic_prompt") prompt_resp = await client.get_prompt( "explore_topic_prompt", {"topic": "Transformer interpretability"} ) print("\nGenerated prompt for an LLM:") for msg in prompt_resp.messages: print(f"{msg.role.upper()}: {msg.content.text}\n")if __name__ == "__main__": asyncio.run(main())
Tất cả tệp và cấu hình có sẵn tại kho GitHub kingabzpro/FastMCP-Project. Bạn có thể dùng nếu gặp bất kỳ vấn đề nào. Tôi cũng đã bao gồm hướng dẫn thiết lập để chạy cục bộ.
4. Chạy ứng dụng
Bây giờ chúng ta sẽ chạy cả máy chủ và ứng dụng khách MCP.
Trước tiên, đặt khóa API Tavily làm biến môi trường trên hệ thống của bạn:
export TAVILY_API_KEY='your_tavily_api_key'
Tiếp theo, chạy máy chủ:
python server.py
Chỉ sau vài giây, bạn sẽ thấy máy chủ FastMCP chạy tại http://localhost:8000/mcp.

Mở một terminal mới và chạy script client để kiểm thử mọi thứ hoạt động ổn định:
python client.py
Như chúng ta thấy, tất cả chức năng, tài nguyên, công cụ và prompt đều hoạt động hoàn hảo. Máy chủ MCP của chúng ta hoạt động tốt, ngay cả với nhiều yêu cầu API Tavily.
🚀 Connecting to FastMCP server at: http://localhost:8000/mcp🔗 Testing server connectivity...✅ Server is reachable!🛠️ Available tools:[ Tool(name='search_arxiv', title='Search Arxiv', description='Queries ArXiv via Tavily, returning title + link for each paper,\nand *only* ArXiv results.', inputSchema={'properties': {'query': {'title': 'Query', 'type': 'string'}, 'max_results': {'default': 5, 'title': 'Max Results', 'type': 'integer'}}, 'required': ['query'], 'type': 'object'}, outputSchema={'properties': {'result': {'items': {'additionalProperties': True, 'type': 'object'}, 'title': 'Result', 'type': 'array'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=ToolAnnotations(title='Search Arxiv', readOnlyHint=None, destructiveHint=None, idempotentHint=None, openWorldHint=None), meta=None), Tool(name='summarize_paper', title='Summarize Paper', description='Returns a one-paragraph summary of the paper at the given URL.', inputSchema={'properties': {'paper_url': {'title': 'Paper Url', 'type': 'string'}}, 'required': ['paper_url'], 'type': 'object'}, outputSchema={'properties': {'result': {'title': 'Result', 'type': 'string'}}, 'required': ['result'], 'title': '_WrappedResult', 'type': 'object', 'x-fastmcp-wrap-result': True}, annotations=ToolAnnotations(title='Summarize Paper', readOnlyHint=None, destructiveHint=None, idempotentHint=None, openWorldHint=None), meta=None)]📚 Available resources:[ Resource(name='arxiv_topics', title=None, uri=AnyUrl('resource://ai/arxiv_topics'), description=None, mimeType='text/plain', size=None, annotations=None, meta=None)]💬 Available prompts:[ Prompt(name='explore_topic_prompt', title=None, description=None, arguments=[PromptArgument(name='topic', description=None, required=True)], meta=None)]📖 Fetching resource: resource://ai/arxiv_topicsToday's AI topics: 1. Transformer interpretability 2. Efficient large-scale model training 3. Federated learning privacy 4. Neural network pruning🔍 Testing tool: search_arxiv 1. Transformer Interpretability Beyond Attention Visualization https://arxiv.org/abs/2012.09838 2. A Practical Review of Mechanistic Interpretability for ... https://arxiv.org/abs/2407.02646 3. Mechanistic Interpretability of Fine-Tuned Vision ... https://arxiv.org/abs/2503.18762📝 Testing tool: summarize_paperSummary of first paper: The paper proposes a novel method for interpreting Transformer networks beyond attention visualization, introducing a new way to compute relevancy. It aims to enhance interpretability in vision tasks. The method is shown to provide more accurate insights into model decisions.🚀 Testing prompt: explore_topic_promptGenerated prompt:USER: type='text' text="I want to explore recent work on 'Transformer interpretability'.\n1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n3. Combine all summaries into an overview report." annotations=None meta=None
Tích hợp máy chủ MCP trong Cursor AI
Giữ máy chủ MCP đang chạy, vì chúng ta sắp tích hợp nó vào trình soạn thảo mã Cursor AI.
- Vào “Settings”.
- Nhấn tab “Tools & Integrations”.
- Nhấn nút “New MCP Server”.
- Thêm cấu hình sau:
{ "mcpServers": { "ArxivExplorer": { "url": "http://127.0.0.1:8000/mcp/" } }}
Sau khi bạn lưu tệp mcp.json với cấu hình trên, bạn sẽ thấy máy chủ MCP mới trong phần “Tools & Integrations”, hiển thị hai công cụ như dưới đây.

Kiểm thử máy chủ MCP trong Cursor AI
Giờ là phần thú vị. Hãy xem máy chủ MCP của chúng ta hoạt động thế nào với trình soạn thảo mã Cursor AI. Chúng ta sẽ học cách dùng prompt để gọi công cụ, truy cập tài nguyên và thực thi prompt tùy chỉnh, tất cả trong trình soạn thảo.
1. Kiểm thử resources
Bắt đầu bằng cách kiểm tra xem máy chủ MCP của bạn có thể cung cấp dữ liệu hữu ích qua các resources của nó không.
Prompt: “what are the some popular arxiv topics”

Nếu mọi thứ được thiết lập đúng, mô hình AI sẽ hiểu yêu cầu của bạn và tự động truy xuất danh sách chủ đề từ endpoint resource của máy chủ MCP.
2. Kiểm thử từng công cụ
Tiếp theo, hãy thử các công cụ bạn đã mở qua MCP. Chúng ta sẽ kiểm thử công cụ search_arxiv trước bằng cách yêu cầu mô hình AI liệt kê mười bài nghiên cứu hàng đầu về mô hình ngôn ngữ lớn.
Prompt: “Please search for the top 10 research papers on large language models.”

AI sẽ gọi công cụ search_arxiv, và bạn sẽ thấy một danh sách nhanh, chính xác các bài báo liên quan, được lấy trực tiếp từ arXiv.
Tiếp theo, chúng ta sẽ kiểm thử công cụ tóm tắt, công cụ này nhận URL bài báo nghiên cứu và trả về bản tóm tắt báo cáo.
Prompt: “Please summarize the following paper for me: https://arxiv.org/abs/2402.06196”

Công cụ tóm tắt sẽ lấy bài báo và trả về bản tóm tắt ngắn gọn.
3. Kiểm thử prompt
Bây giờ, chúng ta sẽ gọi một prompt tùy chỉnh từ MCP để giúp tạo báo cáo.
Prompt: “Create a report on Quantum computing using the latest work.”

Nếu bạn xem mã máy chủ, bạn sẽ thấy mô hình AI hiểu nhiệm vụ và sử dụng hàm explore_topic_prompt.
@mcp.promptdef explore_topic_prompt(topic: str) -> str: return ( f"I want to explore recent work on '{topic}'.\n" f"1. Call the 'Search Arxiv' tool to find the 5 most recent papers.\n" f"2. For each paper URL, call 'Summarize Paper' to extract its key contributions.\n" f"3. Combine all summaries into an overview report." )
Đầu tiên, nó sẽ gọi công cụ 'Search Arxiv' để tìm liên kết đến các bài báo.

Sau đó, nó sẽ lần lượt đưa các liên kết vào công cụ 'Summarize Paper' để tạo các bản tóm tắt. Cuối cùng, tôi sẽ tạo báo cáo.

Kết luận
FastMCP 2.0 mang lại nhiều hơn một cách đơn giản để tạo máy chủ MCP. Nó cung cấp một framework vững chắc để xây dựng các tích hợp AI an toàn, mô-đun và có khả năng mở rộng. Với các tính năng như xác thực, proxy nâng cao (cho phép một máy chủ FastMCP đóng vai trò frontend cho máy chủ khác), và khả năng kết hợp nhiều máy chủ FastMCP vào một ứng dụng duy nhất bằng cách gắn (mount) và nhập (import), bạn có thể thiết kế các hệ thống phức tạp, dễ bảo trì một cách dễ dàng.
Hỗ trợ middleware cho phép bạn thêm các chức năng xuyên suốt, như ghi log hoặc sửa đổi yêu cầu, cho tất cả yêu cầu và phản hồi MCP. Bạn cũng có thể gửi thông điệp log và cập nhật tiến độ trở lại cho client thông qua ngữ cảnh MCP, giúp dễ dàng theo dõi và quản lý các tác vụ chạy lâu.
Trong hướng dẫn này, chúng ta đã học cách xây dựng một máy chủ MCP hoạt động đầy đủ và kiểm thử các tính năng của nó. Những công cụ này và giao thức MCP đang trở thành thành phần thiết yếu của các ứng dụng AI hiện đại, cho phép LLM thực hiện các tác vụ nâng cao và tự động hóa quy trình hiệu quả hơn.
Để tiếp tục học về máy chủ MCP, hãy xem thêm các tài nguyên khác của chúng tôi:
- Model Context Protocol (MCP): Hướng dẫn kèm dự án demo
- Top 10 máy chủ & khách MCP cho tự động hóa quy trình AI năm 2025
- Hướng dẫn Gradio MCP Server: Xây dựng, kiểm thử, triển khai & tích hợp
- Tạo một AI Agent với LangGraph và Model Context Protocol
- Chrome DevTools MCP: Tự động hóa và gỡ lỗi trình duyệt nhờ AI
Là một nhà khoa học dữ liệu được chứng nhận, tôi đam mê tận dụng công nghệ tiên tiến để tạo ra các ứng dụng học máy đổi mới. Với nền tảng vững chắc về nhận dạng giọng nói, phân tích và báo cáo dữ liệu, MLOps, AI hội thoại và NLP, tôi đã rèn giũa kỹ năng phát triển các hệ thống thông minh có thể tạo ra tác động thực sự. Bên cạnh chuyên môn kỹ thuật, tôi cũng là một người truyền đạt tốt, có khả năng chắt lọc các khái niệm phức tạp thành ngôn ngữ rõ ràng, súc tích. Nhờ đó, tôi trở thành một blogger được nhiều người quan tâm trong lĩnh vực khoa học dữ liệu, chia sẻ góc nhìn và kinh nghiệm với cộng đồng các chuyên gia dữ liệu ngày càng lớn. Hiện tại, tôi tập trung vào sáng tạo và biên tập nội dung, làm việc với các mô hình ngôn ngữ lớn để phát triển nội dung mạnh mẽ và hấp dẫn, giúp doanh nghiệp và cá nhân tận dụng tối đa dữ liệu của mình.
