AI agent & MCP

Hộp thư email cho Claude Code, Cursor và Windsurf qua MCP

Mọi agent lập trình đều khựng lại ở đúng một câu: “hãy kiểm tra email để lấy mã”. Cách khắc phục là một máy chủ MCP, một URL, không cần key và không cần tài khoản — chỉ có điều cấu hình lại khác nhau ở mỗi client. Đây là cách làm cho Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Codex CLI và Gemini CLI, cùng bốn lệnh gọi công cụ đưa một lượt đăng ký đi trọn vẹn, và đoạn văn cần đưa vào chính instructions của agent.

  • Cơ bản
  • 14 phút đọc
Một laptop xám mở, một phong bì xanh cắm vào cạnh như chiếc USB, và một phích cắm xanh đặt trong ổ cắm xám phía trước

Một máy chủ, bảy client

Máy chủ này là một endpoint HTTPS duy nhất, nói chuyện bằng Model Context Protocol qua Streamable HTTP: một POST mang theo JSON-RPC, một phản hồi JSON, không có stream nào bị giữ mở. Không có gì cần cài đặt, không có gì cần chạy cục bộ, và không có gì cần đăng ký trên các tên miền công khai — URL chính là toàn bộ cấu hình:

Endpoint MCPhttps://grabmail.io/mcp

Mọi client MCP đều chấp nhận một máy chủ HTTP từ xa, nhưng mỗi client lại lưu cấu hình của mình trong một tệp khác nhau, với một tên khóa hơi khác nhau. Các mục bên dưới đưa ra chính xác dòng cấu hình cho từng client. Các định dạng này là những gì đang được dùng tính đến tháng 9 năm 2026; tài liệu chính thức của từng client mới là nguồn chuẩn nếu có gì đó đã thay đổi kể từ đó.

Kiểm tra xem nó có phản hồi không, từ một shell

Trước khi động vào bất kỳ client nào, hãy chứng minh máy chủ đang tồn tại và xem nó cung cấp gì. Vì transport chỉ là HTTP thuần túy, một lệnh curl là đủ:

liệt kê các công cụ
$ curl -s -X POST https://grabmail.io/mcp -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | jq '.result.tools[].name'
những gì trả về
"create_inbox"
"list_domains"
"list_messages"
"read_message"
"wait_for_message"
"delete_message"

Nếu điều đó hoạt động, mọi client bên dưới cũng sẽ hoạt động, và một client sau đó vẫn thất bại thì đó là vấn đề cấu hình ở phía client, chứ không phải vấn đề của máy chủ. Nếu nó không hoạt động, hãy kiểm tra xem mạng của bạn có cho phép HTTPS hướng ra ngoài đến grabmail.io hay không — đó là toàn bộ dấu chân mạng của nó.

Claude Code

Một lệnh duy nhất, từ bất kỳ thư mục nào. Nó đăng ký máy chủ này cho user của bạn, nên nó sẽ có mặt trong mọi project:

shell
$ claude mcp add --transport http grabmail https://grabmail.io/mcp

Để chia sẻ nó với cả team thông qua repository thay vì vậy, hãy giới hạn phạm vi của nó vào project. Việc đó sẽ ghi ra một tệp .mcp.json ở thư mục gốc, được commit vào repo, và các thành viên trong team sẽ được nhắc phê duyệt:

shell — phạm vi project
$ claude mcp add --transport http --scope project grabmail https://grabmail.io/mcp
.mcp.json — những gì phạm vi project ghi ra
{
  "mcpServers": {
    "grabmail": {
      "type": "http",
      "url": "https://grabmail.io/mcp"
    }
  }
}

Khởi động lại Claude Code, chạy /mcp, và grabmail sẽ xuất hiện trong danh sách cùng sáu công cụ của nó. Máy chủ này cũng trả lời lệnh gọi initialize của giao thức bằng một đoạn instructions ngắn, được Claude Code đưa cho mô hình — nên agent đã biết sẵn cách đưa ra alias và chờ trên address ngay từ đầu.

Claude Desktop

Các máy chủ từ xa được thêm vào thông qua chính ứng dụng, chứ không phải qua tệp cấu hình:

  1. Vào Settings → Connectors → Add custom connector.
  2. Dán https://grabmail.io/mcp vào ô URL rồi đặt cho nó một cái tên.
  3. Bắt đầu một cuộc trò chuyện mới, và các công cụ sẽ xuất hiện dưới connector đó.

Trên một phiên bản chỉ chấp nhận máy chủ cục bộ trong claude_desktop_config.json, hãy dùng mcp-remote làm cầu nối đến endpoint từ xa đó; nó chạy như một tiến trình cục bộ và chuyển tiếp đến URL:

