Lewati ke konten
26/30Bab 26 dari 30

MCP Dijelaskan Berdasarkan Spesifikasi: Apa Sebenarnya Server Itu

Satu baris JSON ke subprocess, 13 definisi tool kembali—dibaca terhadap revisi 2026-07-28 yang menghapus handshake.

Di halaman ini

Instal server MCP yang sudah dipublikasikan, kirim satu baris JSON, lalu baca apa yang kembali.

terminalBASH
npm i @modelcontextprotocol/server-everything@2026.8.31
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  | npx @modelcontextprotocol/server-everything stdio
TEXT
{"result":{"tools":[{"name":"echo","title":"Echo Tool","description":"Echoes
back the input string","inputSchema":{"$schema":"http://json-schema.org/draft-07/
schema#","type":"object","properties":{"message":{"type":"string","description":
"Message to echo"}},"required":["message"]},"annotations":{"readOnlyHint":true,
…                                        … 7,663 bytes on one line …
"jsonrpc":"2.0","id":1}

Tiga belas definisi tool, dalam satu baris, dari sebuah proses yang membaca satu baris dari standard input-nya. Kamu baru saja berbicara dengan Model Context Protocol, tanpa SDK, tanpa client library, dan tanpa framework. Itulah keseluruhannya: sebuah transport, format pesan, dan sekumpulan kecil method bernama.

Chapter 18 mendefinisikan tool sebagai dua hal — JSON Schema yang dilihat model, dan endpoint di kode kamu yang tidak pernah dilihat model. Chapter 23 membangun harness yang menyimpan katalog tool tersebut. Keduanya tidak menjawab pertanyaan yang menentukan apakah semua ini bisa digunakan ulang: siapa yang menulis schema, dan bagaimana schema itu berpindah dari siapa pun yang menulisnya ke dalam prompt kamu? MCP adalah salah satu jawaban untuk pertanyaan itu, dan layak dibaca dari sumber aslinya, karena hampir semua tulisan tentangnya menjelaskan revisi yang sudah tidak ada.

Tiga hal tentang perintah yang baru saja kamu jalankan itu salah, dan masing-masing menjadi satu bagian dalam bab ini. Perintah itu tidak membawa versi protokol, jadi server yang sesuai spesifikasi semestinya menolaknya. Perintah itu tetap mendapat jawaban, karena alasan yang oleh spesifikasi disebut hazard, bukan fitur. Dan perintah itu meminta salah satu dari tiga primitive tanpa pernah menemukan bahwa dua lainnya ada.

Masalah yang diselesaikannya, dan analogi yang dibuat sendiri oleh spesifikasi

Tautan ke bagian: Masalah yang diselesaikannya, dan analogi yang dibuat sendiri oleh spesifikasi

Sebelum wire, hitungannya dulu. Kamu punya NN aplikasi AI dan MM hal yang harus bisa dijangkaunya — kalender, ticket tracker, database warehouse, tool desain. Tanpa kontrak bersama, seseorang menulis N×MN \times M integrasi, dan masing-masing adalah schema plus endpoint plus cerita autentikasi plus beban pemeliharaan. Dengan kontrak bersama, vendor tool menulis server, vendor aplikasi menulis client, dan totalnya menjadi N+MN + M.

Itu bukan observasi baru, dan spesifikasi mengatakan dari mana idenya berasal:

MCP takes some inspiration from the Language Server Protocol, which standardizes how to add support for programming languages across a whole ecosystem of development tools. In a similar way, MCP standardizes how to integrate additional context and tools into the ecosystem of AI applications.1

Ambil perbandingan itu secara harfiah, bukan sebagai pujian. Sebelum protokol itu, mendukung sebuah bahasa di editor berarti satu plugin per editor; setelahnya, tim bahasa mengirimkan satu server dan setiap editor mendapatkannya. Ukuran keberhasilannya bukan elegansi, melainkan jumlah integrasi berhenti berlipat ganda. Hal yang sama berlaku di sini: nilainya ada pada jumlah implementasi, bukan pada desainnya. Protokol yang hanya dipakai dua produk adalah format data dengan seremoni tambahan.

Pesan MCP adalah JSON-RPC 2.0. Request adalah objek dengan jsonrpc, sebuah id, sebuah method, dan params opsional; response membawa id yang sama dan salah satu dari result atau error; notification adalah request tanpa id dan tidak mendapat balasan. Spesifikasi menambahkan tiga batasan di atasnya: id harus berupa string atau number dan tidak boleh null, tidak boleh bertabrakan dengan request lain yang masih berjalan, dan setiap result harus membawa field resultType.2

Pada transport stdio — yang dipakai perintah di atas — aturan framing-nya adalah satu baris per pesan:

Messages are delimited by newlines, and MUST NOT contain embedded newlines. […] The server MUST NOT write anything to its stdout that is not a valid MCP message.3

Klausul terakhir itu adalah cara paling umum server buatan sendiri rusak, dan rusaknya diam-diam: console.log yang tersesat, progress bar, peringatan deprecation dari dependency, lalu line parser client menabrak sesuatu yang bukan JSON. Jalan keluarnya ada di bagian yang sama — server boleh menulis apa pun yang ia suka ke stderr, dan client seharusnya tidak memperlakukannya sebagai error. Server referensi di atas mencetak Starting default (STDIO) server... setiap kali launch, di stderr, sehingga pipe tetap bekerja.

Transport standar lainnya adalah Streamable HTTP: setiap pesan adalah POST ke satu endpoint, dan balasannya adalah objek JSON atau stream Server-Sent Events yang scoped ke request — wire format yang Chapter 14 parse secara manual. Semantics identik pada keduanya, karena transport adalah binding: ia mendefinisikan framing dan delivery, bukan makna.4

Hal pertama yang salah: tidak ada versi

Tautan ke bagian: Hal pertama yang salah: tidak ada versi

Perintah di atas mengirim tools/list dan tidak ada yang lain. Di bawah revisi saat ini, request itu malformed, dan server yang conformant harus menolaknya.

Sejak 2026-07-28, MCP adalah protokol stateless, dan spesifikasi menyatakannya tanpa ragu:

The Model Context Protocol (MCP) is a stateless protocol: all the information needed to process a request is contained in the request itself. A server processes each request independently; no state should be inferred from previous requests, even those on the same connection or stream.2

Jadi setiap request membawa versi protokolnya sendiri dan client capabilities-nya sendiri, di objek reserved _meta di dalam params. Dua field tersebut wajib ada di setiap request; request yang kehilangan salah satunya malformed dan server harus menjawab -32602:2

_meta keyrequiredapa itu
io.modelcontextprotocol/protocolVersionyesrevisi yang dipakai request ini, misalnya "2026-07-28"
io.modelcontextprotocol/clientCapabilitiesyesapa yang bisa dilakukan client untuk server pada request ini
io.modelcontextprotocol/clientInfono (but should)nama dan versi client, hanya untuk tampilan dan log
io.modelcontextprotocol/logLevelnolevel log minimum yang sebaiknya dikeluarkan server untuk request ini

Jika ditulis penuh, tools/list yang benar seperti ini — dan ini terakhir kalinya bab ini menampilkan metadata secara penuh, karena metadata itu ada di setiap request mulai dari sini:

one line, split for the pageTEXT
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{"elicitation":{"form":{}}},
  "io.modelcontextprotocol/clientInfo":{"name":"bare-hands","version":"0.0.1"}}}}

