Xây dựng MCP server đầu tiên

Lý thuyết đã xong. Giờ là lúc bắt tay vào xây dựng.

Trong bài học này, bạn sẽ tạo một MCP server hoạt động, kết nối nó với Claude Desktop và gọi công cụ tùy chỉnh đầu tiên của bạn. Toàn bộ quá trình chỉ cần dưới 50 dòng code.

🔄 Tóm tắt nhanh: Trong bài học trước, bạn đã học về kiến ​​trúc 3 lớp của MCP: Host (ứng dụng AI), Client (trình xử lý giao thức), Server (code của bạn). Bây giờ bạn sẽ xây dựng lớp Server và kết nối nó với Host.

Chọn ngôn ngữ của bạn

MCP có bộ SDK chính thức cho cả Python và TypeScript. Hãy chọn ngôn ngữ nào bạn cảm thấy thoải mái hơn — các khái niệm là giống nhau.

Python (FastMCP) TypeScript
Cài đặt pip install mcp npm install @modelcontextprotocol/sdk
Tốt nhất cho Tạo mẫu nhanh, khoa học dữ liệu Ứng dụng Node.js, tích hợp web
Lớp Server FastMCP McpServer

Chúng ta sẽ xem các ví dụ bằng Python trong khóa học này (chúng ngắn hơn), nhưng SDK TypeScript cũng tuân theo những mẫu tương tự.

Bước 1: Thiết lập dự án

Tạo một thư mục mới và cài đặt SDK:

mkdir my-first-mcp
cd my-first-mcp
pip install mcp

📍 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.

Tạo một file có tên server.py:

✏️ 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ề một 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 sử dụng kết quả: Lưu phản hồi vào file Notes. Chọn gợi ý có hiệu quả cao nhất và thực hiện nó 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 gợi ý 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."

python
from mcp.server.fastmcp import FastMCP

# Create the server
mcp = FastMCP("My First Server")

# Define a tool
@mcp.tool()
def add_numbers(a: float, b: float) -> str:
    """Add two numbers together."""
    return str(a + b)

# Run the server
if __name__ == "__main__":
    mcp.run(transport="stdio")

Vậy là xong. 12 dòng. Bạn đã có một MCP server hoạt động với một công cụ.

Hãy cùng phân tích những gì đang diễn ra:

  1. FastMCP("My First Server") — Tạo một biến thể server với tên hiển thị
  2. @mcp.tool() — Đăng ký hàm như một công cụ có thể gọi được
  3. Gợi ý kiểu ( a: float, b: float ) — MCP sử dụng những gợi ý này để tự động tạo schema đầu vào của công cụ
  4. Chuỗi tài liệu ("""Add two numbers together.""") — Trở thành mô tả của công cụ mà AI nhìn thấy
  5. mcp.run(transport="stdio") — Khởi động server bằng cách sử dụng giao thức stdio

Kiểm tra nhanh: Tại sao gợi ý kiểu Python lại quan trọng trong định nghĩa công cụ MCP?

Câu trả lời: SDK sử dụng gợi ý kiểu để tự động tạo JSON Schema cho các tham số của công cụ. Schema này cho AI client biết công cụ chấp nhận những đầu vào nào, kiểu của chúng và đầu vào nào là bắt buộc — mà không cần bạn phải tự viết định nghĩa schema.

Bước 2: Kết nối với Claude Desktop

Để sử dụng server của bạn, hãy cho Claude Desktop biết vị trí của nó. Chỉnh sửa file cấu hình:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

Windows: %APPDATA%\Claude\claude_desktop_config.json

Thêm server của bạn:

{
  "mcpServers": {
    "my-first-server": {
      "command": "python",
      "args": ["/full/path/to/my-first-mcp/server.py"]
    }
  }
}

Lưu ý quan trọng: Sử dụng đường dẫn tuyệt đối đầy đủ đến file server của bạn. Đường dẫn tương đối sẽ không hoạt động vì Claude Desktop khởi chạy tiến trình từ thư mục riêng của nó.

