Membandingkan dua era lifecycle MCP: alur legacy dengan handshake initialize dan session state berbasis Mcp-Session-Id, versus alur modern stateless 2026-07-28 yang mengirim versi, identity, dan capabilities per-request serta memakai server/discover untuk bootstrap.

Di episode 2 kita sudah memahami arsitektur tiga lapis dan primitives MCP. Sekarang pertanyaannya: bagaimana sebuah koneksi dimulai, dirawat, dan berakhir? Jawabannya inilah yang disebut lifecycle — dan di sinilah MCP mengalami perombakan paling besar pada 2026-07-28.
Episode ini membedah dua era yang bersebrangan: era legacy yang butuh handshake initialize dan menyimpan state sesi, melawan era modern yang sepenuhnya stateless. Kalian akan paham mengapa server MCP modern bisa di-deploy di belakang load balancer tanpa sticky session — sesuatu yang menyakitkan di era legacy.
Pada spesifikasi 2025-11-25 ke bawah, setiap koneksi MCP dimulai dengan handshake initialize yang wajib dilakukan:
initialize berisi versi protokol, nama client, dan capabilities.initialized untuk menandai handshake selesai.tools/list.{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": { "name": "my-host", "version": "1.0.0" }
}
}Kunci dari era ini adalah session state: server mengingat informasi handshake per koneksi, dan mengidentifikasi koneksi lewat header Mcp-Session-Id. Semua request berikutnya wajib membawa Mcp-Session-Id ini, karena server butuh tahu siapa yang berbicara dan versi apa yang sedang dipakai.
Session state memunculkan masalah yang tidak nyaman untuk production: request yang sama harus selalu jatuh ke server instance yang sama. Jika ada dua instance server di belakang load balancer, instance kedua tidak akan mengenal session dari instance pertama — hasilnya error atau re-handshake.
Solusi yang biasa dipakai adalah sticky session di load balancer. Masalahnya, sticky session membatasi distribusi beban, menyulitkan restart rolling, dan membuat horizontal scaling tidak leluasa. Inilah PR besar yang dijawab era stateless.
Pada 2026-07-28, inti protokol dirombak menjadi stateless. Prinsipnya sederhana: tidak ada lagi handshake, tidak ada lagi state sesi. Setiap request berdiri sendiri dan membawa semua informasi yang dibutuhkan server:
Karena tidak ada state di server, satu request bisa di-route ke server mana pun. Kalian bahkan bisa menaruh beberapa server berbeda di belakang satu endpoint — request dijawab oleh siapa pun yang tersedia. Untuk mencoba pola stateless ini, pastikan SDK kalian versi terbaru dengan npm install @modelcontextprotocol/sdk@latest.
Legacy : [initialize handshake] -> [session A] -> [request pakai Mcp-Session-Id]
Modern : [request mandiri + versi + identity + capabilities] -> [response]Kalau tidak ada handshake, bagaimana client tahu versi dan capability server? Jawabannya adalah server/discover — sebuah method baru yang menggantikan peran handshake untuk bootstrapping, bukan untuk membentuk sesi.
{
"jsonrpc": "2.0",
"id": 1,
"method": "server/discover",
"params": {
"protocolVersion": "2026-07-28",
"clientInfo": { "name": "my-host", "version": "1.0.0" }
}
}Server membalas dengan daftar protokol yang didukung, capabilities, dan versi yang dipilih. Client kemudian menyimpan hasilnya sebagai konteks — tapi tidak ada session yang "hidup" di server. Request berikutnya tetap membawa informasi versi dan identity masing-masing.
Info
Jangan bingung dengan episode 8 tentang MRTR: server/discover adalah bootstrap satu arah untuk menegosiasikan versi, sedangkan MRTR (Multi-Round-Trip Requests) adalah mekanisme request interaktif mid-call lewat messageId dan routingId. Keduanya lahir di era yang sama (2026-07-28) tapi melayani tujuan berbeda.
Keputusan stateless membuka pintu lebar-lebar untuk operasional production:
| Kemampuan | Era Legacy | Era Modern |
|---|---|---|
| Load balancer | Perlu sticky session | Bebas (round-robin) |
| Restart rolling | Rumit (session hilang) | Aman (tidak ada session) |
| Scale horizontal | Terbatas | Bebas |
| Health check | Perlu tahu instance | Stateless, mudah |
Dengan stateless, request bisa di-route ke server mana pun — round-robin load balancer cukup membagi request rata tanpa memperhatikan session. Server mati? Request berikutnya langsung dilayani instance lain tanpa re-handshake. Ini fondasi yang membuat deployment MCP berskala besar (episode 9) dan fleet management (episode 16) menjadi masuk akal.
Karena ekosistem masih punya server lama, klien modern disarankan dual-era compatible: tahu cara berbicara dengan server legacy maupun modern. Polanya sederhana:
initialize (era legacy).const discovered = await tryStatelessDiscover();
if (discovered.failed) {
await initializeLegacyHandshake();
}Perhatikan: ini hanyalah ilustrasi alur. Implementasi lengkap memakai SDK resmi akan kita bahas di episode 6 (server) dan episode 7 (client), dan strategi kompatibilitas dua era lebih dalam di episode 17.
Pada episode 3 ini kalian sudah memahami dua era lifecycle MCP: era legacy yang memakai handshake initialize plus session state Mcp-Session-Id, dan era modern 2026-07-28 yang stateless dengan versi, identity, dan capabilities dikirim per-request, ditopang server/discover untuk bootstrap.
Inti yang harus dibawa pulang:
initialize dan memakai Mcp-Session-Id untuk menyimpan state.server/discover menggantikan handshake untuk bootstrap versi dan capability.Di episode 4 berikutnya kita akan membahas Tools secara mendalam — bagaimana tool didefinisikan dengan JSON Schema, dipanggil lewat tools/call, menghasilkan structured output, dan apa itu tool annotation beserta batasannya. Sampai jumpa di episode 4!