Objek capability adalah negosiasinya. Tidak ada lagi langkah negosiasi terpisah: client menyatakan apa yang bisa dilakukannya pada setiap request, server menyatakan apa yang bisa dilakukannya di result, dan tidak satu pihak pun boleh memakai fitur yang belum diklaim pihak lain. Server yang membutuhkan capability yang tidak dideklarasikan client harus menjawab -32021 dan menyebut capability yang hilang di data.requiredCapabilities. Server yang tidak memahami versi yang diminta harus menjawab -32022 dan mencantumkan versi yang ia dukung.2

Client yang ingin mendapat jawabannya di awal bisa memintanya: server/discover adalah RPC wajib yang mengembalikan versi yang didukung, capabilities, identity, dan blok opsional instructions dalam satu round trip.5 Memanggilnya opsional. Mengimplementasikannya tidak.

Hal kedua yang salah: server itu legacy

Tautan ke bagian: Hal kedua yang salah: server itu legacy

Perintah tadi berhasil. Di bawah revisi saat ini seharusnya tidak, dan alasan mengapa berhasil lebih layak diukur daripada diparafrasekan, karena itu adalah kondisi seluruh ekosistem dalam satu baris.

Probe server referensi seperti yang diminta spesifikasi kepada client modern:

terminalBASH
echo '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{
  "io.modelcontextprotocol/protocolVersion":"2026-07-28",
  "io.modelcontextprotocol/clientCapabilities":{}}}}' \
  | npx @modelcontextprotocol/server-everything stdio
TEXT
{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"Method not found"}}

Itulah cabang ketiga dari aturan kompatibilitas: DiscoverResult berarti modern, error modern yang dikenali berarti modern-tapi-versi-salah, dan apa pun selain itu — termasuk -32601 — berarti legacy, fallback ke handshake initialize.3 Jadi lakukan itu, sambil meminta revisi saat ini:

TEXT
→ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2026-07-28",
   "capabilities":{},"clientInfo":{"name":"bare-hands","version":"0.0.1"}}}

← {"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true},
   "prompts":{"listChanged":true},"resources":{"subscribe":true,"listChanged":true},
   "logging":{},"tasks":{…},"completions":{}},"serverInfo":{"name":"mcp-servers/everything",
   "title":"Everything Reference Server","version":"2.0.0"},"instructions":"…"}}

Client meminta 2026-07-28 dan server menjawab 2025-11-25. Pada 7 September 2026, server referensi resmi — npm package @modelcontextprotocol/server-everything, versi 2026.8.31, dipublikasikan 31 Agustus 2026 — belum mengimplementasikan revisi saat ini. Begitu pula, berdasarkan tanggalnya, TypeScript SDK yang membangunnya: release 1.30.0 keluar pada 27 Juli 2026, sehari sebelum revisi itu.

Baca konsekuensinya, bukan gosipnya. Hampir semua tulisan tentang MCP menjelaskan protokol dengan handshake initialize, session, request roots/list yang dikirim server ke client, dan transport HTTP+SSE. Keempatnya sudah hilang atau sedang menuju hilang. Saat kamu membaca apa pun tentang MCP, termasuk halaman ini, hal pertama yang perlu dicari adalah nomor revisi.

Dan alasan perintah paling pertama tadi berhasil dinyatakan di spesifikasi sebagai hazard, bukan fitur:

some legacy servers do not validate that a request arrives after initialize and would process an era-ambiguous method (such as tools/call) under legacy semantics. Probing yields a deterministic failure instead.3