Khởi động lại Claude Desktop. Bạn sẽ thấy biểu tượng búa (🔨) trong khu vực nhập liệu — điều đó có nghĩa là các công cụ MCP đã có sẵn.

Bước 3: Kiểm tra

Nhập vào Claude Desktop:

"What's 42.5 plus 17.3?"

Claude sẽ nhận ra cần phải tính toán, nhìn thấy công cụ add_numbers của bạn và gọi nó. Bạn sẽ thấy kết quả tương tự như sau:

Used tool: add_numbers
Result: 59.8
42.5 plus 17.3 equals 59.8

Bạn vừa cung cấp cho Claude một khả năng mới mà trước đây nó chưa có. Ví dụ về add_numbers rất đơn giản — nhưng mô hình này hoạt động với mọi thứ: Truy vấn cơ sở dữ liệu, gọi API, thao tác file, tính toán.

Xây dựng một server hữu ích hơn

Hãy mở rộng server với một công cụ thực tế — công cụ đếm từ:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Text Tools")

@mcp.tool()
def count_words(text: str) -> str:
    """Count the number of words in a text."""
    word_count = len(text.split())
    char_count = len(text)
    return f"Words: {word_count}, Characters: {char_count}"

@mcp.tool()
def reverse_text(text: str) -> str:
    """Reverse the given text."""
    return text[::-1]

@mcp.tool()
def extract_emails(text: str) -> str:
    """Extract all email addresses from text."""
    import re
    emails = re.findall(r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}', text)
    if emails:
        return "Found emails:\n" + "\n".join(emails)
    return "No email addresses found."

if __name__ == "__main__":
    mcp.run(transport="stdio")

Bây giờ server của bạn có ba công cụ. Sau khi khởi động lại Claude Desktop, Claude có thể đếm từ, đảo ngược văn bản và trích xuất email — tất cả bằng cách gọi server cục bộ của bạn.

Kiểm tra nhanh: Bạn thêm một công cụ mới vào MCP server của mình. Bạn cần làm gì để Claude Desktop nhận diện công cụ mới?

Đáp án: Khởi động lại Claude Desktop. Client sẽ phát hiện các công cụ có sẵn trong quá trình bắt tay khởi tạo, vì vậy các công cụ mới sẽ không hiển thị cho đến khi kết nối được thiết lập lại.

Cách AI quyết định sử dụng các công cụ của bạn

Bạn có thể tự hỏi: Làm thế nào Claude biết khi nào cần gọi các công cụ của bạn?

Trong quá trình khởi tạo, server của bạn gửi một danh sách các công cụ có sẵn với tên, mô tả và schema tham số của chúng. Khi người dùng gửi một tin nhắn, quá trình suy luận của Claude sẽ xem xét:

  1. Yêu cầu này có khớp với mô tả của công cụ không? — "Trích xuất email từ văn bản này" khớp với công cụ extract_emails
  2. Các tham số cần thiết có sẵn không? — Người dùng đã cung cấp văn bản, đây là đầu vào cần thiết
  3. Việc gọi công cụ có tốt hơn là trả lời trực tiếp không? — Đối với việc trích xuất email, một công cụ regex đáng tin cậy hơn so với việc mô hình đoán

Đây là lý do tại sao mô tả tốt và tên tham số rõ ràng lại quan trọng. Một công cụ có tên fn1 mà không có mô tả sẽ không được sử dụng. Một công cụ có tên extract_emails với mô tả "Trích xuất tất cả địa chỉ email từ văn bản" sẽ được gọi một cách đáng tin cậy.

Mẹo gỡ lỗi

Khi mọi thứ không hoạt động:

