Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 3 — Transport: stdio, HTTP/SSE và cách chọn đúng

Đã đọc 0/8 mục · còn khoảng 4 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

JSON-RPC message ở bài trước cần một kênh vận chuyển (transport) để đi từ client sang server. MCP hỗ trợ chủ yếu hai loại, và chọn sai sẽ khiến agent chạy được ở máy dev nhưng chết khi deploy.

1. stdio (Standard Input/Output)

Client khởi chạy server như một tiến trình con (subprocess) và trao đổi message qua stdin/stdout. Mỗi message là một dòng JSON.

  • Ưu điểm: cực đơn giản, không cần mạng, không cổng, độ trễ thấp. Bảo mật tốt vì chạy cục bộ.
  • Nhược điểm: server phải nằm cùng máy với host. Không dùng được cho server đặt ở xa hay chia sẻ cho nhiều người.
Cấu hình điển hình trong host (ví dụ file config của Claude Desktop):

{
  "mcpServers": {
    "orders": {
      "command": "node",
      "args": ["/opt/mcp/orders-server.js"],
      "env": { "DB_URL": "postgres://localhost/shop" }
    }
  }
}

Host sẽ tự chạy node /opt/mcp/orders-server.js và nói chuyện qua stdio.

> Lưu ý sống còn với stdio: KHÔNG bao giờ print/console.log ra stdout để debug. stdout là kênh truyền JSON-RPC; log rác sẽ phá hỏng message. Hãy log ra stderr.

2. HTTP + SSE / Streamable HTTP

Server chạy như một dịch vụ web độc lập. Client kết nối qua HTTP. Phản hồi streaming dùng SSE (Server-Sent Events) hoặc cơ chế Streamable HTTP mới hơn.

  • Ưu điểm: server đặt ở xa, chia sẻ cho nhiều client/nhiều người, scale được, đặt sau load balancer/gateway.
  • Nhược điểm: phức tạp hơn — cần xác thực, HTTPS, quản lý session, CORS.
POST https://mcp.congty.com/orders
Authorization: Bearer <token>
Content-Type: application/json

{ "jsonrpc":"2.0", "id":1, "method":"tools/list" }

Khung quyết định: chọn transport nào?

Tình huốngChọn
Server chạy cùng máy, dùng cá nhân, truy cập file/DB cục bộstdio
Server dùng chung cho team, đặt trên server riêngHTTP/SSE
Cần scale, đứng sau API gateway, có auth tập trungHTTP/SSE
Prototype nhanh trên laptopstdio

Các bước triển khai transport

  • Xác định vị trí server: cùng máy hay từ xa?
  • Chọn transport theo bảng trên.
  • Với stdio: cấu hình command/args/env trong host, đảm bảo log đi stderr.
  • Với HTTP: dựng endpoint, bật HTTPS, gắn xác thực (Bearer/OAuth), cấu hình URL trong client.
  • Kiểm thử handshake trước, rồi mới tới tools/list.
  • Ghi lại retry/timeout cho môi trường mạng không ổn định (chỉ HTTP).

Ví dụ tình huống

Bạn viết một MCP server đọc file dự án cho IDE cá nhân → stdio là hoàn hảo. Sáu tháng sau, cả team muốn dùng agent truy vấn CRM đặt trên cloud → bạn dựng phiên bản HTTP/SSE có OAuth. Logic tool (tools/list, tools/call) giữ nguyên; chỉ lớp transport thay đổi. Đây là sức mạnh tách lớp của MCP.

Tách logic khỏi transport ngay từ đầu

Bài học thực chiến quan trọng nhất về transport: đừng nhét logic nghiệp vụ vào lớp transport. Hãy viết các hàm tool/resource thuần túy (nhận tham số, trả kết quả), rồi để SDK gắn chúng vào transport nào tùy chọn. Với FastMCP hay các SDK tương đương, bạn thường chỉ đổi một dòng transport="stdio" sang transport="streamable-http" là chuyển được. Nếu logic tool của bạn gọi trực tiếp sys.stdin hay đụng vào chi tiết HTTP, bạn đã trói mình vào một transport và sẽ phải viết lại khi đổi.

Một lưu ý vận hành với HTTP: hãy quản lý session. Streamable HTTP cho phép nhiều client cùng nói chuyện với một server; mỗi client cần một session id riêng để server không lẫn ngữ cảnh giữa người dùng. Ngoài ra, đặt server sau một reverse proxy (nginx, API gateway) để lo HTTPS, rate limit và auth tập trung — thay vì tự viết mọi thứ trong server. Với stdio thì đơn giản hơn nhiều: một tiến trình, một client, không session.

Sai lầm thường gặp

  • Log ra stdout khi dùng stdio → message JSON-RPC hỏng, client báo lỗi parse khó hiểu. Luôn log stderr.
  • Dùng stdio cho server cần chia sẻ từ xa → không ai ngoài máy đó gọi được.
  • Bật HTTP transport nhưng quên xác thực → phơi bày tools (gồm cả hành động ghi/xóa) ra Internet. Cực nguy hiểm.
  • Quên xử lý reconnect với SSE khi kết nối rớt, khiến agent "treo" giữa chừng.
  • Đường dẫn tương đối trong args: host có thể chạy ở thư mục khác. Luôn dùng đường dẫn tuyệt đối.
Đã hiểu cách message đi qua dây, bài 4 ta bắt tay xây MCP server đầu tiên phơi bày một tool thật.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi