AI agent & MCP

AI Agent Verifikasi Email Sendiri lewat MCP

Agent otonom bisa sampai ke tahap “cek email Anda untuk kode”, lalu berhenti di situ. Inilah solusi lengkapnya: enam tool MCP, tanpa akun dan tanpa kunci, dan salah satunya menunggu sampai pesannya benar-benar tiba.

  • Menengah
  • 13 menit baca
Robot kecil berwarna abu-abu yang mengulurkan amplop biru ke arah kotak surat terbuka, dengan sebuah stopwatch menunggu di antara keduanya

Apa yang dibutuhkan agent tapi tidak diberikan REST API

Situs ini punya REST API, dan seorang programmer yang mengintegrasikannya akan baik-baik saja. Agent tidak: ia tidak bisa membuka referensinya, memutuskan endpoint mana dari tiga yang tersedia yang diinginkan, lalu menyusun sendiri permintaan dengan query string yang tepat. Ia bertanya kepada server apa saja yang bisa dilakukan, menerima skema yang bisa dibaca mesin, lalu memanggil salah satunya.

Jadi semua yang dilakukan layanan ini diekspos untuk kedua kalinya, sebagai tool. Enam buah, dan tidak ada state yang perlu dikelola di antara panggilan:

ToolUntuk apa
create_inboxMembuat alamat baru yang bisa langsung dibagikan oleh agent. Tidak ada yang dipesan di sisi server, jadi panggilan ini tidak bisa gagal. Menerima prefix opsional yang bisa dibaca manusia; akhiran acak menjaganya tetap unik.
list_domainsDomain publik yang boleh dipakai siapa saja — berguna saat sebuah formulir baru saja menolak salah satunya.
list_messagesSemua yang menunggu di sebuah alamat, yang terbaru lebih dulu. Langsung memberi jawaban, termasuk saat tidak ada apa-apa.
read_messageSatu pesan secara lengkap: pengirim, subjek, teks polos, HTML, lampiran. Di sinilah kode atau tautan masuknya berada.
wait_for_messageMenunggu sampai sesuatu tiba, lalu mengembalikannya secara lengkap. Tool yang dipanggil tepat setelah sebuah formulir dikirim.
delete_messageMenghapus satu pesan sekarang juga, alih-alih menunggu 5 hari sampai kedaluwarsa. Idempoten, jadi agent yang mencoba ulang tidak menimbulkan biaya apa pun.

Server ini juga menjawab initialize dengan satu paragraf singkat berisi instruksi, yang oleh sebagian besar klien langsung diteruskan ke model. Agent pun tiba dengan sudah mengetahui untuk apa layanan ini dan apa satu-satunya peringatan pentingnya, tanpa ada orang yang perlu menuliskannya ke dalam prompt.

Menghubungkan klien MCP dalam satu baris

Endpoint-nya cuma satu URL, dan tidak ada pendaftaran apa pun untuk domain publiknya. Setiap klien MCP memakai bentuk konfigurasi yang sama — Claude Desktop, Claude Code, Cursor, Continue, OpenAI Agents SDK, dan apa pun lain yang mendukung protokol ini:

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

Transportnya adalah Streamable HTTP: satu POST berisi JSON-RPC 2.0, satu balasan JSON, tanpa stream yang tetap terbuka. Jadi Anda bisa memeriksa semuanya dari terminal sebelum agent mana pun terlibat:

menampilkan daftar tool, dari shell
curl -sX POST https://grabmail.io/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Klien yang mencari server dulu sebelum bertanya ke manusia akan menemukan /.well-known/mcp.json di domainnya, yang menyebutkan endpoint yang sama beserta transportnya.

Seluruh alur pendaftaran, dalam empat panggilan tool

Ini urutan yang dibutuhkan hampir semua agent, dan tidak ada yang lain selain ini:

  1. Panggil create_inbox. Hasilnya berupa sebuah alamat, sebuah alias, domainnya, dan sebuah catatan yang memberi tahu agent mana dari keduanya yang harus dibagikan. Belum ada yang benar-benar dibuat — kotak suratnya baru mulai ada saat pesan pertama masuk ke dalamnya.
  2. Masukkan alias-nya ke dalam formulir. Layanan yang sedang didaftari mendapat alamat yang berfungsi, yang sampai ke kotak suratnya tapi tidak bisa dipakai untuk membacanya.
  3. Panggil wait_for_message dengan alamatnya. Tepat setelah formulir dikirim, bukan berdasarkan jadwal waktu. Tool ini menunggu; ia tidak melakukan polling dalam loop yang harus ditulis sendiri oleh agent.
  4. Baca kodenya dari dalam pesan. Isi lengkapnya sudah ikut kembali bersama hasil menunggu tadi, jadi biasanya tidak perlu panggilan kedua sama sekali — read_message hanya dibutuhkan untuk sesuatu yang sudah tiba sebelumnya.
