MCP và API: Khi nào dùng MCP hoặc HTTP trực tiếp

Jakub Swistak
Ngày đăng Cập nhật Thời gian đọc: 8 phút
Sơ đồ so sánh kiến trúc cho thấy các mẫu tích hợp MCP và HTTP

Khi kết nối một AI agent với công cụ và API bên ngoài, có hai cách tiếp cận chính: dùng Model Context Protocol (MCP) làm lớp trừu tượng, hoặc gọi API trực tiếp qua HTTP. Cả hai đều hoạt động. Chúng có các đánh đổi khác nhau về tính linh hoạt, độ phức tạp, hiệu năng và tính di động.

Bài viết này so sánh hai cách tiếp cận bằng ví dụ mã cụ thể, phân tích độ trễ và một khung ra quyết định để chọn giữa chúng.

Hai cách tiếp cận

Tích hợp HTTP trực tiếp

Ứng dụng AI (hoặc backend của ứng dụng) gọi trực tiếp các API bên ngoài bằng các yêu cầu HTTP tiêu chuẩn. Nhà phát triển viết mã để tạo yêu cầu, xử lý xác thực, phân tích phản hồi và đưa kết quả trở lại LLM.

┌────────────┐     ┌─────────────┐                        ┌─────────────┐
│ Người dùng │────▶│ Ứng dụng AI │──── Yêu cầu HTTP ─────▶│ Weather API │
└────────────┘     │             │◀─── Phản hồi JSON ─────│             │
                   │             │                        └─────────────┘
                   │             │── Kết quả làm context ─▶ LLM
                   │             │◀── Câu trả lời định dạng
                   └──────┬──────┘
                          │
                          ▼
              Người dùng nhận câu trả lời

Tích hợp MCP

Ứng dụng AI kết nối tới một MCP server bọc API bên ngoài. Ứng dụng dùng giao thức MCP để khám phá các công cụ có sẵn, gọi chúng theo tên và nhận kết quả. MCP server xử lý các lệnh gọi HTTP thực tế tới API bên ngoài.

┌────────────┐     ┌──────────────────────┐              ┌────────────┐     ┌──────────┐
│ Người dùng │────▶│ Ứng dụng AI/MCP Client │── JSON-RPC ─▶│ MCP Server │────▶│ HTTP API │
└────────────┘     │                      │◀─ JSON-RPC ──│            │◀────│          │
                   │                      │              └────────────┘     └──────────┘
                   │                      │── Kết quả làm context ─▶ LLM
                   │                      │◀── Câu trả lời định dạng
                   └───────────┬──────────┘
                               │
                               ▼
                   Người dùng nhận câu trả lời

Điểm khác biệt chính: với HTTP trực tiếp, ứng dụng AI sở hữu mã tích hợp API. Với MCP, MCP server sở hữu phần đó, còn ứng dụng AI chỉ gọi công cụ theo tên.

Bạn có thể có phần MCP trong sơ đồ này mà không cần tự xây dựng server: Quickchat AI lưu trữ một MCP server streamable-HTTP cho mỗi AI Agent, và việc biến agent của bạn thành MCP server chỉ còn là dán một URL vào ứng dụng AI.

So sánh mã

Hãy so sánh cả hai cách tiếp cận bằng một ví dụ thực tế: lấy danh sách repository của một người dùng GitHub.

Tích hợp HTTP trực tiếp

import httpx

async def get_user_repos(username: str, token: str) -> list[dict]:
    """Lấy repository của một người dùng GitHub."""
    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"https://api.github.com/users/{username}/repos",
            headers={
                "Authorization": f"Bearer {token}",
                "Accept": "application/vnd.github.v3+json",
                "X-GitHub-Api-Version": "2022-11-28"
            },
            params={"sort": "updated", "per_page": 10}
        )
        response.raise_for_status()
        repos = response.json()
        return [
            {
                "name": r["name"],
                "description": r["description"],
                "stars": r["stargazers_count"],
                "language": r["language"],
                "url": r["html_url"]
            }
            for r in repos
        ]

Để tích hợp phần này với LLM, bạn cũng cần:

  • Một định nghĩa công cụ theo bất kỳ định dạng nào LLM yêu cầu (OpenAI function calling schema, Claude tool use schema, v.v.)
  • Mã để phân tích lệnh gọi công cụ của LLM, gọi get_user_repos và chèn kết quả trở lại cuộc hội thoại
  • Xử lý lỗi cho lỗi HTTP, giới hạn tốc độ và hết hạn xác thực

MCP server

from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("github-server")

GITHUB_TOKEN = os.environ["GITHUB_TOKEN"]