Terukur: mengirim tools/list ke server itu tanpa handshake sama sekali mengembalikan seluruh katalog. Method yang seharusnya ditolak justru dilayani, persis mengapa spesifikasi mengatakan untuk probe dengan server/discover terlebih dahulu bahkan ketika kamu hanya mendukung versi modern.

Tiga peran, dan kalimat yang perlu dikutip dari seluruh dokumen

Tautan ke bagian: Tiga peran, dan kalimat yang perlu dikutip dari seluruh dokumen

MCP memiliki tiga pihak, dan perbedaan antara dua yang pertama adalah yang sering diruntuhkan orang:

Host. Aplikasi: produk chat, editor, agent. Ia memiliki percakapan, model, credentials, dan consent pengguna. Ia membuat client dan menegakkan batas keamanan di antara mereka.

Client. Connector di dalam host. Setiap client berbicara dengan tepat satu server — relasi 1:1 yang ketat — dan melampirkan versi protokol serta capabilities ke setiap request yang ia route.

Server. Proses atau layanan yang mengekspos resources, tools, dan prompts. Ia bisa lokal atau remote, beroperasi secara independen, dan seluruh tugasnya adalah satu area yang terfokus.6

Aturan "tepat satu server" itu bukan pembukuan. Itulah yang membuat prinsip desain di bawah ini bisa diimplementasikan, dan inilah kalimat yang perlu kamu ambil dari spesifikasi jika hanya mengambil satu:

Servers should not be able to read the whole conversation, nor "see into" other servers. Servers receive only necessary contextual information. Full conversation history stays with the host. Each server maintains isolation. Cross-server interactions are controlled by the host.6

Itu membalik model mental yang dibawa kebanyakan orang. Server cuaca yang kamu hubungkan ke assistant kamu tidak melihat apa yang kamu tanyakan. Ia melihat tools/call dengan arguments yang dipilih model, dan tidak ada yang lain — bukan turn sebelumnya, bukan system prompt kamu, bukan result yang dikembalikan server kalender beberapa saat sebelumnya. Jika dua server perlu bekerja sama, host membawa nilai dari satu ke yang lain, secara sengaja, karena model memintanya. Itulah mengapa isolasi adalah properti keamanan yang menjadi sandaran Chapter 30: server yang compromised memiliki blast radius kecil dan terdefinisi, dan memperbesarnya menuntut host ikut bekerja sama.

Hal ketiga: tiga primitive, diurutkan berdasarkan siapa yang memegang kendali

Tautan ke bagian: Hal ketiga: tiga primitive, diurutkan berdasarkan siapa yang memegang kendali

Perintah pertama meminta tools dari server itu dan mendapat tiga belas. Tanyakan dua hal lainnya dan ia juga menjawab: resources/list mengembalikan tujuh, prompts/list mengembalikan empat. Tidak satu pun muncul, karena tidak ada yang meminta. Ini membawa kita ke tulang punggung pedagogis MCP, tersimpan di spesifikasi sebagai tabel yang hampir tidak pernah dikutip siapa pun:

PrimitiveControlDescriptionExample
PromptsUser-controlledTemplate interaktif yang dipanggil lewat pilihan penggunaSlash commands, opsi menu
ResourcesApplication-controlledData kontekstual yang dilampirkan dan dikelola clientIsi file, riwayat git
ToolsModel-controlledFunction yang diekspos ke LLM untuk melakukan aksiRequest API POST, penulisan file

Bukan "tiga cara untuk mengekspos capability". Melainkan tiga jawaban untuk siapa yang memutuskan bahwa ini terjadi. Model memutuskan untuk memanggil tool. Aplikasi memutuskan untuk melampirkan resource. Orang memutuskan untuk menjalankan prompt. Salah memahami ini dan fiturnya tetap bekerja, tetapi bekerja pada momen yang salah dan untuk alasan yang salah.

Cara paling jelas untuk merasakannya adalah kalender. Berikut server yang mengekspos kalender yang sama tiga kali, masing-masing sebagai satu primitive, dalam seratus baris Node polos tanpa dependency:

calendar.mjs — the parts that matterJS
const TOOL = {
  name: "create_event",
  description: "Create a calendar event. Writes to the calendar.",
  inputSchema: {
    type: "object",
    properties: {
      title:    { type: "string", description: "Event title." },
      startsAt: { type: "string", format: "date-time", description: "Start, ISO 8601 UTC." },
    },
    required: ["title"],
  },
};

switch (method) {
  case "resources/read":                                          
    return ok(id, { contents: [{ uri: "calendar://week",
      mimeType: "application/json", text: JSON.stringify(EVENTS) }],
      ttlMs: 60000, cacheScope: "private" });

  case "prompts/get":                                             
    return ok(id, { description: PROMPT.description, messages: [{ role: "user",
      content: { type: "text", text: `Read calendar://week and draft a plan. ` +
        `Focus: ${params.arguments?.focus ?? "balance"}.` } }] });

  case "tools/list":                                              
    return ok(id, { tools: [TOOL], ttlMs: 300000, cacheScope: "public" });
}

Jalankan dan tanyakan dengan ketiga cara. Output nyata, satu pesan per baris di wire, dibungkus di sini untuk halaman, dengan request _meta dan blok identity server dihilangkan:

