Lompat ke isi halaman
TechVerse X
AI AgentsDraf — belum diperiksa manusia

Model Context Protocol

Langkah belajar
12
Alat
4
Proyek mini
2
Sumber
15

Diperbarui 9 Oktober 2026

Overview

Bayangkan setiap aplikasi AI harus membuat kabel khusus untuk setiap sistem yang ingin disambungkannya: satu untuk berkas, satu untuk basis data, satu untuk kalender. Model Context Protocol (MCP) menggantikan kabel-kabel itu dengan satu colokan baku, mirip port USB-C. Sebuah sistem cukup menyediakan satu server MCP, dan aplikasi AI apa pun yang berbicara MCP bisa memakainya. Aplikasi itu disebut host (misalnya Claude Code atau Visual Studio Code), dan di dalamnya ada satu client untuk setiap server. Server menawarkan tiga hal: tools (fungsi yang bisa dipanggil model), resources (data untuk konteks), dan prompts (templat interaksi). Pesannya berformat JSON-RPC 2.0 dan berjalan lewat stdio untuk server lokal atau Streamable HTTP untuk server jarak jauh. Sejak revisi spesifikasi 2026-07-28, MCP tak lagi memakai sesi: tak ada jabat tangan initialize, dan setiap permintaan membawa sendiri versi protokol serta kapabilitas kliennya. Halaman ini mengajakmu memahami cara berpikir MCP dan membangun server sendiri. Spesifikasinya masih terus bergerak, jadi cocokkan selalu contoh yang kamu temukan dengan revisi terbaru.

Kenapa butuh colokan bersama

Misalkan kamu membuat aplikasi AI dan ingin ia bisa membaca berkas, menanyai basis data, dan melihat kalender. Tanpa standar, kamu menulis penyambung khusus untuk masing-masing. Lalu tim lain yang membuat aplikasi AI berbeda menulis penyambung yang sama sekali lagi. Sepuluh aplikasi dan sepuluh sistem bisa berarti seratus penyambung yang dikerjakan berulang-ulang.

Model bahasa sendiri hanya tahu apa yang ada di data latihnya dan di konteks yang diberikan kepadanya. Supaya bisa bekerja dengan dunia nyata, ia perlu disambungkan. MCP memberi satu bentuk sambungan untuk semuanya: sebuah sistem cukup menyediakan satu server MCP, dan aplikasi apa pun yang berbicara MCP bisa langsung memakainya.

Dokumentasi resminya memakai analogi port USB-C: satu colokan untuk perangkat yang berbeda-beda. Spesifikasinya sendiri menyebut sumber ilhamnya, yaitu Language Server Protocol, yang dulu membakukan cara alat pengembang mendukung berbagai bahasa pemrograman.

Kalau kamu sudah membaca topik Tool use, posisinya mudah diingat. Tool use adalah cara model memakai tool; MCP adalah cara baku menyediakan tool, dan lebih dari itu, dari luar aplikasi.

Tiga peran: host, client, server

Diagram: kotak Host berisi Client 1, 2, dan 3. Client 1 tersambung ke Server A (berkas, stdio) dan Client 2 ke Server B (basis data, stdio), keduanya di mesin yang sama. Client 3 tersambung ke Server C (web, Streamable HTTP) di internet.
Satu host, satu client per server. Diringkas dari diagram arsitektur di spesifikasi MCP revisi 2026-07-28.Lisensi: Karya sendiri

Ada tiga pemain di MCP, dan bisa membedakan mereka sudah separuh jalan untuk memahaminya.

  • Host adalah aplikasi AI yang dipakai orang, seperti Claude Code atau Visual Studio Code. Ia membuat dan mengelola client, memegang seluruh percakapan, meminta persetujuan pengguna, dan memutuskan apa yang boleh dilihat tiap server.
  • Client adalah komponen di dalam host. Satu client berbicara dengan tepat satu server, dan di setiap permintaan ia melampirkan versi protokol serta kapabilitasnya, yaitu kemampuan yang ia dukung.
  • Server adalah program yang menyediakan konteks dan kemampuan. Ia bisa berupa proses lokal yang dijalankan host lewat stdio (jalur masukan dan keluaran standar sebuah proses), atau layanan jarak jauh lewat Streamable HTTP.

Contoh dari dokumentasi resmi: Visual Studio Code yang tersambung ke server Sentry (jarak jauh) dan server filesystem (lokal) memegang dua client, satu untuk setiap server.

Catatan

Ada satu prinsip desain yang paling menentukan: server tak boleh membaca seluruh percakapan dan tak bisa "mengintip" server lain. Riwayat percakapan tinggal di host; server hanya menerima yang perlu ia ketahui.

Dua lapis: isi surat dan jasa pengirimannya

Diagram: lapis transport sebagai kotak luar (pembingkaian pesan, koneksi, otorisasi) dengan dua pilihan, stdio dan Streamable HTTP. Di dalamnya lapis data JSON-RPC 2.0 berisi server/discover, primitif server, elicitation lewat MRTR, dan notifikasi.
Lapis data menentukan isi pesan; lapis transport menentukan jalannya.Lisensi: Karya sendiri

Bayangkan sebuah surat. Lapis data adalah isi suratnya: pesan JSON-RPC 2.0 beserta maknanya, yaitu penemuan versi dan kapabilitas, primitif, dan notifikasi. Lapis transport adalah jasa pengirimannya: bagaimana pesan dibingkai, dikirim lewat koneksi, dan diotorisasi. Karena keduanya terpisah, surat yang sama persis bisa dikirim lewat stdio maupun HTTP.

Primitif: apa yang ditawarkan, dan siapa yang memutuskan

Hal-hal yang ditawarkan lewat MCP disebut primitif. Yang paling berguna untuk diingat bukan hanya namanya, melainkan siapa yang memutuskan kapan masing-masing dipakai:

PrimitifDisediakanYang memutuskan dipakaiMetode
Toolsservermodel, dengan manusia yang bisa menolaktools/list, tools/call
Resourcesserveraplikasi (host)resources/list, resources/read
Promptsserverpengguna, mis. lewat perintah garis miringprompts/list, prompts/get
Elicitationclientserver meminta, pengguna menjawabelicitation/create

Tiga fitur lain kini berstatus deprecated sejak revisi 2026-07-28, artinya masih berfungsi tetapi tak dianjurkan untuk implementasi baru. Ketiganya adalah Sampling dan Roots di sisi client, serta utilitas Logging, dan paling cepat dihapus pada revisi yang terbit 2027-07-28 atau sesudahnya. Spesifikasi sudah menyiapkan penggantinya:

  • ganti Sampling dengan memanggil API penyedia LLM langsung;
  • ganti Roots dengan folder atau berkas yang dikirim lewat parameter tool, URI resource, atau konfigurasi server;
  • ganti Logging dengan log ke stderr (stdio) atau OpenTelemetry.

Revisi 2026-07-28: protokol tanpa sesi

Kalau kamu menemukan tutorial MCP yang dimulai dengan jabat tangan initialize, kemungkinan besar ia ditulis sebelum revisi ini. Inilah perubahan terbesar sejak MCP dibuka, dan banyak tutorial, video, serta SDK lama masih menggambarkan cara sebelumnya.

Dulu client dan server berkenalan sekali di awal, lalu mengandalkan sesi untuk saling mengingat. Kini setiap permintaan membawa "kartu identitasnya" sendiri, sehingga server tak perlu mengingat apa pun di antara permintaan.

Dua diagram urutan. Atas, sampai revisi 2025-11-25: initialize, jawaban versi dan kapabilitas, notifications/initialized, lalu tools/call dengan konteks di sesi. Bawah, revisi 2026-07-28: server/discover opsional, lalu tools/call yang membawa versi, kapabilitas, dan clientInfo di _meta, dijawab resultType complete.
Sejak 2026-07-28 tak ada jabat tangan: konteks berpindah dari koneksi ke setiap permintaan.Lisensi: Karya sendiri
Dulu (sampai 2025-11-25)Kini (2026-07-28)
Jabat tangan initialize lalu notifications/initializedSetiap permintaan membawa versi dan kapabilitas client di _meta
Sesi HTTP lewat header Mcp-Session-IdTak ada sesi; keadaan lintas panggilan memakai pegangan eksplisit buatan server
Server mengirim permintaan ke client (sampling/createMessage, elicitation/create)Server membalas InputRequiredResult, client mengulang permintaannya dengan jawaban (MRTR)
resources/subscribe dan aliran HTTP GETSatu aliran subscriptions/listen yang memilih jenis notifikasinya
ping dan logging/setLevelDihapus; tingkat log dikirim per permintaan di _meta
Hasil tanpa penanda jenisSetiap hasil wajib membawa resultType: complete atau input_required

Setiap server wajib menjawab server/discover dengan versi yang didukung, kapabilitas, dan identitasnya. Client boleh memanggilnya lebih dulu, tetapi tak harus. Ia boleh langsung mengirim permintaan apa pun dan menangani UnsupportedProtocolVersionError (kode -32022), yang menyebut versi-versi yang didukung server.

Begini rupa satu pemanggilan tool sekarang. Perhatikan _meta, tempat versi dan kapabilitas client dibawa:

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "location": "New York" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {
        "name": "ExampleClient",
        "version": "1.0.0"
      },
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

Dan inilah jawabannya. resultType menandai bahwa hasilnya sudah lengkap:

json
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
      }
    ],
    "isError": false
  }
}

Catatan

Masa peralihan ini bisa dilewati dengan mulus. Server boleh melayani client lama dan baru sekaligus ("dua era"). Client yang perlu menyambung ke server lama di stdio dianjurkan mengirim server/discover lebih dulu, lalu kembali ke initialize bila jawabannya bukan galat modern yang dikenal.

Mengikuti satu pertanyaan

Supaya semuanya terasa nyata, mari ikuti satu pertanyaan dari awal sampai akhir. Pengguna mengetik di host: "Ada peringatan cuaca di California?"

  1. Host sudah tahu daftar tool server cuaca dari tools/list, dan menyertakannya ke model.
  2. Model memilih memanggil get_alerts dengan argumen {"state": "CA"}.
  3. Host menampilkan pemanggilan itu. Spesifikasi menganjurkan agar pengguna selalu bisa menolaknya.
  4. Client mengirim tools/call ke server, lengkap dengan _meta.
  5. Server menjawab dengan content berisi teks peringatan. Host meneruskannya ke model, yang lalu menyusun jawaban.

Perhatikan bahwa model tak pernah berbicara langsung dengan server. Semuanya lewat host, dan justru di sanalah persetujuan, kebijakan, dan batas keamanan dijalankan.

Siapa yang merawat MCP

Anthropic membuka MCP pada November 2024. Pada 9 Desember 2025, Anthropic mendonasikannya ke Agentic AI Foundation (AAIF), dana terarah di bawah Linux Foundation yang didirikan bersama Anthropic, Block, dan OpenAI. Saat itu Anthropic mencatat lebih dari 10.000 server MCP publik yang aktif, dan MCP sudah dipakai di ChatGPT, Cursor, Gemini, Microsoft Copilot, dan Visual Studio Code.

Beberapa hal lain yang berguna diketahui sebelum mulai membangun:

  • SDK resminya bertingkat. Tier 1: TypeScript, Python, C#, Go, Rust, dan Ruby. Tier 2: Java. Tier 3: Swift, PHP, dan Kotlin.
  • SDK TypeScript v2 (paket @modelcontextprotocol/server dan @modelcontextprotocol/client) dirilis 27 Juli 2026 dan mengimplementasikan revisi 2026-07-28. Versi 1.x (@modelcontextprotocol/sdk) tetap menerima perbaikan setidaknya enam bulan sesudahnya. Jadi saat menyalin contoh dari internet, cek dulu versi SDK dan revisi protokolnya.
  • Fitur di luar inti datang sebagai ekstensi yang dinegosiasikan lewat kapabilitas, misalnya Tasks (io.modelcontextprotocol/tasks: operasi panjang dengan pegangan yang bisa ditanyai) dan MCP Apps (io.modelcontextprotocol/ui: antarmuka interaktif di dalam percakapan).

Dengar dari pembuatnya

Dua video dari kanal resmi Anthropic ini menceritakan mengapa MCP dirancang seperti sekarang. Keduanya direkam sebelum revisi 2026-07-28, jadi detail protokol di dalamnya (jabat tangan, sesi) sudah berubah, tetapi gagasan dasarnya tetap berlaku.

Tonton di YouTube
Theo Chu, David Soria Parra, dan Alex Albert membahas komponen inti MCP, awal mulanya, dan kiat memulai (19 menit, Juni 2025 — sebelum revisi tanpa sesi).Sumber: Anthropic di YouTube · Lisensi: Lisensi standar YouTube; disematkan lewat pemutar YouTube
Tonton di YouTube
Stuart Ritchie berbincang dengan David Soria Parra, salah satu pencipta MCP, tentang masalah yang dipecahkan, kritik terhadap MCP, dan donasinya ke Linux Foundation (35 menit, Desember 2025).Sumber: Anthropic di YouTube · Lisensi: Lisensi standar YouTube; disematkan lewat pemutar YouTube

Hal yang perlu diingat

  • MCP tidak membuat tool aman dengan sendirinya. Tool berarti kode yang benar-benar berjalan, dan deskripsi serta anotasi tool dari server yang tak tepercaya harus dianggap tak tepercaya juga.
  • Protokol tak bisa memaksakan persetujuan pengguna; itu tanggung jawab host. Spesifikasi menganjurkan (SHOULD) agar selalu ada manusia yang bisa menolak pemanggilan tool.
  • Server lokal berjalan dengan hak akses yang sama dengan client yang menjalankannya.

Learning Roadmap

  1. Prasyarat

    Yang perlu kamu kenal dulu: JSON-RPC 2.0 dan JSON Schema

    Ada dua hal yang sebaiknya sudah akrab bagimu, karena keduanya persis yang lewat di kabel MCP.

    • JSON-RPC 2.0 adalah format sederhana untuk memanggil fungsi lewat pesan JSON. Sebuah request punya id, method, dan params. Response membawa result atau error dengan id yang sama, sehingga kamu tahu jawaban mana untuk permintaan mana. Notification tak punya id dan tak dijawab. MCP menambah satu aturan: id tak boleh null.
    • JSON Schema adalah cara baku menuliskan bentuk data: type, properties, required. Untuk inputSchema dan outputSchema tool, MCP memakai dialek 2020-12 secara bawaan.

    Semuanya akan lebih mudah bila kamu sudah membaca topik Tool use, atau pernah memanggil LLM lewat API dengan function calling. MCP adalah cara baku menyediakan fungsi-fungsi itu dari luar aplikasi.

  2. 1

    Gambar sendiri peta host, client, dan server

    Cara terbaik memahami arsitektur MCP adalah menggambarnya sendiri. Lihat diagram ini, lalu gambar ulang dengan tanganmu sampai kamu bisa menjelaskannya tanpa melihat:

    Diagram: kotak Host berisi Client 1, 2, dan 3. Client 1 tersambung ke Server A (berkas, stdio) dan Client 2 ke Server B (basis data, stdio), keduanya di mesin yang sama. Client 3 tersambung ke Server C (web, Streamable HTTP) di internet.
    Satu host, satu client per server. Diringkas dari diagram arsitektur di spesifikasi MCP revisi 2026-07-28.Lisensi: Karya sendiri

    Saat menggambar, pastikan tiga hal ini terlihat:

    1. Satu host membuat satu client untuk setiap server.
    2. Server lokal (stdio) biasanya melayani satu client, sedangkan server jarak jauh (Streamable HTTP) melayani banyak client.
    3. Riwayat percakapan tinggal di host. Server hanya menerima yang perlu, dan tak bisa melihat server lain.

    Bedakan juga dua lapisnya: data (JSON-RPC dan primitif) dan transport (stdio atau HTTP, pembingkaian, otorisasi).

    Tips

    Coba jawab: Visual Studio Code tersambung ke server filesystem dan server Sentry. Ada berapa client? Dua, satu untuk setiap server.

  3. 2

    Kenali primitif dan siapa yang mengendalikannya

    Ketiga primitif server tampak mirip, tetapi dikendalikan pihak yang berbeda, dan perbedaan itu menentukan cara kamu merancangnya.

    • Tools dikendalikan model. Model memilih memanggilnya, lalu host meminta persetujuan.
    • Resources dikendalikan aplikasi. Host yang memutuskan data mana masuk konteks, misalnya lewat pemilih berkas. Setiap resource dikenali lewat URI seperti file:///project/src/main.rs.
    • Prompts dikendalikan pengguna, dan biasanya muncul sebagai perintah garis miring.

    Semua primitif ditemukan saat aplikasi berjalan lewat metode list-nya (tools/list, resources/list, prompts/list), bukan dari konfigurasi tetap, sehingga daftarnya boleh berubah. Server yang menyatakan listChanged memberi tahu perubahan itu kepada client yang membuka aliran subscriptions/listen.

    Di sisi client, hanya Elicitation yang dianjurkan untuk implementasi baru: server meminta masukan dari pengguna, misalnya konfirmasi sebelum sebuah tindakan. Sampling dan Roots, juga utilitas Logging, kini deprecated.

    Latihan: pilih satu sistem yang kamu kenal, misalnya aplikasi catatan. Tulis dua tool, satu resource, dan satu prompt untuknya, lalu tandai siapa yang seharusnya memutuskan masing-masing dipakai.

  4. 3

    Baca kartu identitas di setiap permintaan: _meta dan server/discover

    Karena tak ada lagi jabat tangan, setiap permintaan harus memperkenalkan dirinya sendiri. Perkenalan itu ditaruh di _meta:

    Kunci di _metaWajib
    io.modelcontextprotocol/protocolVersionya
    io.modelcontextprotocol/clientCapabilitiesya
    io.modelcontextprotocol/clientInfodianjurkan
    io.modelcontextprotocol/logLeveltidak

    Permintaan yang tak membawa kunci wajib ditolak dengan -32602 (di HTTP: status 400). Bila server butuh kapabilitas yang tak dinyatakan client, ia menjawab -32021 sambil menyebut kapabilitas yang kurang. Server pun sebaiknya memperkenalkan diri di _meta setiap hasil (io.modelcontextprotocol/serverInfo).

    Dua diagram urutan. Atas, sampai revisi 2025-11-25: initialize, jawaban versi dan kapabilitas, notifications/initialized, lalu tools/call dengan konteks di sesi. Bawah, revisi 2026-07-28: server/discover opsional, lalu tools/call yang membawa versi, kapabilitas, dan clientInfo di _meta, dijawab resultType complete.
    Sejak 2026-07-28 tak ada jabat tangan: konteks berpindah dari koneksi ke setiap permintaan.Lisensi: Karya sendiri

    server/discover wajib ada di setiap server, tetapi client tak wajib memanggilnya. Jawabannya memuat supportedVersions, capabilities, serta petunjuk cache ttlMs dan cacheScope.

    Peringatan

    clientInfo dan serverInfo diisi sendiri oleh pengirimnya dan tidak diverifikasi protokol. Pakai untuk tampilan dan log, jangan untuk keputusan keamanan.

  5. 4

    Bangun server stdio pertama dengan SDK resmi

    Saatnya membangun. Tutorial resmi Build an MCP server mengajakmu membuat server cuaca dengan dua tool, get_alerts dan get_forecast. Kerangkanya dengan SDK Python seperti ini:

    python
    from mcp.server import MCPServer
    
    mcp = MCPServer("weather")
    
    @mcp.tool()
    async def get_alerts(state: str) -> str:
        """Get weather alerts for a US state.
    
        Args:
            state: Two-letter US state code (e.g. CA, NY)
        """
        ...
    
    if __name__ == "__main__":
        mcp.run(transport="stdio")

    Yang menarik, petunjuk tipe dan docstring di atas adalah skemanya: dari state: str, SDK membuat inputSchema sendiri. Di TypeScript, padanannya McpServer dari paket @modelcontextprotocol/server, dengan registerTool dan skema Zod.

    Peringatan

    Di server stdio, jangan pernah menulis ke stdout selain pesan protokol. print() di Python atau console.log() di Node akan merusak aliran JSON-RPC. Tulis log ke stderr.

    Pesan stdio dipisahkan baris baru dan tak boleh memuat baris baru di dalamnya. Host menghentikan servermu dengan menutup stdin, jadi pastikan servermu keluar dengan rapi saat stdin habis.

  6. 5

    Intip isi pesannya dengan MCP Inspector

    Begitu server berjalan, kamu pasti ingin melihat apa yang sebenarnya terjadi. Untuk itulah ada MCP Inspector, alat pengembang rujukan: satu paket dengan tiga antarmuka, yaitu web, CLI, dan TUI (antarmuka di terminal). Ia butuh Node 22.19.0 atau lebih baru.

    bash
    # antarmuka web, tersambung ke server stdio hasil build TypeScript
    npx @modelcontextprotocol/inspector node build/index.js
    
    # CLI: daftar tool lalu keluar — cocok untuk skrip dan CI
    npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list
    
    # antarmuka terminal
    npx @modelcontextprotocol/inspector --tui node build/index.js

    Untuk server Python dari SDK resmi, uv run mcp dev server.py langsung membukanya di Inspector.

    Kirim tools/list, lalu tools/call, dan baca pesan mentahnya di panel pemantau. Kamu akan melihat bahwa setiap permintaan membawa _meta-nya sendiri dan setiap hasil membawa resultType. Melihat JSON yang benar-benar lewat adalah cara tercepat memahami apa yang selama ini disembunyikan SDK darimu.

    Catatan

    Inspector menyimpan status OAuth di disk. Perlakukan ia sebagai alat pengembangan di mesinmu sendiri, bukan layanan yang dibagikan.

  7. 6

    Rancang tool yang mudah dipakai model

    Model hanya melihat tiga hal dari tool-mu: nama, deskripsi, dan skema. Ketiganya adalah wajah tool-mu, jadi rancang dengan cermat.

    • Nama: 1–128 karakter; huruf, angka, _, -, dan .; peka huruf besar-kecil; unik di dalam server.
    • Deskripsi: apa yang dilakukan, dan kapan dipakai.
    • inputSchema: JSON Schema. Untuk tool tanpa parameter, anjurannya {"type": "object", "additionalProperties": false}.
    • outputSchema (opsional): bila ada, server wajib mengembalikan structuredContent yang sesuai, dan sebaiknya juga salinannya sebagai teks.

    Galat juga perlu dirancang. MCP membedakan dua jenis, masing-masing dengan jalannya sendiri:

    GalatContohDikirim sebagai
    Protokoltool tak dikenal, permintaan cacaterror JSON-RPC, mis. -32602
    Eksekusitanggal di masa lalu, API hilir gagalhasil biasa dengan isError: true
    json
    {
      "resultType": "complete",
      "content": [
        {
          "type": "text",
          "text": "Invalid departure date: must be in the future."
        }
      ],
      "isError": true
    }

    Kenapa dibedakan? Galat eksekusi diteruskan ke model supaya ia bisa memperbaiki panggilannya sendiri, misalnya memilih tanggal lain. Galat protokol jarang bisa diperbaiki model. Satu kiat kecil: kembalikan tools/list dalam urutan yang tetap, supaya client bisa menyimpannya dan prompt cache LLM lebih sering kena.

  8. 7

    Sambungkan ke host sungguhan dan biarkan manusia tetap memegang kendali

    Server yang hanya diuji di Inspector belum benar-benar hidup. Tutorial resmi memakai Claude for Desktop sebagai host. Daftarkan servermu di claude_desktop_config.json (di Windows: $env:AppData\Claude\claude_desktop_config.json), di bawah kunci mcpServers:

    json
    {
      "mcpServers": {
        "weather": {
          "command": "uv",
          "args": ["--directory", "/JALUR/ABSOLUT/weather", "run", "weather.py"]
        }
      }
    }

    Mulai ulang host, minta sesuatu yang membutuhkan tool-mu, lalu amati kapan model memilih memanggilnya.

    Spesifikasi menganjurkan agar selalu ada manusia yang bisa menolak pemanggilan tool. Karena itu aplikasi sebaiknya:

    • menampilkan tool mana yang terpapar ke model,
    • menandai dengan jelas saat tool dipanggil,
    • meminta konfirmasi untuk operasi yang berdampak.

    Cari di host-mu di mana ketiganya terlihat. Bagian ini tak bisa dipaksakan oleh protokol; ia tanggung jawab host.

  9. 8

    Ingat keadaan tanpa sesi: pegangan eksplisit dan MRTR

    Tanpa sesi, bagaimana server mengingat keranjang belanja yang baru dibuat? Di MCP, koneksi, bahkan proses stdio sekalipun, bukan percakapan. Ada dua pola yang menggantikan sesi.

    1. Pegangan eksplisit. Mirip nomor tiket penitipan barang: tool pembuat mengembalikan ID, dan tool lain menerimanya sebagai argumen biasa.

    jsonc
    // → tools/call
    { "name": "create_basket", "arguments": {} }
    // → tools/call berikutnya
    {
      "name": "add_item",
      "arguments": { "basket_id": "bsk_a1b2c3", "sku": "..." }
    }

    Buat pegangan acak yang tak bisa ditebak (misalnya UUIDv4), tulis umurnya di deskripsi tool, dan kembalikan galat eksekusi yang jelas untuk pegangan kedaluwarsa, supaya model tahu ia perlu membuat yang baru.

    2. Multi Round-Trip Requests (MRTR). Kadang server butuh masukan pengguna di tengah tools/call, resources/read, atau prompts/get. Alih-alih bertanya langsung, ia membalas InputRequiredResult, lalu client mengulang permintaannya dengan jawaban pengguna:

    Diagram urutan antara Pengguna, Client, dan Server: tools/call id 1; server menjawab InputRequiredResult dengan inputRequests dan requestState; client bertanya kepada pengguna dan menerima accept; client mengulang tools/call id 2 dengan inputResponses dan requestState; server menjawab resultType complete.
    Multi Round-Trip Requests menggantikan permintaan dari server ke client. Diringkas dari halaman MRTR di spesifikasi revisi 2026-07-28.Lisensi: Karya sendiri

    requestState adalah teks buram milik server, dan client wajib mengembalikannya apa adanya. Permintaan ulang wajib memakai id JSON-RPC yang baru.

  10. 9

    Amankan servermu: validasi, token, dan sikap waspada

    Server MCP menjalankan kode atas permintaan model, jadi keamanannya tak boleh jadi urusan belakangan. Spesifikasi mewajibkan (MUST) empat hal di sisi server: validasi semua masukan tool, kendalikan akses, batasi laju pemanggilan, dan bersihkan keluaran. Panduan keamanan resmi lalu menyebut empat jebakan:

    • Token passthrough. Server hanya boleh menerima token yang diterbitkan untuknya (periksa audiensnya) dan tak boleh meneruskan token itu ke API hilir. Butuh API lain? Minta token tersendiri untuk API itu.
    • Pembajakan pegangan. Memegang ID bukan bukti identitas. Ikat pegangan ke pengguna terautentikasi di sisi server, mis. kunci user_id:handle dengan user_id dari token yang terverifikasi, bukan dari client.
    • Server lokal yang berbahaya. Server lokal berjalan dengan hak akses client. Host yang menawarkan pemasangan sekali klik wajib menampilkan perintah lengkapnya dan meminta persetujuan, dan sebaiknya menjalankannya di kotak pasir.
    • Deskripsi yang menipu. Anotasi dan deskripsi tool dari server yang tak tepercaya dianggap tak tepercaya.

    Di sisi client, spesifikasi menganjurkan (SHOULD): tampilkan masukan tool sebelum dikirim (mencegah kebocoran data), validasi hasil sebelum diteruskan ke LLM, pasang batas waktu, dan catat pemakaian tool untuk audit.

  11. 10

    Naik ke server jarak jauh: Streamable HTTP

    Server stdio hanya bisa dipakai di mesin yang sama. Supaya bisa dipakai lewat jaringan, servermu perlu Streamable HTTP: setiap pesan dari client adalah POST baru ke satu endpoint MCP, dan server menjawab dengan satu objek JSON atau aliran SSE (Server-Sent Events). Header wajibnya:

    http
    POST /mcp HTTP/1.1
    Content-Type: application/json
    MCP-Protocol-Version: 2026-07-28
    Mcp-Method: tools/call
    Mcp-Name: get_weather

    Nilai header harus sama dengan isi badan. Bila berbeda, server menolak dengan 400 dan -32020 (HeaderMismatch), supaya penyeimbang beban yang membaca header dan server yang membaca badan tak pernah berselisih.

    Tiga aturan keamanan transport:

    • validasi header Origin di setiap koneksi (403 bila tak sah) untuk menangkal DNS rebinding;
    • saat berjalan lokal, dengarkan hanya di 127.0.0.1, bukan 0.0.0.0;
    • autentikasi semua koneksi.

    Otorisasinya OAuth 2.1. Server wajib menerbitkan Protected Resource Metadata (RFC 9728), client wajib menyebut server tujuan lewat parameter resource (RFC 8707), dan pendaftaran client dianjurkan lewat Client ID Metadata Documents; Dynamic Client Registration kini deprecated. Server stdio tak memakai kerangka ini: kredensialnya diambil dari lingkungan proses.

  12. 11

    Dengarkan perubahan dan atur cache: subscriptions/listen dan ttlMs

    Daftar tool bisa bertambah dan isi berkas bisa berubah. Bagaimana client tahu? Kini semuanya tiba lewat satu permintaan berumur panjang:

    json
    {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "subscriptions/listen",
      "params": {
        "notifications": {
          "toolsListChanged": true,
          "resourceSubscriptions": ["file:///project/config.json"]
        }
      }
    }

    (_meta wajib tetap ada; di sini disingkat.) Server lebih dulu mengirim notifications/subscriptions/acknowledged, berisi jenis notifikasi yang benar-benar ia layani. Sesudah itu datang notifikasi bertanda io.modelcontextprotocol/subscriptionId, yang nilainya id permintaan listen tadi. Notifikasi milik satu permintaan tertentu, seperti notifications/progress, tetap lewat aliran jawaban permintaan itu.

    Cache melengkapinya. Hasil server/discover, tools/list, prompts/list, resources/list, resources/templates/list, dan resources/read wajib membawa ttlMs (berapa milidetik hasil boleh dianggap segar) dan cacheScope (public atau private). TTL hanya petunjuk kesegaran, bukan janji bahwa data tak akan berubah.