@mcp.tool()
async def get_user_repos(username: str) -> str:
    """Lấy 10 repository được cập nhật gần đây nhất của một người dùng GitHub.

    Args:
        username: Tên người dùng GitHub cần tra cứu
    """
    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"https://api.github.com/users/{username}/repos",
            headers={
                "Authorization": f"Bearer {GITHUB_TOKEN}",
                "Accept": "application/vnd.github.v3+json",
                "X-GitHub-Api-Version": "2022-11-28"
            },
            params={"sort": "updated", "per_page": 10}
        )
        response.raise_for_status()
        repos = response.json()
        lines = []
        for r in repos:
            stars = r["stargazers_count"]
            lang = r["language"] or "không xác định"
            lines.append(f"- {r['name']} ({lang}, {stars} sao): {r['description'] or 'Không có mô tả'}")
        return "\n".join(lines)

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

Phiên bản MCP đóng gói lệnh gọi API, xác thực và định dạng phản hồi bên trong server. Bất kỳ client nào tương thích với MCP đều có thể dùng công cụ này mà không cần biết gì về GitHub API.

Điều gì thay đổi với ứng dụng AI

Mối quan tâmHTTP trực tiếpMCP
Định nghĩa công cụViết theo định dạng gốc của LLM (OpenAI schema, v.v.)Tự động tạo từ MCP server
Xác thựcDo ứng dụng AI quản lýDo MCP server quản lý
Phân tích phản hồiỨng dụng AI trích xuất và định dạng dữ liệuMCP server trả về kết quả đã định dạng
Xử lý lỗiỨng dụng AI xử lý lỗi HTTPMCP server xử lý lỗi, trả về thông báo lỗi có cấu trúc
Thêm công cụ mớiViết mã mới trong ứng dụng AIKết nối tới MCP server mới (hoặc thêm công cụ vào server hiện có)
Đổi LLMViết lại định nghĩa công cụ cho định dạng LLM mớiKhông cần thay đổi

So sánh hiệu năng

MCP thêm một lớp giữa ứng dụng AI và API bên ngoài. Lớp đó có chi phí.

Độ trễ

Với stdio transport (MCP server cục bộ), phần overhead là tối thiểu: khởi tạo tiến trình lúc bắt đầu (một lần, thường dưới 100ms) và giao tiếp liên tiến trình cho mỗi thông điệp (dưới một mili giây trên các hệ thống hiện đại). Trong thực tế, lệnh gọi API bên ngoài chi phối tổng độ trễ.

Với remote MCP servers (Streamable HTTP hoặc SSE), bạn thêm một vòng HTTP giữa client và MCP server, cộng với vòng HTTP của MCP server tới API bên ngoài. Nếu MCP server và API bên ngoài được đặt cùng vị trí, phần overhead này nhỏ (vài mili giây). Nếu chúng ở các khu vực khác nhau, độ trễ cộng dồn. Tuy vậy, transport hiếm khi là phần người dùng cảm nhận được: khi xây dựng một help-center agent trên MCP server được Notion lưu trữ, 248 lệnh gọi công cụ có trung bình 2,7 giây mỗi lệnh, gần như toàn bộ là thời gian Notion tìm kiếm và render trang thay vì bước nhảy trung gian.

Thiết lậpĐộ trễ thêm xấp xỉ
MCP server cục bộ (stdio)< 1ms mỗi lệnh gọi công cụ
MCP server từ xa (cùng khu vực với API)1-5ms mỗi lệnh gọi công cụ
MCP server từ xa (khác khu vực với API)10-50ms mỗi lệnh gọi công cụ

Với hầu hết trường hợp sử dụng AI agent, trong đó suy luận LLM mất 500ms-5s, overhead của MCP là không đáng kể.

Quản lý kết nối

HTTP trực tiếp: Ứng dụng của bạn quản lý kết nối tới từng API bên ngoài. Điều này nghĩa là xử lý connection pool, logic retry và giới hạn tốc độ cho từng API.

MCP: Ứng dụng của bạn quản lý một kết nối cho mỗi MCP server. Server quản lý kết nối API bên ngoài. Nếu bạn có 10 công cụ phân bổ trên 3 MCP server, bạn quản lý 3 kết nối thay vì 10.

Khi nào dùng MCP

Nhiều tích hợp công cụ

Nếu ứng dụng AI của bạn cần kết nối tới hơn 5 dịch vụ bên ngoài, MCP giảm gánh nặng tích hợp. Thay vì viết và bảo trì client API tùy chỉnh cho từng dịch vụ, bạn kết nối tới MCP server (nhiều server trong số đó có sẵn dưới dạng dự án mã nguồn mở).

Tính di động giữa các nền tảng AI

Nếu bạn xây dựng MCP server cho công cụ của mình, các server đó hoạt động với bất kỳ MCP client nào: Claude Desktop, Cursor, Windsurf, ứng dụng tùy chỉnh và các nền tảng như Quickchat AI. Với HTTP trực tiếp, bạn sẽ cần triển khai lại định nghĩa công cụ cho định dạng của từng nền tảng.

Khám phá công cụ động

MCP hỗ trợ khám phá công cụ lúc chạy thông qua tools/list. Một ứng dụng AI có thể kết nối tới server và biết các công cụ nào có sẵn mà không cần cấu hình hardcode. Điều này hữu ích trong các kịch bản công cụ thay đổi thường xuyên hoặc có thể được người dùng cấu hình.