TEXT
→ resources/read  {"uri":"calendar://week"}
← {"resultType":"complete","contents":[{"uri":"calendar://week",
   "mimeType":"application/json","text":"[{\"id\":\"e1\",\"title\":\"Standup\",
   \"startsAt\":\"2026-09-07T09:00:00Z\"},{\"id\":\"e2\",\"title\":\"Design review\",
   \"startsAt\":\"2026-09-09T15:00:00Z\"}]"}],"ttlMs":60000,"cacheScope":"private"}

→ prompts/get    {"name":"prepare_week","arguments":{"focus":"deep work"}}
← {"resultType":"complete","description":"Read the week and draft a plan.",
   "messages":[{"role":"user","content":{"type":"text",
   "text":"Read calendar://week and draft a plan. Focus: deep work."}}]}

→ tools/call     {"name":"create_event","arguments":{"title":"Dentist",
                  "startsAt":"2026-09-10T08:30:00Z"}}
← {"resultType":"complete","content":[{"type":"text",
   "text":"Created e3: Dentist at 2026-09-10T08:30:00Z"}],
   "structuredContent":{"id":"e3","title":"Dentist","startsAt":"2026-09-10T08:30:00Z"},
   "isError":false}

Tiga method, tiga bentuk, satu kalender. Sekarang intinya:

Ia dialamatkan oleh URI, inert, dan aplikasi memutuskan apakah akan melampirkannya ke percakapan. Tidak ada dalam protokol yang memungkinkan model meraihnya sendiri. Result membawa ttlMs dan cacheScope, baru di revisi ini, sehingga client bisa cache minggu itu selama satu menit alih-alih polling.

Ia punya schema, punya side effect, dan model memutuskan kapan memanggilnya. Result-nya membawa isError, yaitu field yang diperjuangkan Chapter 18: kegagalan validasi kembali sebagai tool result yang bisa dibaca dan diperbaiki model, bukan sebagai protocol error.

Ia adalah template bernama yang menerima argument dan orang yang memanggilnya — slash command di menu. Ia mengembalikan messages, bukan jawaban. Ini adalah cara bagi penulis server untuk mengirimkan phrasing yang bekerja dengan tool mereka sendiri, yang memang merupakan pengetahuan yang dimiliki penulis server dan tidak dimiliki pengguna.

Hampir semua orang membuat ketiganya sebagai tools. Hasilnya adalah katalog tempat read yang seharusnya dilampirkan aplikasi secara senyap bersaing untuk attention model dengan write yang membutuhkan approval, dan tempat satu hal yang diinginkan orang sebagai tombol terkubur di dalam schema. Tidak ada biaya untuk membetulkannya, dan keputusan itu diambil sebelum kamu menulis satu baris pun.

Tool kalender punya satu argument wajib, title, dan satu startsAt opsional. Minta ia membuat event tanpa tanggal, dan sesuatu yang menarik kembali:

TEXT
→ tools/call {"name":"create_event","arguments":{"title":"Dentist"}}

← {"resultType":"input_required",
   "inputRequests":{"when":{"method":"elicitation/create","params":{"mode":"form",
     "message":"When should \"Dentist\" start?",
     "requestedSchema":{"type":"object",
       "properties":{"startsAt":{"type":"string","format":"date-time"}},
       "required":["startsAt"]}}}},
   "requestState":"eyJ0aXRsZSI6IkRlbnRpc3QifQ=="}

Server tidak mengirim request. Ia menjawab request yang diberikan kepadanya, dengan resultType: "input_required" dan deskripsi tentang apa yang masih ia butuhkan. Client mengumpulkan jawaban dari orangnya, lalu mengirim ulang call asli — dengan id baru, membawa inputResponses dan menggemakan kembali requestState yang opaque:

TEXT
→ tools/call {"name":"create_event","arguments":{"title":"Dentist"},
   "inputResponses":{"when":{"action":"accept",
     "content":{"startsAt":"2026-09-10T08:30:00Z"}}},
   "requestState":"eyJ0aXRsZSI6IkRlbnRpc3QifQ=="}

← {"resultType":"complete","content":[{"type":"text",
   "text":"Created e3: Dentist at 2026-09-10T08:30:00Z"}],"isError":false}

Ini adalah Multi Round-Trip Requests, diperkenalkan di revisi saat ini, dan menggantikan desain lama ketika server mengirim JSON-RPC requests balik ke client. Spesifikasi transport sekarang menyatakan aturannya secara tegas: "servers do not initiate JSON-RPC requests and clients do not send JSON-RPC responses".4 Hanya ada satu arah inisiatif, dan itu milik host.

Dua fitur sisi-client menumpang pada mekanisme itu, dan salah satunya punya nama yang akan menjegal kamu.

Elicitation adalah server meminta sesuatu kepada orang: form dengan JSON Schema yang sengaja dibatasi — objek flat, properti primitive, tanpa nesting — sehingga client mana pun bisa merendernya tanpa layout engine. Ia membawa aturan keras: server tidak boleh memakai mode form untuk meminta "passwords, API keys, access tokens, or payment credentials", dan harus memakai mode URL untuk itu, yang mengirim pengguna ke halaman yang tidak pernah dibaca client.7

Sampling adalah server meminta generation kepada model milik host, sehingga server bisa cerdas tanpa memegang API key. Dan inilah peringatan kosakata, karena kata ini sudah berarti hal lain dalam course ini: ini bukan sampling dari Chapter 17. Tidak ada di sini yang membahas temperature, top-p, atau bentuk probability distribution. Ini adalah nested model call yang bergerak mundur melalui protokol.