claude_desktop_config.json — thông qua cầu nối mcp-remote
{
  "mcpServers": {
    "grabmail": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://grabmail.io/mcp"]
    }
  }
}

Cursor

Cursor đọc .cursor/mcp.json trong project (hoặc ~/.cursor/mcp.json để áp dụng cho mọi project). Một máy chủ từ xa được khai báo bằng url:

.cursor/mcp.json
{
  "mcpServers": {
    "grabmail": {
      "url": "https://grabmail.io/mcp"
    }
  }
}

Mở Cursor Settings → MCP để thấy nó xuất hiện trong danh sách và bật các công cụ của nó lên. Ở chế độ Agent, mô hình sẽ tự gọi chúng; trong khung chat, bạn có thể gọi tên chúng ra trực tiếp.

Windsurf

Windsurf lưu các máy chủ của nó trong ~/.codeium/windsurf/mcp_config.json, và khóa dùng cho một máy chủ từ xa là serverUrl chứ không phải url — đây là chỗ duy nhất mà hình dạng cấu hình khác đi:

~/.codeium/windsurf/mcp_config.json
{
  "mcpServers": {
    "grabmail": {
      "serverUrl": "https://grabmail.io/mcp"
    }
  }
}

Cascade sẽ liệt kê máy chủ này sau khi làm mới từ MCP panel. Cùng một tệp đó cũng có thể mở được từ Windsurf Settings → Cascade → MCP servers → View raw config.

VS Code

Chế độ agent của VS Code đọc .vscode/mcp.json trong workspace, hoặc tệp cấp user mà lệnh MCP: Add Server trong command palette ghi ra. Các máy chủ nằm dưới khóa servers, chứ không phải mcpServers, và một máy chủ từ xa cần khai báo transport của nó:

.vscode/mcp.json
{
  "servers": {
    "grabmail": {
      "type": "http",
      "url": "https://grabmail.io/mcp"
    }
  }
}

Một liên kết nhỏ ghi “Start” sẽ xuất hiện phía trên mục đó trong editor; sau đó các công cụ sẽ hiện ra trong bộ chọn công cụ của khung chat, và chế độ agent sẽ tự gọi chúng mà không cần hỏi.

Codex CLI và Gemini CLI

Codex CLI lưu cấu hình của nó bằng TOML tại ~/.codex/config.toml. Một máy chủ từ xa là một table có url:

~/.codex/config.toml
[mcp_servers.grabmail]
url = "https://grabmail.io/mcp"

Gemini CLI đọc ~/.gemini/settings.json (hoặc .gemini/settings.json trong project), và khóa dùng cho một máy chủ Streamable HTTP là httpUrl:

~/.gemini/settings.json
{
  "mcpServers": {
    "grabmail": {
      "httpUrl": "https://grabmail.io/mcp"
    }
  }
}

Một phiên bản của cả hai công cụ trên, nếu chỉ chấp nhận máy chủ cục bộ, vẫn có thể tiếp cận endpoint đó qua cùng cầu nối mcp-remote đã trình bày cho Claude Desktop: command = "npx", args = ["-y", "mcp-remote", "https://grabmail.io/mcp"].

Sáu công cụ

Dù là client nào, mô hình cũng thấy cùng sáu công cụ đó, với cùng tên gọi. Không có trạng thái nào cần quản lý giữa các lệnh gọi, và không công cụ nào cần một tham số mà lệnh gọi trước đó chưa trả về.

create_inbox
Tạo ra một địa chỉ mới và trả về nó cùng với alias của nó, kèm một next_step cho biết cái nào dùng ở đâu. Không có gì được giữ chỗ ở phía máy chủ, nên việc này không thể thất bại. Nhận một prefix dễ đọc, không bắt buộc.
wait_for_message
Block cho đến khi một thư đến tại địa chỉ đó, tối đa 25 giây, rồi trả về thư đầy đủ — tiêu đề, người gửi, văn bản thuần, HTML. Lọc bằng subject_contains hoặc from_contains; truyền since_id để bỏ qua những gì đã có sẵn từ trước. Sau một lượt chờ không có gì đến, nó trả về timed_out và yêu cầu được gọi lại.
read_message
Một thư đầy đủ, tra theo id. Hiếm khi cần đến, vì lượt chờ ở trên đã trả về cả thư rồi.
list_messages
Mọi thứ đang chờ tại một địa chỉ, mới nhất trước, ngay lập tức — kể cả khi chẳng có gì cả.
list_domains
Các tên miền công khai mà ai cũng có thể dùng, dành cho lúc một biểu mẫu vừa từ chối một trong số chúng.
delete_message
Xóa một thư ngay lập tức thay vì phải đợi 5 ngày. Có tính idempotent, nên một agent thử lại cũng không tốn kém gì.