Tách biệt trách nhiệm

Nếu các nhóm khác nhau sở hữu các công cụ khác nhau, MCP cung cấp một ranh giới rõ ràng. Nhóm sở hữu tích hợp Salesforce xây dựng và bảo trì Salesforce MCP server. Nhóm ứng dụng AI kết nối tới server đó mà không cần hiểu API của Salesforce. Các bản cập nhật đối với Salesforce API được xử lý trong MCP server mà không chạm vào ứng dụng AI.

Khi nào dùng HTTP trực tiếp

Một hoặc hai tích hợp

Nếu AI agent của bạn chỉ cần gọi một API (ví dụ, tra cứu cơ sở dữ liệu), overhead của việc chạy một MCP server là không cần thiết. Một lệnh gọi HTTP trực tiếp đơn giản hơn và có ít thành phần chuyển động hơn.

Bạn cũng không phải viết yêu cầu thủ công. Trình tạo API Action bằng ngôn ngữ tự nhiên đọc một REST API có tài liệu, tạo method, URL, tham số và mô tả, sau đó cho phép bạn kiểm thử phản hồi thực tế trước khi bật.

Kiểm soát tối đa yêu cầu

MCP server trừu tượng hóa các chi tiết HTTP. Nếu bạn cần kiểm soát chính xác cách tạo yêu cầu (header cụ thể, tham số truy vấn, ký yêu cầu hoặc xác thực không chuẩn), HTTP trực tiếp cho bạn quyền kiểm soát đó mà không phải chống lại một lớp trừu tượng.

Hoạt động nhạy cảm với độ trễ

Nếu từng mili giây đều quan trọng (ví dụ, agent thoại thời gian thực trong đó lệnh gọi công cụ phải hoàn tất trong ngân sách thời gian nghiêm ngặt), loại bỏ lớp MCP sẽ loại bỏ một bước nhảy.

Lệnh gọi HTTP không thuộc AI

Nếu lệnh gọi HTTP không được kích hoạt bởi AI agent (ví dụ, một cron job backend đồng bộ dữ liệu), MCP không liên quan. MCP được thiết kế riêng cho giao tiếp từ AI tới công cụ. Các dịch vụ backend thông thường nên dùng HTTP client thông thường.

Cách tiếp cận kết hợp

Nhiều hệ thống production dùng cả hai. Mẫu thường gặp:

  • MCP cho các tích hợp công cụ mà AI agent gọi trong cuộc hội thoại (tra cứu CRM, tạo ticket, truy vấn knowledge base)
  • HTTP trực tiếp cho hoạt động backend nội bộ, webhook và giao tiếp hệ thống-với-hệ thống

Đây là cách Quickchat AI hoạt động nội bộ. Nền tảng hỗ trợ cả HTTP Request Actions (lệnh gọi API trực tiếp với tạo mẫu tham số) và Remote MCP Actions (kết nối tới MCP server bên ngoài). Bạn chọn cách tiếp cận phù hợp cho từng tích hợp:

Loại tích hợpCách tiếp cận được khuyến nghị
Lệnh gọi API đơn giản với tham số đã biếtHTTP Request Action
Tích hợp phức tạp với nhiều công cụ liên quanRemote MCP Action
Dịch vụ bên thứ ba có MCP server hiện cóRemote MCP Action
API nội bộ với xác thực tùy chỉnhHTTP Request Action
Công cụ có thể được người dùng cấu hìnhRemote MCP Action

Để xem so sánh chi tiết về cách điều này hoạt động trong thực tế, bao gồm khác biệt giữa GPT Actions của OpenAI và MCP, hãy xem GPT Actions so với MCP.

Khung ra quyết định

Dùng lưu đồ này để lựa chọn:

  1. AI agent có đang gọi công cụ không? Nếu không (đó là hoạt động backend), dùng HTTP trực tiếp.
  2. Bạn cần bao nhiêu công cụ bên ngoài? Nếu 1-2, HTTP trực tiếp đơn giản hơn. Nếu 3+, hãy cân nhắc MCP.
  3. Có MCP server dựng sẵn cho dịch vụ đó không? Nếu có, dùng nó sẽ tiết kiệm thời gian phát triển.
  4. Bạn có cần tích hợp hoạt động trên nhiều nền tảng AI không? Nếu có, MCP cung cấp tính di động.
  5. Độ trễ có quan trọng không (ngân sách dưới 100ms cho lệnh gọi công cụ)? Nếu có, hãy benchmark overhead của MCP và quyết định tương ứng.
  6. Các nhóm khác nhau có sở hữu các tích hợp khác nhau không? Nếu có, mô hình mỗi server cho một tích hợp của MCP giúp xác định ranh giới sở hữu.

Trong thực tế, nếu bạn đang xây dựng một AI agent cần tương tác với dịch vụ bên ngoài, MCP ngày càng trở thành lựa chọn mặc định. Hệ sinh thái server dựng sẵn đủ lớn để bạn thường có thể bắt đầu mà không cần viết bất kỳ mã server nào.

Đọc thêm