Ada alasan kedua untuk tidak buru-buru memakainya: pada revisi ini, sampling sudah deprecated, bersama roots dan logging, di bawah SEP-2577, dengan migrasi yang disarankan secara blak-blakan — "integrate directly with LLM provider APIs instead of Sampling".8 Idenya tidak gagal secara teknis; ia gagal membenarkan surface area-nya, dan protokol yang bisa menghapus sesuatu lebih sehat daripada protokol yang tidak bisa.

Rusakkan dengan sengaja: connections bukan sessions

Tautan ke bagian: Rusakkan dengan sengaja: connections bukan sessions

Statelessness terdengar seperti detail wire-format sampai kamu mengujinya. Ambil pertukaran tiga pesan di atas dan jalankan setiap pesan dalam proses terpisahnode calendar.mjs baru, tanpa shared memory, tidak ada yang dibawa:

TEXT
process A   tools/call (no date)   → resultType: input_required
                                     requestState: eyJ0aXRsZSI6IkRlbnRpc3QifQ==
process B   tools/call (with the answer, same requestState)
                                   → resultType: complete
                                     "Created e3: Dentist at 2026-09-10T08:30:00Z"
process C   resources/read calendar://week
                                   → events: 2  (Standup, Design review)

Process B, yang tidak pernah melihat pertanyaannya, menyelesaikan multi-round-trip call yang dimulai Process A. Itulah inti requestState: continuation berjalan di dalam pesan, sehingga tidak ada yang bergantung pada proses yang sama.

Process C adalah kegagalannya. Event dibuat dan tidak ada di sana — karena toy server menyimpan EVENTS di array level modul, dan array level modul adalah connection state. Catatan spesifikasi menamai kesalahan itu dengan tepat:

an open connection, such as a STDIO process, is not a conversation or session: clients may interleave unrelated requests on the same transport, and a server must not treat connection or process identity as a proxy for conversation or session continuity.2

Perbaikan yang ditentukan bukan session. Melainkan handle eksplisit: tool creation mengembalikan identifier opaque, dan setiap call berikutnya menerimanya sebagai argument biasa. Protokol sama sekali tidak punya konsep tentang itu — "from the wire's perspective a handle is an ordinary string in a tool result and an ordinary argument to subsequent tool calls".9 Itu menempatkan model sebagai pihak yang membawa handle, dan server sebagai pihak yang memvalidasi bahwa caller ini boleh memakainya pada setiap call, karena handle adalah nama, bukan permission.

Biaya sebuah server sebelum melakukan apa pun

Tautan ke bagian: Biaya sebuah server sebelum melakukan apa pun

Setiap tool yang diekspos server adalah schema yang masuk ke prompt kamu pada setiap request, dan Chapter 24 mengukur dampaknya pada window. MCP menambahkan item biaya kedua yang mudah terlewat, jadi keduanya layak dihitung pada server referensi di atas.

o200k_base tokensTEXT
13 tool definitions (name + description + inputSchema):  1,307 tokens
  cheapest tool, get-tiny-image                              52
  costliest tool, gzip-file-as-resource                     235
server `instructions`, returned by discovery:               312 tokens
                                                          ------
one server, connected, before it is used:                 1,619 tokens

Dua observasi. Yang pertama adalah aritmetika: hubungkan lima server sebesar ini dan sekitar delapan ribu token dari window kamu sudah terpakai di setiap turn, selamanya, baik model memakai salah satunya atau tidak — inilah mekanisme di balik pengurangan 150.000-ke-2.000 yang dikutip Chapter 24, dan alasan just-in-time tool discovery ada.

Yang kedua adalah catatan keamanan yang menyamar sebagai akuntansi. instructions adalah teks natural-language, ditulis oleh penulis server, yang mendarat di prompt host, dan deskripsi tool di sebelahnya sama. Spesifikasi mengatakan apa yang harus dilakukan terhadap itu dalam prinsip keamanannya sendiri: tool annotations dan descriptions "should be considered untrusted, unless obtained from a trusted server", dan host "must obtain explicit user consent before invoking any tool".1 Menghubungkan server MCP bukan menambahkan dependency. Itu memberi orang asing 1.619 token dari system prompt kamu dan hak untuk dipanggil. Chapter 30 adalah apa yang terjadi ketika orang asing itu hostile.

Bagian bertanggal: revisi 2026-07-28, dan apa yang dirusaknya

Tautan ke bagian: Bagian bertanggal: revisi 2026-07-28, dan apa yang dirusaknya

Semua di bagian ini benar untuk revisi protokol 2026-07-28, yang saat ini berlaku, dibaca pada 7 September 2026. Revisi diberi tanggal YYYY-MM-DD dan tanggalnya adalah terakhir kali perubahan backwards-incompatible dibuat.10 Dokumen normatifnya adalah file TypeScript, schema/2026-07-28/schema.ts; JSON Schema di sebelahnya dihasilkan darinya, itulah mengapa spesifikasi dibaca di sini dalam TypeScript dan mengapa mengajarkan MCP dari hal lain berarti mengajarkan terjemahan.