Tools

  • MCP C# SDK

    SDK resmi MCP untuk C# (Tier 1), dengan paket terpisah untuk inti, hosting, dan server HTTP berbasis ASP.NET Core.

    Pilihan bila servermu ditulis dengan .NET.

  • MCP Inspector

    Alat pengembang rujukan untuk memeriksa server MCP: satu paket, tiga client — antarmuka web, CLI untuk skrip dan CI, dan TUI.

    Dipakai sejak server pertama berjalan, untuk melihat pesan JSON-RPC yang sebenarnya lewat. Butuh Node 22.19.0 atau lebih baru.

  • MCP Python SDK

    SDK resmi MCP untuk Python (Tier 1). Server dibangun dengan kelas MCPServer; petunjuk tipe dan docstring menjadi skema tool.

    Pilihan bila servermu ditulis dengan Python. Pasang dengan uv add "mcp[cli]"; perintah mcp dev membukanya di Inspector.

  • MCP TypeScript SDK

    SDK resmi MCP untuk TypeScript (Tier 1). Versi 2 — paket @modelcontextprotocol/server dan @modelcontextprotocol/client — mengimplementasikan revisi spesifikasi 2026-07-28.

    Pilihan bila servermu berjalan di Node.js, Bun, atau Deno. Contoh yang mengimpor @modelcontextprotocol/sdk ditulis untuk v1.x.