Server không xuất hiện trong Claude Desktop:

  • Kiểm tra xem file cấu hình JSON có hợp lệ không (chỉ cần thiếu một dấu phẩy cũng làm hỏng mọi thứ)
  • Xác minh đường dẫn file là tuyệt đối, không phải tương đối
  • Khởi động lại hoàn toàn Claude Desktop (không chỉ đóng/mở lại cửa sổ)

Server xuất hiện nhưng các công cụ bị lỗi:

  • Kiểm tra nhật ký server trong stderr (đối với giao thức truyền tải stdio, console.error() hoặc print() đến stderr)
  • Kiểm tra server độc lập bằng cách chạy nó và kiểm tra lỗi nhập
  • Xác minh môi trường Python khớp với môi trường trong file cấu hình của bạn (môi trường ảo có thể gây ra sự không khớp)

Claude không gọi công cụ:

  • Cải thiện mô tả của công cụ — hãy cụ thể về những gì nó làm
  • Kiểm tra xem tên tham số có mô tả rõ ràng không (không phải x, y, mà là text, city, query)

Bài tập thực hành

  1. Tạo một MCP server mới với ít nhất 2 công cụ bạn chọn (ý tưởng: công cụ chuyển đổi nhiệt độ, công cụ rút gọn URL, công cụ định dạng văn bản)
  2. Kết nối nó với Claude Desktop bằng file cấu hình
  3. Kiểm tra từng công cụ bằng cách đặt câu hỏi cho Claude để kích hoạt chúng
  4. Hãy thử đặt một câu hỏi nào đó không rõ ràng — liệu Claude có chọn đúng công cụ không?

Những điểm chính cần ghi nhớ

  • FastMCP (Python) xây dựng một server hoạt động chỉ với chưa đến 15 dòng code
  • Decorator @mcp.tool() đăng ký các hàm như những công cụ có thể gọi
  • Gợi ý kiểu dữ liệu tự động tạo schema tham số — luôn luôn bao gồm chúng
  • Kết nối với Claude Desktop thông qua claude_desktop_config.json với lệnh và đường dẫn của server
  • Mô tả công cụ và tên tham số tốt sẽ quyết định liệu AI có sử dụng công cụ của bạn một cách chính xác hay không
  • Câu 1:

    Điều gì xảy ra nếu MCP server của bạn bị lỗi và gặp sự cố?

    GIẢI THÍCH:

    Các kết nối MCP có khả năng phục hồi. Nếu server gặp sự cố, client sẽ mất kết nối cụ thể đó nhưng Host (Claude Desktop) vẫn tiếp tục chạy. Mô hình AI nhận ra công cụ không khả dụng và có thể thông báo cho người dùng. Bạn sửa server và kết nối lại. Claude nói với bạn rằng không thể lấy được công cụ đó, nhưng cuộc trò chuyện vẫn tiếp tục.

  • Câu 2:

    Bạn cấu hình Claude Desktop để kết nối với MCP server của mình ở đâu?

    GIẢI THÍCH:

    Claude Desktop đọc cấu hình MCP server từ file claude_desktop_config.json. Mỗi mục server bao gồm một lệnh (như 'python' hoặc 'node'), các đối số (đường dẫn đến server script của bạn) và tùy chọn env cho những biến môi trường.

  • Câu 3:

    Decorator @mcp.tool() trong FastMCP của Python làm gì?

    GIẢI THÍCH:

    Decorator @mcp.tool() đăng ký một hàm Python như một công cụ MCP. Trong quá trình khởi tạo, server quảng cáo công cụ này cho client. Khi AI quyết định sử dụng nó, MCP client gửi yêu cầu công cụ/cuộc gọi, và server thực thi hàm.

Thứ Ba, 02/06/2026 08:49
51 👨 75
Xác thực tài khoản!

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:

Số điện thoại chưa đúng định dạng!
Số điện thoại này đã được xác thực!
Bạn có thể dùng Sđt này đăng nhập tại đây!
Lỗi gửi SMS, liên hệ Admin
0 Bình luận
Sắp xếp theo
❖ MCP Tools