Episode ini menutup fase operasional dengan negosiasi versi antar era spec MCP: bagaimana client modern dan legacy berhadapan, strategi implementasi dual-era agar satu server melayani keduanya, serta kebijakan deprecation — fitur seperti Roots, Sampling, dan Logging yang memakai removal clock sekitar satu tahun sebelum dihapus.

Di episode 16 kalian mengelola fleet dengan versioning dan rolling deployment. Tapi ada satu versi yang lebih rumit dari versi aplikasi kalian: versi protokol MCP itu sendiri. Spec berubah besar di 2026-07-28 — stateless, server/discover, MRTR, deprecation — sementara klien yang beredar (IDE agents, CLI agents, aplikasi lama) masih ada yang berbicara era 2025-11-25 atau lebih tua. Episode 17 ini membahas bagaimana kalian tetap bertahan ketika dua dunia itu bertemu.
Roadmap episode ini: mekanisme version negotiation, apa saja yang berubah antara era modern dan legacy, strategi implementasi dual-era agar satu server melayani kedua era, kebijakan deprecation dengan removal clock, dan rencana migrasi yang terukur.
Semua sesi MCP dimulai dengan handshake initialize (dari episode 3). Salah satu peran terpentingnya adalah version negotiation: client menyatakan protocolVersion yang didukungnya, dan server menjawab dengan versi yang akan dipakai bersama. Keduanya tidak harus persis sama — mereka mencari versi tertinggi yang dipahami keduanya.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2026-07-28",
"capabilities": { "tools": {}, "resources": {} },
"clientInfo": { "name": "legacy-agent", "version": "1.4.0" }
}
}Server yang mendukung banyak era menjawab dengan versi yang paling cocok. Sebuah server modern yang juga kompatibel dengan client lama akan merespons protocolVersion: "2025-11-25" jika client hanya memahami era itu. Negosiasi inilah fondasi semua strategi compatibility — tanpa ini, server dan client yang berbeda era akan saling mengirim pesan yang tidak dipahami.
Supaya kalian tahu apa yang harus dijembatani, rangkum perbedaan paling menentukan antara era modern (2026-07-28+) dan legacy (2025-11-25 ke bawah):
| Aspek | Legacy (≤2025-11-25) | Modern (2026-07-28+) |
|---|---|---|
| State | Session state dengan Mcp-Session-Id | Stateless, identitas per-request |
| Handshake | initialize lalu session | server/discover menggantikan handshake penuh |
| Notifikasi panjang | Mengandalkan stream SSE | MRTR dengan messageId/routingId |
| Fitur tambahan | Roots, Sampling, Logging di core | Deprecated, diganti OTel & extensions |
| MRTR | Tidak ada | Tersedia |
Di tingkat implementasi, perbedaan ini terasa paling sakit pada state: client legacy mengirim Mcp-Session-Id dan mengharapkan server mengingatnya, sementara client modern mengirim segalanya per-request. Server yang melayani keduanya harus menangani kedua pola tanpa mencampurnya.
Dual-era berarti satu server biner yang bisa melayani client dari kedua era secara bersamaan. Ini strategi yang paling banyak dipakai selama transisi, dan polanya konsisten:
protocolVersion pada initialize (atau dari server/discover untuk client modern).Mcp-Session-Id), client modern mendapat alur stateless.Contoh logika deteksi era di sisi server:
const MODERN = "2026-07-28";
const LEGACY = "2025-11-25";
function negotiate(clientVersion) {
const supported = [MODERN, LEGACY];
return supported.includes(clientVersion) ? clientVersion : LEGACY;
}
function handleInitialize(req, res) {
const era = negotiate(req.params.protocolVersion);
if (era === MODERN) {
return res.json({ protocolVersion: MODERN, serverDiscover: true });
}
res.setHeader("Mcp-Session-Id", crypto.randomUUID());
return res.json({ protocolVersion: LEGACY, capabilities: legacyCaps });
}Dual-era memang menambah kompleksitas kode, tapi memberi waktu transisi yang berharga: kalian tidak wajib meng-upgrade semua klien bersamaan dengan rilis server. Strategi yang lebih ketat — misalnya menolak semua client legacy — hanya layak jika kalian mengontrol seluruh klien dan punya jadwal rilis terkoordinasi.
Warning
Dual-era bukan alasan untuk mengabaikan keamanan. Fitur legacy — khususnya session state dan Roots — membawa risiko yang sudah dimitigasi di era modern. Pastikan client legacy yang dilayani tetap lewat gateway dengan unified auth (episode 16), dan pantau metrik berapa traffic masih memakai era lama; itu data utama untuk keputusan kapan era legacy boleh dimatikan.
MCP menetapkan kebijakan deprecation yang disiplin: fitur yang ditinggalkan tidak dihapus mendadak, melainkan diberi removal clock — masa tenggang sekitar satu tahun sejak status deprecated diumumkan. Tiga nama yang paling sering kalian temui:
Fitur-fitur ini masih bisa dipakai selama removal clock berjalan — server dual-era sering menyediakannya untuk client lama — tapi tidak akan ada pengembangan, dan dukungannya akan dicabut setelah tenggat. Rencana kalian seharusnya:
Menggabungkan semuanya, inilah rencana migrasi yang terukur untuk tim kalian:
Selama seluruh proses, terus kembali ke version negotiation: selama server dan client menyepakati versi di handshake, dua era bisa hidup berdampingan dengan damai. Kesalahan paling umum bukan teknis, melainkan manajerial — mengabaikan negosiasi versi sampai rilis besar mengagetkan semua orang.
Episode 17 menutup fase operasional dengan kedewasaan: version negotiation menjadi jembatan antara era spec yang berbeda, perbedaan modern dan legacy (state, handshake, notifikasi, fitur) dipetakan untuk disiasati, strategi dual-era memberi waktu transisi, deprecation policy dengan removal clock sekitar satu tahun membuat penghapusan terencana, dan rencana migrasi lima langkah menjaga perjalanan tetap terukur.
Inti yang harus dibawa pulang:
server/discover versus handshake penuh.Episode 18 berikutnya kita masuk fase advanced: Advanced SDK & Custom Transport — implementasi transport kustom seperti WebSocket dan gRPC, JSON-RPC framing, notification batching, dan error codes. Sampai jumpa!