What changedWasIs nowBreaks
Handshakeinitialize + notifications/initialized, sekali per connectiondihapus; setiap request membawa versi dan capabilities _metasetiap client yang ditulis sebelum revisi ini
Sessionsheader Mcp-Session-Id, state scoped ke connectiondihapus; state berjalan dalam handle eksplisit yang dicetak serverendpoint list yang berubah per connection
Discoverydisimpulkan dari result initializeserver/discover, yang harus diimplementasikan servertidak ada, tetapi sekarang wajib diimplementasikan
Server-to-client callsserver mengirim roots/list, sampling/createMessage, elicitation/createInputRequiredResult dan retry oleh clientsetiap server yang mendorong request ke client
Result shapeobjek apa punwajib resultType: "complete" atau "input_required"tidak ada: field yang absen harus dibaca sebagai "complete"
Subscriptionsstream HTTP GET, resources/subscribesatu stream subscriptions/listen dengan tipe opt-inendpoint GET hilang
Stream resumptionreplay Last-Event-ID pada Streamable HTTPdihapus; stream yang putus kehilangan request, kirim ulang dengan id baruclient yang bergantung pada redelivery
Rootsfitur client yang bisa diminta serverdeprecated (SEP-2577); pass paths sebagai tool arguments atau resource URIsbelum ada — window dua belas bulan
Sampling and loggingfitur clientdeprecated (SEP-2577)belum ada — window dua belas bulan
HTTP+SSE transportdeprecated sejak 2025-03-26Deprecated di bawah lifecycle policy (SEP-2596)migrasi ke Streamable HTTP
Client registrationOAuth 2.0 Dynamic Client Registration, RFC 7591deprecated demi Client ID Metadata Documentsdipertahankan untuk authorization servers yang belum memilikinya
Error codes-32002 untuk resource not found-32602; -32020-32099 reserved untuk spesifikasicode baru -32020, -32021, -32022

Perubahan governance di bawah tabel itu lebih penting daripada baris mana pun. Revisi ini mengadopsi feature lifecycle and deprecation policy: fitur berstatus Active, Deprecated, atau Removed, fitur deprecated mendokumentasikan jalur migrasinya dan tetap berada di spesifikasi setidaknya dua belas bulan sebelum eligible untuk dihapus, dan ada registry yang mencantumkan semua yang saat ini berada dalam status Deprecated.8 Sebelum policy itu, "deprecated" dalam protokol AI berarti apa pun yang dikatakan blog post terakhir. Sekarang artinya tanggal.

Tampilkan detail

Extensions, bagian yang belum ditulis siapa pun.

Di luar core, MCP mendefinisikan extensions opsional — "always opt-in and require explicit support from both client and server", dideklarasikan melalui field extensions di capabilities client dan server.1 Tiga yang layak diketahui namanya:

  • Tasks (io.modelcontextprotocol/tasks), dipindahkan keluar dari core protocol menjadi extension resmi dalam revisi ini: eksekusi asynchronous untuk operasi yang berjalan lama, dengan polling melalui tasks/get, input saat masih berjalan melalui tasks/update, dan durable handles. Ini adalah jawaban untuk tool yang memakan dua puluh menit, yang di Chapter 23 ditangani dengan progress event dan signal yang mencapai tool.
  • Skills over MCP, working group yang membuat agent skills — subjek Chapter 28 — discoverable dan consumable melalui protokol.
  • MCP Apps, UI interaktif yang dirender inline di percakapan: charts, forms, video players.

Dan perhatikan apa arti "negotiated" sekarang: tidak ada initialization tempat melakukan negosiasi, jadi extension dideklarasikan per request seperti semua hal lainnya.

Posisi MCP dibanding hal-hal yang sering tertukar dengannya

Tautan ke bagian: Posisi MCP dibanding hal-hal yang sering tertukar dengannya

Ini kosakata untuk seluruh blok itu dalam satu tempat.

What it isWho talks to whomWhen it is the answer
A plain APIInterface untuk programkode kamu ↔ sebuah serviceKamu menulis caller-nya. Kamu mengontrol schema, auth, dan error handling, dan tidak ada masalah discovery yang perlu diselesaikan.
MCPProtokol untuk mengekspos tools, data, dan templates ke aplikasi AIhost ↔ server, masing-masing satu clientOrang lain menulis capability-nya dan banyak host harus bisa memakainya tanpa integrasi bespoke.
RAGTeknik untuk menemukan teks dan memasukkannya ke promptkode kamu ↔ index kamuModel perlu mengetahui sesuatu. Chapter 19. MCP adalah cara mengirimkan retriever; ia bukan retriever.
Agent skillsFolder dengan SKILL.md yang dibaca modelmodel ↔ dokumenPengetahuannya procedural — bagaimana kita melakukan ini — dan berbentuk prosa, bukan function. Chapter 28.
A2AProtokol agar agents berkolaborasi sebagai peeragent ↔ agentSisi lain bernalar, membuat plan, dan menyimpan state sepanjang tugas panjang, alih-alih menjawab call.
ACPDulunya protokol komunikasi agent terpisahIni bukan perbandingan live lagi. Lihat di bawah.

Dua di antaranya layak mendapat satu kalimat masing-masing, karena di situlah kebingungan sebenarnya terjadi.

MCP dibanding A2A bukan rivalitas, dan kedua spesifikasi mengatakannya begitu. Dokumentasi A2A menarik garis berdasarkan apa yang ada di ujung lain: MCP "defines how an AI agent interacts with and utilizes individual tools and resources, such as a database or an API", ketika tool menjalankan "specific, often stateless, functions"; A2A membahas agents, "more autonomous systems" yang "reason, plan, use multiple tools, maintain state over longer interactions, and engage in complex, often multi-turn dialogues". Ringkasannya sendiri adalah kalimat yang perlu diingat: "A2A is about agents partnering on tasks, while MCP is more about agents using capabilities."11 Keduanya bersarang — aplikasi memakai A2A untuk menjangkau agents lain, dan setiap agent memakai MCP untuk menjangkau tool-nya sendiri. Chapter 25 menggambar garis itu di dalam satu proses, antara meminta sub-agent dan menyerahkan percakapan kepadanya; A2A menggambarnya di antara organisasi.