Vòng lặp đăng ký trong bốn lệnh gọi

Đây là trình tự mà hầu như mọi tác vụ đều cần đến, và client nào cũng không làm thay đổi nó:

  1. create_inbox. Trả về một address, một alias, và một ghi chú cho biết cái nào là cái nào.
  2. Alias được điền vào biểu mẫu. Trang web nhận được một địa chỉ hoạt động được, đưa thư đến hộp thư, nhưng không thể dùng để mở hộp thư đó.
  3. wait_for_message trên address đó, ngay sau khi gửi biểu mẫu, với subject_contains đặt thành một từ mà thư xác nhận chắc chắn sẽ mang theo. Nó block; agent không phải tự lặp.
  4. Mã được lấy ra từ chính thư mà lượt chờ đã trả về. Thường thì không cần thêm bất kỳ lệnh gọi nào nữa.
một prompt chạy qua toàn bộ vòng lặp
Sign up for a trial at https://app.example.com/signup with a fresh GrabMail inbox.
Use the ALIAS in the form, wait for the confirmation code with wait_for_message
on the ADDRESS, enter it, and tell me the resulting login.

Nên đưa gì vào chính instructions của agent

Máy chủ đã cho mô hình biết cách dùng nó ngay tại thời điểm kết nối, nhưng một mô hình đã đọc cùng bốn quy tắc đó trong chính instructions của project sẽ tuân theo chúng mọi lần, thay vì chỉ phần lớn các lần. Hãy thêm đoạn sau vào CLAUDE.md, .cursor/rules, .windsurfrules, AGENTS.md hoặc GEMINI.md — tùy vào tệp nào client của bạn đọc:

CLAUDE.md, .cursor/rules, AGENTS.md — cùng một đoạn văn
## Email

- To receive email, use the `grabmail` MCP server. Call `create_inbox` once per task.
- Put the **alias** it returns into forms; poll the **address** it returns with `wait_for_message`.
- Call `wait_for_message` right after submitting a form, with `subject_contains` set to a word
  you expect ("code", "verify", "confirm"). If it returns `timed_out`, call it again — up to
  three times — before concluding the mail was not sent.
- Never reuse an inbox across tasks. Never send anything confidential to one: it is public.

Hai quy tắc quan trọng nhất chính là hai điều một agent sẽ làm sai nếu không được nói trước: điền alias vào biểu mẫu và chờ trên address, đồng thời coi timed_out là “gọi lại lần nữa”, chứ không phải “thư đã không bao giờ được gửi”. Bài một hộp thư mà AI agent có thể đọc được đi sâu vào cả hai điều này, bao gồm cả lý do vì sao lượt chờ lại trả về trước khi thư kịp đến.

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

Triệu chứngNguyên nhânCách khắc phục
Máy chủ không xuất hiện trong danh sáchTệp cấu hình đặt sai chỗ, dùng sai khóa (url / serverUrl / httpUrl / servers), hoặc client chưa được khởi động lại.Sao chép đúng khối cấu hình cho client của bạn, khởi động lại, rồi chạy lệnh curl ở trên để loại trừ khả năng lỗi ở máy chủ.
Các công cụ xuất hiện trong danh sách nhưng mô hình không bao giờ gọi chúngCác công cụ bị tắt trong MCP panel của client, hoặc mô hình chưa được cho biết có một bước liên quan đến email.Hãy bật chúng lên, và thêm đoạn instructions ở trên vào.
wait_for_message cứ liên tục trả về timed_outBiểu mẫu chưa từng được gửi, alias bị gõ sai, trang web đã từ chối tên miền đó, hoặc đã có 8 lượt chờ đang chạy sẵn.Gọi lại tối đa ba lần; kiểm tra lỗi do chính biểu mẫu báo ra; đọc bài vì sao biểu mẫu đăng ký chặn email dùng một lần.
Trang web báo địa chỉ không hợp lệTên miền công khai đó nằm trong một danh sách chặn email dùng một lần.Hãy dùng một tên miền riêng của bạn (chỉ cần một bản ghi MX) hoặc một tên miền từ nhóm được giữ ngoài các danh sách chặn.
Cầu nối (mcp-remote) không khởi động đượcMáy không có Node, hoặc npx không thể truy cập được registry.Hãy cài Node 18 trở lên, hoặc dùng một phiên bản client chấp nhận URL trực tiếp.