Agent Andamengambil sebuah alamat dan sebuah aliasSitusnyamenerima alias-nya, mengirim kodenyaGrabMailmenahan apa yang tibawait_for_message, hingga 25 smengembalikan pesan lengkapnya, atau timed_out
Empat panggilan, dan hanya satu yang menunggu. Alias-nya keluar ke situs; alamatnya tetap dipegang agent dan itulah yang didengarkannya.

Kenapa wait_for_message bisa kembali sebelum emailnya tiba

Inilah tool yang membuat agent benar-benar bisa dipakai, dan juga yang perilakunya paling sering mengejutkan orang, jadi pantas diberi waktu semenit untuk dipahami. Sebuah panggilan terlihat seperti ini:

menunggu pesan yang subjeknya mengandung “code”
curl -sX POST https://grabmail.io/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":
        {"name":"wait_for_message",
         "arguments":{"address":"demo.5kuqarzuch@grabmail.io",
                       "subject_contains":"code"}}}'

Tool ini menunggu hingga 25 detik. Kalau sampai saat itu belum ada yang tiba, ia tidak gagal — ia kembali dengan jawaban apa adanya dan minta dipanggil lagi:

jawaban setelah menunggu tanpa hasil
{
  "timed_out": true,
  "waited_seconds": 25,
  "message": null,
  "note": "Nothing arrived yet. Call wait_for_message again ..."
}
Kenapa harus dibatasi
Setiap detik menunggu adalah satu worker server yang tidak melakukan apa-apa selain tidur, dan jumlahnya terbatas. Waktu tunggu yang bisa sampai lima menit berarti satu agent menahan satu slot yang dibutuhkan seratus agent lain. 25 detik juga masih berada di dalam timeout default kebanyakan klien, sehingga panggilannya kembali dengan sendirinya alih-alih ditinggalkan oleh klien yang menyerah duluan.
Hanya 8 sesi tunggu dalam satu waktu
Lewat dari itu, tool-nya langsung menjawab dengan timed_out beserta catatan yang menjelaskannya. Diberi tahu untuk kembali lagi jauh lebih baik daripada diantre di belakang tujuh agent lain tanpa cara untuk mengetahuinya.
Penyaringan, supaya email yang salah tidak ikut menghentikannya
from_contains dan subject_contains membuat sesi tunggu ini mengabaikan apa pun lain yang masuk di saat bersamaan. since_id adalah parameter yang perlu dikirim kalau kotak suratnya sudah berisi sesuatu sebelumnya: berikan id terbaru yang sudah pernah dilihat, dan hanya email yang benar-benar baru yang akan memenuhi panggilan itu.

Bagikan alias-nya, pantau alamatnya

Setiap kotak surat di sini punya alamat kedua sepanjang dua belas karakter, yang mengantarkan pesan ke kotak surat yang sama tapi tidak bisa membacanya. Perbedaan ini jauh lebih penting bagi agent dibanding bagi manusia, karena agent akan dengan senang hati menempelkan apa pun yang diberikan ke kolom apa pun yang ditemukannya.

Jadi create_inbox tidak sekadar mengembalikan sebuah alamat dan berharap yang terbaik. Ia mengembalikan keduanya, plus sebuah next_step yang menjelaskan mana yang mana — agent membaca hasil tool-nya sendiri, sehingga instruksinya sampai tepat saat dibutuhkan, bukannya tertinggal di halaman dokumentasi yang tidak terbaca oleh siapa pun dalam loop itu.

Apa yang perlu ditulis di instruksi agent