MCP dibanding ACP adalah perbandingan dengan premis yang sudah basi, dan justru itulah mengapa layak dijawab. Agent Communication Protocol dulunya standar terbuka terpisah untuk messaging agent-to-agent. Dokumentasinya sendiri sekarang dibuka dengan pemberitahuan: "ACP is now part of A2A under the Linux Foundation!"12 Jawaban jujur untuk "MCP atau ACP?" pada September 2026 adalah bahwa pertanyaannya punya satu opsi lebih sedikit daripada yang disiratkan halaman-halaman yang ranking untuknya.

Dan perbandingan yang paling sering diminta orang, mcp vs api, punya jawaban paling tidak menarik: MCP adalah API. Yang ditambahkannya bukan power, melainkan conventions — kumpulan tetap method names, discovery call, hierarki kontrol atas primitive, dan model isolasi. Kamu menyerahkan kebebasan untuk mendesain interface sendiri dan mendapatkan setiap host yang berbicara protokol tersebut, trade yang selalu ditawarkan setiap protokol.

Sekarang kamu bisa membaca spesifikasi tanpa penerjemah, membedakan resource dari tool dari prompt berdasarkan siapa yang memegang kendali, mengetik request secara manual ketika client library berbohong, dan memberi tanggal pada artikel MCP mana pun yang kamu baca berdasarkan fitur deprecated mana yang masih diajarkannya sebagai current.

Yang belum kamu lakukan adalah mengirimkannya ke production. Chapter 27 menulis server yang sama dua kali — TypeScript dan Python, berdampingan, karena MCP adalah satu wilayah yang benar-benar bilingual dalam course ini dan angkanya mengatakan begitu di dua arah. Bab itu membahas dua transport live dengan benar, inspector, packaging, dan separuh protokol yang sengaja ditinggalkan bab ini: authorization. Karena begitu server kamu remote, bukan subprocess di laptop kamu sendiri, client milik orang asing akan menyodorkan token, dan aturan spesifikasi tentang apa yang boleh kamu lakukan dengannya luar biasa ketat.

Yang memunculkan pertanyaan yang harus dijawab bab berikutnya, dan ini bukan pertanyaan yang ramah: jika token tiba di server kamu dan token itu diterbitkan untuk audience milik orang lain, apa tepatnya yang menghentikan kamu untuk meneruskannya?


Setiap kutipan, method name, error code, dan aturan dalam bab ini dibaca dari spesifikasi Model Context Protocol, revisi 2026-07-28, pada 7 September 2026. Setiap trace diproduksi lokal di Node 22: toy calendar server adalah 101 baris tanpa dependency, dan server referensi adalah npm package yang dipublikasikan dengan nama di bawah. Tidak ada API berbayar yang dipanggil untuk menulis bab ini — tidak ada di sini yang membutuhkan model, dan itu sendiri adalah intinya.

Pengukuran: @modelcontextprotocol/server-everything@2026.8.31, dipublikasikan 31 Agustus 2026, dibangun di atas @modelcontextprotocol/sdk@1.30.0, dipublikasikan 27 Juli 2026 — satu hari sebelum revisi yang dijelaskan bab ini. Ia menjawab server/discover dengan -32601, menegosiasikan 2025-11-25 ketika diminta 2026-07-28, dan melayani tools/list tanpa handshake sama sekali. Katalognya berisi 13 tools dalam 7.663 byte; token count adalah o200k_base via tiktoken, atas name, description, dan inputSchema dari setiap definition, yaitu apa yang dirender provider ke prompt kamu dan bukan bobot JSON-RPC frame.