Mini Project

  • Misi

    Server MCP untuk catatan lokal

    Proyek pertama ini merangkai langkah 4 sampai 7 menjadi sesuatu yang bisa kamu pakai sehari-hari. Bangun server stdio yang membuka akses ke satu folder catatan Markdown:

    • tool cari_catatan(kata) yang mengembalikan judul catatan yang cocok;
    • tool tambah_catatan(judul, isi) yang menulis berkas baru;
    • satu resource yang membaca isi satu catatan lewat URI-nya.

    Periksa semuanya dengan MCP Inspector, sambungkan ke satu host, lalu minta model mencari sebuah catatan.

    Kamu selesai bila:

    1. model menemukan catatan lewat tool-mu;
    2. kamu bisa menunjukkan di host-mu bagaimana seorang manusia menolak pemanggilan tambah_catatan sebelum ia menulis;
    3. percobaan menulis di luar folder catatan ditolak dengan galat eksekusi (isError: true) yang menjelaskan sebabnya, bukan dengan server yang mati;
    4. servermu tak menulis apa pun ke stdout selain pesan protokol (log ke stderr);
    5. npx @modelcontextprotocol/inspector --cli <perintah servermu> --method tools/list mencetak kedua tool dalam urutan yang sama setiap kali dijalankan.
  • Misi

    Server jarak jauh tanpa sesi: keranjang belanja

    Proyek kedua menguji pemahamanmu tentang dunia tanpa sesi. Bangun server Streamable HTTP dengan SDK resmi yang mendukung revisi 2026-07-28, dengan tiga tool: create_basket, add_item(basket_id, sku), dan checkout(basket_id).

    • create_basket mengembalikan pegangan acak (misalnya UUIDv4) di structuredContent, dan deskripsinya menyebut umur keranjang;
    • checkout meminta konfirmasi pengguna lewat MRTR: jawaban pertamanya InputRequiredResult berisi permintaan elicitation/create, dan baru selesai ketika client mengulang panggilan dengan jawaban accept;
    • server mendengarkan di 127.0.0.1 dan menolak Origin yang tak dikenal.

    Kamu selesai bila:

    1. keranjang tetap ada sesudah proses server dimatikan dan dinyalakan lagi, karena keadaannya disimpan menurut pegangan, bukan menurut koneksi;
    2. add_item dengan pegangan yang tak dikenal atau kedaluwarsa menghasilkan galat eksekusi yang menyuruh model membuat keranjang baru;
    3. checkout yang dijawab decline tak memproses apa pun;
    4. permintaan yang header Mcp-Name-nya berbeda dari params.name ditolak dengan 400;
    5. kamu bisa menjelaskan, dengan merujuk spesifikasi, kenapa pegangan saja tak boleh dianggap bukti identitas begitu server ini diberi autentikasi.

Resources

Topik terhubung

Pelajari lebih dulu

Dibutuhkan oleh