Tool-toolnya sudah cukup menjelaskan dirinya sendiri sehingga model yang cukup andal bisa melakukan ini dengan benar tanpa diberi tahu. Lima baris berikut membuatnya jadi pasti, bukan sekadar mungkin:

  • Satu alamat untuk satu pendaftaran. Bukan satu alamat yang dipakai ulang di mana-mana: kotak surat yang menampung email dari enam layanan berarti enam konfirmasi yang harus dibedakan sendiri oleh agent, dan satu kebocoran yang membuka semuanya sekaligus.
  • Bagikan alias-nya, jangan pernah alamatnya. Layak ditulis secara eksplisit meski hasil tool-nya juga sudah mengatakan hal yang sama.
  • Panggil wait_for_message tepat setelah mengirim formulir, dan panggil lagi saat mendapat timed_out alih-alih menganggapnya sebagai kegagalan. Dua atau tiga kali itu normal.
  • Kirim since_id saat kotak suratnya bukan yang baru, kalau tidak, pesan lama bisa saja memenuhi sesi tunggu itu dan agent akan membaca kode yang sudah kedaluwarsa sejak sejam lalu.
  • Hapus pesannya setelah kodenya dipakai. Tidak wajib — semuanya akan hilang dalam 5 hari juga — tapi ini menutup celahnya lebih awal dan hanya perlu satu panggilan idempoten.

Ditulis sebagai blok instruksi, panjangnya kira-kira seperti ini:

system prompt, atau satu baris di AGENTS.md
Saat Anda butuh alamat email, panggil create_inbox lalu bagikan ALIAS yang
dikembalikannya, jangan pernah alamatnya. Tepat setelah formulir dikirim, panggil
wait_for_message dengan alamatnya. Kalau jawabannya timed_out, panggil lagi —
itu wajar dan tidak ada yang hilang. Kirim since_id kalau kotak suratnya sudah
berisi email sebelumnya. Hapus pesannya setelah kodenya dipakai.

Batasan yang perlu diketahui sebelum membangun di atasnya

Semuanya dipublikasikan, bukan ditemukan sendiri, dan tidak satu pun punya paket berbayar yang menaikkan batasnya:

BatasanNilaiArtinya bagi agent
Satu sesi tunggu25 detikLalu timed_out. Panggil lagi; jangan anggap ini sebagai error.
Sesi tunggu bersamaan8Lewat dari itu, tool-nya langsung menjawab dan memberi tahu soal itu. Gunakan list_messages sebagai cadangan.
PembacaanSatu per detik, per alamatJauh di atas yang dilakukan loop pemanggilan tool biasa. Satu sesi tunggu yang blocking adalah satu request, bukan enam puluh.
Ukuran pesan5 MBDitolak selama percakapan SMTP berlangsung, sehingga pengirimnya yang diberi tahu, bukan agent yang menunggu sesuatu yang tidak akan pernah datang.
Retensi5 hariBatas keras yang dijalankan oleh sebuah proses otomatis. Apa pun yang harus disimpan agent, ia harus mencatatnya sendiri.

Tidak ada endpoint untuk mengirim dan tidak ada tool untuk itu. Layanan ini hanya menerima, dan itulah yang menjaga kotak surat tanpa autentikasi ini agar tidak menjadi relay spam — jadi agent yang perlu membalas ke manusia butuh kotak surat sungguhan di tempat lain.

Kalau formulir menolak domain publik

Banyak layanan menyimpan daftar domain email sekali pakai, dan ketiga domain publik di sini termasuk di dalamnya. Agent akan mengalami ini sebagai formulir yang menolak alamat yang baru saja diberikan, atau yang lebih buruk, menerimanya tapi tidak pernah mengirim apa pun.

Jawaban yang bertahan lama adalah domain milik Anda sendiri. Satu record MX mengubah setiap alamat di domain itu menjadi kotak surat di sini, tidak ada dalam daftar siapa pun karena tidak pernah dicantumkan di mana pun pada situs ini, dan keenam tool yang sama tetap berfungsi tanpa perubahancreate_inbox satu-satunya yang tidak, karena tool itu membuat alamat khusus pada domain publik. Agent tinggal memakai you-pick-it@your-domain dan memanggil wait_for_message pada alamat itu.

Record MX untuk domain Anda10 smtp.grabmail.io

Panduan lengkapnya ada di sini — recordnya, apa yang dibuktikan dengan mempublikasikannya, dan batasan kotak surat tanpa kata sandi.

Yang sebaiknya tidak dilakukan agent dengan ini

Bagian yang jujur, dan bagian yang menghemat waktu Anda satu sore:

  • Jangan simpan apa pun yang harus bisa Anda pulihkan kembali. Apa pun yang menyangkut uang, identitas, atau pekerjaan. Kotak suratnya kosong lagi dalam 5 hari dan bisa dibaca oleh siapa pun yang tahu alamatnya, jadi reset kata sandi yang dikirim ke sana tahun depan tidak akan sampai ke siapa-siapa — atau malah sampai ke orang lain.
  • Jangan jadikan faktor kedua. Kotak surat tanpa kata sandi bukanlah sebuah faktor keamanan.
  • Jangan untuk apa pun yang bersifat privat. Bukan karena kami membacanya, tapi karena alamatnya adalah satu-satunya hal rahasia di sini, dan agent bisa saja sudah menuliskannya ke dalam log, transcript, atau pesan commit.
  • Jangan untuk membuat akun massal. Agent yang membuka akun sampai ratusan adalah persis perilaku yang membuat semua blocklist itu dibuat, dan itu cara tercepat membuat domain publik ini ditolak untuk semua orang lain.