Trước khi bạn coi như đã xong

  • Lệnh curl ở trên liệt kê được sáu công cụ, từ máy của bạn.
  • Máy chủ xuất hiện trong MCP panel của client sau khi khởi động lại, các công cụ đã được bật.
  • Đoạn instructions đã nằm trong tệp mà client của bạn đọc.
  • Một prompt thử nghiệm đã hoàn thành trọn vẹn một lượt đăng ký: alias được điền vào biểu mẫu, chờ trên address, mã được đọc ra.
  • Sẽ không có gì mang tính bí mật được gửi đến một trong các hộp thư này — chúng đều là công khai.

Đó là toàn bộ phần thiết lập. Cùng một máy chủ đó hoạt động được từ bất kỳ framework nào nói được MCP, còn với các agent được xây dựng mà không dùng MCP — một hàm tool thuần túy trong LangChain, OpenAI Agents SDK, hay vòng lặp tự viết của riêng bạn — bài email cho AI agent trình bày phiên bản REST của cùng bốn bước đó.

Câu hỏi

Tôi có cần API key hay tài khoản cho máy chủ MCP không?

Không cần. Các tên miền công khai không cần key, không cần tài khoản, không cần header nào, và máy chủ MCP này lộ ra đúng những gì REST API lộ ra. Chỉ có nhóm tên miền trả phí được giữ ngoài các danh sách chặn email dùng một lần mới dùng đến bearer token, được truyền dưới dạng một header Authorization trên endpoint đó.

Đây là Streamable HTTP hay SSE?

Streamable HTTP: một POST, một phản hồi JSON. Không có event stream nào cần giữ mở, và đó chính là lý do wait_for_message bị giới hạn ở mức 25 giây — một client mở một GET và mong đợi SSE sẽ được báo lại, bằng JSON thuần túy, rằng chẳng có SSE nào ở đây cả.

Nhiều agent có thể dùng chung máy chủ này cùng lúc không?

Có thể. Không có trạng thái phiên nào cả; mỗi lệnh gọi tự mang theo mọi thứ nó cần. Giới hạn dùng chung duy nhất là chỉ 8 lệnh gọi wait_for_message được chạy cùng lúc trên toàn hệ thống — vượt quá con số đó, công cụ này sẽ trả về timed_out ngay lập tức và yêu cầu được gọi lại, điều mà đoạn instructions ở trên đã xử lý sẵn.

Vì sao wait_for_message lại trả về trước khi thư kịp đến?

Vì một worker của máy chủ ngủ hàng phút trời là một worker mà không ai khác có thể dùng được. Lượt chờ bị giới hạn ở mức 25 giây và báo timed_out một cách trung thực thay vì báo thất bại; agent sẽ gọi lại. Ba lượt gọi là đã chờ hơn một phút, đủ bao trùm mọi email giao dịch thực sự đã được gửi đi.

Agent có thể gửi email luôn không?

Không thể. Dịch vụ này được thiết kế để chỉ nhận thư — một máy chủ miễn phí, không cần tài khoản mà lại có thể gửi thư thì sẽ trở thành một trạm chuyển tiếp spam chỉ trong vòng một giờ. Một agent cần gửi thư phải dùng một nhà cung cấp dịch vụ gửi thư; còn cái này chỉ dành cho việc đọc những gì gửi đến.

Hộp thư có riêng tư với agent của tôi không?

Không riêng tư. Bất kỳ ai biết address đều đọc được nó, dù trên tên miền công khai hay trên tên miền riêng của bạn. Đó chính là lý do alias tồn tại: trang web nhận được một địa chỉ đưa thư đến hộp thư nhưng không thể dùng để mở nó. Đừng bao giờ để một agent gửi bất cứ thứ gì mang tính bí mật đến một trong các hộp thư này.

Nếu những thứ này thay đổi, cấu hình client nào mới là chuẩn?

Tài liệu chính thức của từng client. Các hình dạng cấu hình ở trên là những gì đang được dùng tính đến tháng 9 năm 2026; phía máy chủ thì không thay đổi theo chúng — nó vẫn chỉ là một URL, và bất kỳ client nào có thể gọi một máy chủ MCP từ xa qua HTTP đều có thể gọi được nó.

Hãy thử ngay khi nó còn mới

Một địa chỉ chỉ mất một cú nhấp, không tài khoản và không thẻ. Mọi thứ trong hướng dẫn này đều hoạt động ngay trên đó.

Chào mừng trở lại

Hộp thư và tên miền của bạn, ở cùng một nơi.