Anthropic, Code execution with MCP: building more efficient agents, 4 November 2025, adalah sumber angka 150.000-ke-2.000, dikutip dan digunakan di Chapter 24 dan hanya dirujuk di sini.

  1. Specification, modelcontextprotocol.io/specification/latest (redirecting to /2026-07-28), dibaca 7 September 2026. Sumber perbandingan Language Server Protocol; pernyataan bahwa spesifikasi "based on the TypeScript schema in schema.ts"; ringkasan base-protocol ("Stateless, self-contained requests", "Per-request capability negotiation"); daftar extension (Tasks, Skills over MCP, MCP Apps) dan pernyataan bahwa extensions "are always opt-in and require explicit support from both client and server"; serta prinsip Security and Trust & Safety, termasuk "Hosts must obtain explicit user consent before invoking any tool" dan perlakuan tool annotations sebagai untrusted. 2 3

  2. Base Protocol, modelcontextprotocol.io/specification/2026-07-28/basic. Sumber batasan JSON-RPC (id non-null, tidak ada reuse id, resultType wajib); bagian Statelessness dan catatannya bahwa proses stdio terbuka bukan session; tabel reserved-key _meta dan status wajib/opsional setiap field per-request; aturan -32602 untuk field wajib yang hilang; aturan MissingRequiredClientCapability (-32021); serta policy alokasi error-code. 2 3 4 5

  3. stdio transport, modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio. Sumber aturan framing newline-delimited, persyaratan purity stdout, allowance stderr, dan probe backward-compatibility tiga hasil — termasuk peringatan bahwa beberapa legacy servers memproses method era-ambiguous tanpa handshake, yang direproduksi pengukuran dalam bab ini. 2 3

  4. Transports overview, modelcontextprotocol.io/specification/2026-07-28/basic/transports. Sumber framing "a transport is a binding" dan pernyataan bahwa server tidak menginisiasi JSON-RPC requests dan client tidak mengirim JSON-RPC responses. 2

  5. Discovery, modelcontextprotocol.io/specification/2026-07-28/server/discover. Sumber status wajib server/discover, bentuk DiscoverResult, dan field instructions yang dijelaskan sebagai "optional natural-language guidance for LLMs on how to use this server effectively".

  6. Architecture, modelcontextprotocol.io/specification/2026-07-28/architecture. Sumber definisi host/client/server, aturan client-to-server 1:1, empat prinsip desain, yang prinsip isolasinya dikutip di sini tanpa bullet kelima, "Host process enforces security boundaries", dan bagian capability-negotiation. 2

  7. Elicitation, .../client/elicitation, dan Sampling, .../client/sampling. Sumber dua mode elicitation dan schema terbatasnya; larangan meminta credentials melalui mode form; definisi sampling, persyaratan human-in-the-loop, dan peringatan deprecation yang melekat padanya.

  8. Key Changes, modelcontextprotocol.io/specification/2026-07-28/changelog, dan Feature lifecycle and deprecation policy, .../community/feature-lifecycle. Sumber setiap baris tabel perubahan: penghapusan sessions dan header Mcp-Session-Id (SEP-2567); statelessness dan penghapusan initialize (SEP-2575); server/discover (SEP-2575); subscriptions/listen (SEP-2575); Multi Round-Trip Requests dan resultType (SEP-2322); penghapusan stream resumability (SEP-2575); deprecation Roots, Sampling, dan Logging (SEP-2577); reklasifikasi HTTP+SSE (SEP-2596); deprecation Dynamic Client Registration demi Client ID Metadata Documents; penomoran ulang error-code; dan window deprecation dua belas bulan. 2

  9. Tools, modelcontextprotocol.io/specification/2026-07-28/server/tools, dan Server Features, .../server. Sumber tabel hierarki kontrol yang direproduksi di atas; bentuk tools/list dan tools/call; perbedaan isError antara protocol errors dan tool execution errors; aturan tool-name dan catatan namespace yang merekomendasikan "prefixing tool names with a server identifier"; serta panduan non-normatif "Stateful Tools" tentang handle eksplisit.

  10. Versioning, modelcontextprotocol.io/specification/versioning. Sumber skema YYYY-MM-DD, status revisi Draft/Current/Final, konfirmasi bahwa 2026-07-28 adalah current, dan aturan negosiasi per-request. Tabel tier SDK di modelcontextprotocol.io/docs/sdk mencantumkan TypeScript, Python, C#, Go, dan Rust di Tier 1, Java dan Ruby di Tier 2, serta Swift, PHP, dan Kotlin di Tier 3.

  11. A2A Protocol, version 1.0.0, a2a-protocol.org — spesifikasi dan halaman A2A and MCP: Relationship and Distinction, dibaca 7 September 2026. Sumber perbedaan tools-against-agents, pernyataan bahwa kedua protokol "address distinct but highly complementary needs", dan formulasi partnering/using.

  12. Agent Communication Protocol, agentcommunicationprotocol.dev, dibaca 7 September 2026: "ACP is now part of A2A under the Linux Foundation!", banner yang ditambahkan di atas spesifikasi yang masih disajikan utuh — architecture, agent manifest, agent discovery, message structure, stateful agents, run lifecycle, dan daftar REST endpoint semuanya masih menjawab 200. Spesifikasinya tidak hilang; proyeknya yang hilang.


Dibuat oleh

David Vicente Campos

Pendiri NeuraLIA Labs & salah satu pendiri MyRealFood

Saya seorang insinyur komputer lulusan Universitas León. Saya ikut mendirikan MyRealFood, tempat saya sebagai CTO membangun aplikasi yang telah digunakan jutaan orang untuk makan lebih sehat, dan saya mendirikan NeuraLIA Labs, tempat saya membangun produk AI. Di sini saya menulis tentang hal-hal yang harus saya pahami sepanjang perjalanan, sebagaimana dulu saya berharap ada yang menjelaskannya kepada saya.

Selengkapnya tentang penulis

Diterbitkan oleh NeuraLIA Labs.

Dapatkan postingan baru di inbox kamu

Berita AI, panduan, dan update produk — email singkat saat kami menerbitkan sesuatu yang layak kamu baca.

Indeks kursus

Abstract software decision engine with branching paths, probability nodes, and glowing gates.
jev11 menit baca

Model AI Jev dibuat untuk keputusan, bukan prosa

Jev dari TypeSafe AI menarik perhatian karena memperlakukan kecerdasan software sebagai persoalan probabilitas: pilih cabang yang tepat, sertakan keyakinan, dan hindari membayar LLM untuk menulis teks saat kode membutuhkan keputusan.

Abstract agent runtime sorting documents, memory blocks and pointer nodes inside a bounded context frame.
context-engineering11 menit baca

Rekayasa konteks untuk agen AI jangka panjang

Agen yang berjalan lama tidak gagal hanya karena window-nya kecil. Mereka gagal ketika file, output tool, dan riwayat lama menggeser tugas yang seharusnya diselesaikan agen.

Siap membiarkan LIA yang memilih?

Berkarya dengan semua model AI dalam satu tempat — mulai gratis hari ini.