Dipakai sesuai fungsinya — langkah konfirmasi yang berdiri di antara agent dan hal yang sebenarnya diminta untuk dilakukannya — ini menghilangkan satu-satunya langkah yang selama ini selalu menghentikannya.

Pertanyaan

Apakah saya perlu API key atau akun?

Tidak. Domain publik, tool-toolnya, dan domain milik Anda sendiri semuanya gratis dan tanpa autentikasi. Satu-satunya kasus yang butuh kunci adalah domain yang sudah ditutup atas permintaan, yang kemudian meminta header Authorization.

Berfungsi dengan klien apa saja?

Klien mana pun yang mendukung Model Context Protocol — Claude Desktop, Claude Code, Cursor, Continue, OpenAI Agents SDK, dan lainnya. Transportnya adalah Streamable HTTP, yang memang jadi default kebanyakan klien saat ini, dan tiga versi protokol diterima sehingga klien yang lebih lama pun tetap bisa terhubung.

Kenapa wait_for_message bisa kembali dengan timed_out?

Karena satu sesi tunggu memang sengaja dibatasi hingga 25 detik. Ini bukan error dan tidak ada yang hilang: panggil lagi saja. Email seringkali butuh waktu lebih lama daripada yang disiratkan halaman yang menjanjikannya, dan dua atau tiga kali menunggu berturut-turut adalah hal biasa dalam sebuah pendaftaran.

Bisakah agent memakai domain saya sendiri?

Bisa, dan yang berubah cuma alamatnya. Arahkan record MX ke smtp.grabmail.io dan setiap alamat pada domain itu jadi bisa dibaca lewat tool yang sama. Hanya create_inbox yang khusus domain publik, karena itu satu-satunya tool yang membuatkan nama untuk Anda.

Bisakah agent mengirim email lewat ini?

Tidak. Tidak ada tool untuk mengirim dan tidak ada endpoint untuk mengirim, memang disengaja: layanan tanpa autentikasi yang bisa mengirim email akan menjadi relay spam dalam sehari. SPF kami adalah v=spf1 -all dan DMARC kami adalah p=reject, jadi apa pun yang mengaku berasal dari alamat di sini pasti palsu.

Apakah kotak masuknya bersifat privat?

Tidak, dan inilah satu-satunya peringatan yang perlu diberikan secara eksplisit ke agent. Pada domain publik, siapa pun yang tahu atau menebak alamatnya bisa membacanya. Gunakan alamat yang sulit ditebak, bagikan alias-nya alih-alih alamatnya, dan jangan pernah biarkan apa pun yang bersifat privat mendekatinya.

Bisakah dua agent menunggu di alamat yang sama sekaligus?

Bisa, dan keduanya akan sama-sama menerima pesannya saat tiba. Yang dibatasi adalah jumlah sesi tunggu yang berlangsung bersamaan di seluruh layanan ini, yaitu 8; lewat dari itu, tool-nya langsung menjawab dan memberi tahu soal itu, dan list_messages tetap berfungsi.

Berapa lama pesan-pesannya bertahan?

5 hari sejak tiba, dibaca ataupun tidak, dan tidak ada pengaturan yang bisa memperpanjangnya. Setiap pesan membawa expires_at, jadi agent tidak pernah perlu menghitung sendiri tanggal itu.

Apa bedanya dengan memanggil REST API langsung dari skrip?

Untuk skrip, tidak ada bedanya, dan REST API justru lebih cocok — panduan menguji alur verifikasi membahas bentuknya, termasuk deadline dan helper-nya. MCP dipakai untuk kasus saat tidak ada seorang pun yang menulis loop-nya: modelnya sendiri yang memutuskan untuk membuka kotak masuk, dan butuh tool yang bisa ditemukan sendiri, bukan sekadar didokumentasikan.

Coba selagi masih segar

Alamat hanya perlu satu klik, tanpa akun dan tanpa kartu. Semua yang ada di panduan ini langsung berfungsi dengannya.

Selamat datang kembali

Kotak surat dan domain Anda, di satu tempat.