[{"data":1,"prerenderedAt":195},["ShallowReactive",2],{"site-header":3,"site-footer-license":42,"article-mcp-dibongkar-ulang-kabar-baik-buat-kamu-with-latest":46},{"navigations":4},[5,20,37],{"collection":6,"item":7},"series",{"__typename":6,"title":8,"slug":9,"children_series":10},"Artikel","all",[11,14,17],{"title":12,"slug":13},"Algoritma dan Struktur Data","algoritma-struktur-data",{"title":15,"slug":16},"Kecerdasan Artifisial","kecerdasan-artifisial",{"title":18,"slug":19},"Konsep Dasar Pemrograman","konsep-dasar-pemrograman",{"collection":6,"item":21},{"__typename":6,"title":22,"slug":23,"children_series":24},"Tutorial","tutorial",[25,28,31,34],{"title":26,"slug":27},"Belajar Java","belajar-java",{"title":29,"slug":30},"Belajar Pascal","belajar-pascal",{"title":32,"slug":33},"Belajar Golang","belajar-golang",{"title":35,"slug":36},"Belajar Python","belajar-python",{"collection":6,"item":38},{"__typename":6,"title":39,"slug":40,"children_series":41},"Lab","lab",[],{"name":43,"url":44,"show":45},"CC BY-SA","https:\u002F\u002Fcreativecommons.org\u002Flicenses\u002Fby-sa\u002F4.0\u002F",false,{"article":47,"renderedBody":115,"renderedTakeaway":116,"latestArticles":117,"toc":169},{"prerequisite":48,"id":49,"title":50,"slug":51,"excerpt":52,"published_at":53,"thumbnail_image":48,"tags":54,"reading_time":61,"takeway":62,"body":63,"authors":64,"series":65},null,"125","MCP dibongkar ulang: kabar baik buat kamu yang capek nulis konektor","mcp-dibongkar-ulang-kabar-baik-buat-kamu","Kamu punya beberapa API internal dan satu agent AI, tapi kodenya harus ditulis ulang tiap kali modelnya diganti. MCP datang buat mengakhiri itu, dan tahun ini protokolnya dibongkar ulang supaya server-nya bisa jalan seperti web server biasa. Yuk lihat apa yang berubah. 🔧","2026-10-16T05:00:00.000Z",[55,56,57,58,59,60],"mcp","model-context-protocol","ai-agent","llm","backend","python",8,"- Model Context Protocol mengubah integrasi model-ke-sumber-data dari puluhan konektor buatan sendiri jadi satu protokol terbuka yang dipakai bersama.\n- Server MCP membagi peran dengan rapi: tool dipanggil model, resource dibaca aplikasi, dan prompt dipilih user.\n- Kredensial tetap di sisi server dan nggak pernah masuk ke prompt, karena server memang nggak boleh membaca seluruh percakapan.\n- Sejak spec 2026-07-28 protokolnya stateless, jadi server MCP bisa dideploy seperti workload HTTP biasa tanpa sesi yang harus dijaga.\n- Kalau tutorial yang kamu baca masih memakai FastMCP atau transport SSE, itu versi lama: nama API-nya sudah pindah dan transportnya sudah deprecated.","Kamu punya beberapa endpoint internal: satu buat data artikel, satu buat pengguna, satu lagi buat laporan. Lalu ada satu agent AI yang harus bisa mengakses semuanya. Cara paling cepat adalah menulis konektor per pasangan, yaitu satu kode khusus untuk model A dan sumber data X, satu lagi untuk model A dan sumber Y. Awalnya terasa beres. Semua jalan, demo lancar, dan kamu merasa cukup produktif hari itu.\n\nMasalahnya baru kelihatan begitu modelnya diganti. Format *tool calling* beda, cara mendeskripsikan argumen beda, penanganan *error* pun beda. Setengah kode konektor tadi mendadak jadi sampah, dan kamu harus mengulang dari awal 😅. Kalau dihitung kasar, lima model dikali sepuluh sumber data berarti lima puluh implementasi yang harus dirawat. Angka itu cuma ilustrasi, tapi rasa sakitnya nyata bagi siapa pun yang pernah menjaga kode perekat.\n\n```mermaid\nflowchart LR\n  M1[Model A] --> K1[konektor khusus]\n  M2[Model B] --> K1\n  M3[Model C] --> K1\n  K1 --> S1[(PostgreSQL)]\n  K1 --> S2[(Git)]\n  K1 --> S3[(REST internal)]\n```\n\nNah, di titik inilah **Model Context Protocol** (MCP) masuk. Ide dasarnya sederhana: daripada setiap model bicara dengan setiap sumber lewat jalur khusus, semuanya bicara lewat satu protokol standar. Sumber data cukup ditulis sekali sebagai *server* — dan model apa pun yang paham protokolnya bisa memakainya.\n\n## Kenapa masalah remeh ini mahal?\n\nKode perekat itu jarang dianggap pekerjaan serius. Isinya cuma mengubah format, menyalin skema, dan menempelkan kredensial. Tapi justru bagian itu yang paling rapuh, karena setiap perubahan di salah satu ujung memaksa perubahan di ujung lain. Biayanya nggak kelihatan di *sprint planning*, tapi menumpuk diam-diam sampai satu hari kita sadar separuh waktu habis untuk menambal konektor.\n\nKalau kamu pernah memakai editor modern, kamu sudah merasakan solusi serupa di dunia lain. Spesifikasi MCP sendiri menyebut bahwa protokol ini mengambil inspirasi dari [Language Server Protocol](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2026-07-28). Dulu setiap editor harus mengimplementasikan dukungan untuk setiap bahasa pemrograman. Setelah ada protokol bersama, satu *language server* bisa melayani banyak editor. MCP membawa pola yang sama ke dunia agent AI, jadi kamu menulis konektor sekali dan nggak perlu peduli siapa yang memakainya nanti.\n\n## Siapa yang ngobrol dengan siapa\n\nArsitekturnya punya tiga peran. **Host** adalah aplikasi yang kamu pakai langsung, misalnya aplikasi desktop atau ekstensi editor, dan di dalamnya model AI berjalan. *Client* adalah komponen di dalam host yang mengurus komunikasi. *Server* adalah program yang membuka kemampuan atau data, dan di sinilah kode yang kamu tulis nanti berada.\n\nSatu hal yang perlu diingat: satu *client* berpasangan dengan tepat satu *server*. Kalau host terhubung ke tiga *server*, berarti ada tiga *client* di dalamnya. Pembagian ini bukan kebetulan, karena dari sinilah batas keamanannya terbentuk. Menurut [prinsip arsitektur di spec](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2026-07-28\u002Farchitecture), *server* nggak boleh bisa membaca seluruh percakapan dan nggak boleh bisa melihat ke dalam *server* lain. Riwayat percakapan tetap tinggal di host.\n\nKredensial juga ikut aman. Token *database* atau kunci API tetap berada di sisi *server*, jadi nggak pernah ikut masuk ke *prompt*. Model cuma tahu bahwa ada *tool* bernama sekian dengan argumen sekian, bukan password di belakangnya. Itu keputusan desain yang menenangkan, kan.\n\n## Tiga primitif, dan siapa yang pegang kendali\n\n```mermaid\nsequenceDiagram\n  autonumber\n  participant H as Host\n  participant S as MCP Server\n  Note over H,S: Sebelum 2026-07-28 (stateful)\n  H->>S: initialize\n  S-->>H: Mcp-Session-Id\n  H->>S: tools\u002Fcall + Mcp-Session-Id\n  Note over H,S: Sejak 2026-07-28 (stateless)\n  H->>S: tools\u002Fcall + _meta\n  S-->>H: hasil\n```\n\nServer bisa menawarkan tiga jenis hal, dan perbedaannya terletak pada siapa yang memutuskan kapan dipakai.\n\n- *Tools* dikendalikan model. Model memutuskan sendiri kapan memanggilnya, dan *tool* biasanya punya efek samping seperti menulis data atau mengirim sesuatu.\n- *Resources* dikendalikan aplikasi. Isinya data yang dibaca lewat URI, dan host yang menentukan apa yang masuk ke konteks.\n- *Prompts* dikendalikan user. Bentuknya template alur kerja yang dipilih manusia secara sadar.\n\nBuat kita yang terbiasa bikin web API, ada padanan yang gampang diingat. Resource itu seperti `GET` — cuma membaca dan nggak mengubah apa-apa. *Tool* itu seperti `POST`, karena bisa mengubah keadaan di dunia luar. Dengan cara pikir ini, memutuskan sebuah fungsi harus jadi resource atau *tool* biasanya selesai dalam hitungan detik.\n\n## Kenapa protokolnya dibongkar ulang\n\nIni bagian terpenting, jadi yuk kita bahas pelan-pelan. MCP lahir dengan transport `stdio` untuk aplikasi lokal. Di situ *server* adalah proses anak yang hidup berdampingan dengan host, dan *state* itu wajar. Ada koneksi, ada sesi, dan semuanya berjalan di satu mesin.\n\nMasalah muncul ketika *server* mulai berjalan jauh dari host. *State* tadi ikut terbawa ke HTTP: urusan sesi, stream yang digantung terus, sampai *replay* pesan ketika koneksi putus. [Tulisan Cloudflare](https:\u002F\u002Fblog.cloudflare.com\u002Fmcp-v2) menyebut bahwa kritik utama ke MCP memang koneksi stateful-nya. Bebannya berupa mengatur rute *request* ke *sticky session*, menahan stream terbuka, dan memutar ulang pesan. Siapa sih yang senang mengoperasikan itu semua di produksi?\n\nJawaban dari spesifikasi `2026-07-28` cukup tegas. Handshake `initialize` dan header `Mcp-Session-Id` **dihapus**. Sebagai gantinya, setiap *request* membawa versi protokol, identitas *client*, dan *capability*-nya sendiri. Client yang tetap ingin tahu kemampuan *server* lebih dulu bisa memanggil `server\u002Fdiscover`, tapi itu opsional, bukan syarat. Singkatnya, protokolnya sekarang **stateless di level protokol**.\n\n```mermaid\nflowchart TD\n  H[Host] --> C1[Client]\n  C1 --> SM[MCP Server]\n  SM --> T[Tools - dipanggil model]\n  SM --> R[Resources - dibaca aplikasi]\n  SM --> P[Prompts - dipilih user]\n```\n\nBeberapa detail baru layak dicatat. Pertama, header `Mcp-Method` dan `Mcp-Name` kini wajib ada di *request* Streamable HTTP. Gateway, *rate limiter*, atau WAF jadi bisa memutuskan tanpa membedah body JSON, dan itu kabar bagus buat yang mengurus infrastruktur.\n\nKedua, hasil `tools\u002Flist` dan kawan-kawannya membawa petunjuk cache `ttlMs` dan `cacheScope`, dengan urutan yang deterministik. Artinya katalog *tool* bisa di-*cache* oleh client dengan aman, tanpa khawatir urutannya berubah-ubah.\n\nKetiga, ada **MRTR** (*Multi Round-Trip Request*). Kalau sebuah *tool* butuh konfirmasi, *server* membalas `input_required` beserta permintaan yang dibutuhkan. Client mengumpulkan jawaban dari user, lalu mengulang pemanggilan aslinya. Dulu urusan server-ke-client seperti ini butuh stream terbuka, sekarang cukup putaran *request* biasa.\n\nKonsekuensinya besar: *server* MCP sekarang bisa jadi *workload* HTTP biasa. Nggak ada sesi yang harus dijaga, dan *server* bisa jalan di *serverless*. Menurut Cloudflare, setelah protokolnya stateless, *server* MCP bisa jalan di Worker dan primitif `McpAgent` mereka nggak lagi diperlukan. Emang begitu hasilnya kalau *state* dipindahkan dari koneksi ke *request*.\n\nSatu catatan supaya nggak salah paham: stateless bukan berarti aplikasimu nggak boleh punya *state*. Kalau butuh, buat *handle* eksplisit dari sebuah *tool*, misalnya pengenal keranjang atau sesi kerja, lalu biarkan model membawanya balik sebagai argumen di panggilan berikutnya. *State*-nya pindah ke tempat yang kelihatan, bukan hilang.\n\n## Yang perlu diwaspadai kalau baca tutorial lama\n\nBanyak *tutorial* MCP ditulis sebelum perubahan di atas, jadi ada beberapa jebakan yang gampang kita temui. Kalau kamu menemukan contoh yang kelihatan meyakinkan, cek dulu hal-hal ini:\n\n- `from mcp.server.fastmcp import FastMCP` itu API versi lama. Sekarang yang dipakai `from mcp.server import MCPServer`, dan import lamanya langsung melempar `ModuleNotFoundError`.\n- Transport HTTP+SSE sudah digantikan Streamable HTTP sejak revisi `2025-03-26`. Ia masih hidup demi kompatibilitas, tapi statusnya *deprecated*.\n- Roots, Sampling, dan Logging juga *deprecated*, dengan masa transisi minimal 12 bulan. Sementara itu `ping` sudah dihapus dari protokol.\n\nArtikel ini sendiri punya tanggal kedaluwarsa. Revisi spec datang dengan jarak 3 sampai 8 bulan, dengan urutan `2024-11-05`, `2025-03-26`, `2025-06-18`, `2025-11-25`, lalu `2026-07-28`. Versi yang dipakai di sini adalah `2026-07-28`, jadi kalau kamu membaca ini jauh setelahnya, [cek versi terbaru](https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002Fversioning) sebelum menyalin apa pun.\n\n## Server MCP pertama, sedikit baris\n\nCukup teorinya, sekarang kita lihat kodenya. Server di bawah nih punya satu resource berisi skema tabel dan satu *tool* pencarian. Isinya sengaja dibuat sederhana, dan fungsi pencariannya cuma mengembalikan teks, bukan *query* sungguhan.\n\n```python\n# server.py\nfrom mcp.server import MCPServer\n\nmcp = MCPServer(\"Invasikode Database Server\")\n\n\n@mcp.resource(\"db:\u002F\u002Farticles\u002Fschema\")\ndef get_articles_schema() -> str:\n    \"\"\"Skema DDL tabel artikel, buat konteks LLM.\"\"\"\n    return \"\"\"\n    CREATE TABLE articles (\n        id SERIAL PRIMARY KEY,\n        title VARCHAR(255) NOT NULL,\n        slug VARCHAR(255) UNIQUE NOT NULL,\n        tags VARCHAR(255),\n        status VARCHAR(32) DEFAULT 'draft'\n    );\n    \"\"\"\n\n\n@mcp.tool()\ndef search_articles_by_keyword(keyword: str, limit: int = 5) -> str:\n    \"\"\"Cari artikel berdasarkan kata kunci judul.\n\n    Args:\n        keyword: Kata kunci pencarian.\n        limit: Batas maksimum artikel yang dikembalikan.\n    \"\"\"\n    return f\"Berhasil mengambil {limit} artikel dengan kata kunci '{keyword}'.\"\n```\n\nPerhatikan apa yang nggak ada di kode tuh. Nggak ada JSON Schema yang ditulis tangan, karena *type hint* dan *docstring* sudah otomatis jadi skema. Nggak ada *request handler*, nggak ada deklarasi *capability*. Nama, deskripsi, dan skema argumen semuanya diturunkan dari fungsi Python-nya sendiri. Itulah poinnya — kamu menulis fungsi biasa, dan SDK mengurus sisanya. Kode ini sudah dijalankan pada SDK Python `mcp` 2.0.0, dengan protokol yang dinegosiasikan `2026-07-28`, dan *tool* serta resource-nya terdaftar. Ia belum diuji di *server* produksi, jadi perlakukan sebagai titik awal. Dokumentasi lengkapnya ada di [panduan SDK Python](https:\u002F\u002Fpy.sdk.modelcontextprotocol.io\u002Fget-started\u002Ffirst-steps\u002F).\n\nCara menjalankannya gampang kok: simpan sebagai `server.py`, pasang paketnya, lalu jalankan lewat SDK. Setelah itu kita daftarkan ke host. Di aplikasi desktop, biasanya lewat berkas konfigurasi seperti `claude_desktop_config.json`, dengan menunjuk perintah yang menjalankan servermu. Di editor, biasanya lewat ekstensi atau pengaturan MCP. Setelah terdaftar, coba tanya agent soal skema tabel artikel deh, lalu lihat apakah ia memakai resource yang baru kamu tulis 🙂.\n\n## Kenapa ini penting buat kamu\n\nKeuntungan paling nyata adalah sekali tulis, dipakai di mana-mana. Konektor ke *database* artikel yang tadi kamu tulis bisa dipakai oleh host mana pun yang mendukung MCP, tanpa perubahan di sisi *server*. Ganti model nggak lagi berarti nulis ulang konektor, dan itu menyelesaikan masalah di pembuka tadi.\n\nKredensial juga tetap di sisimu. Server yang menyimpan token dan kunci, model cuma melihat hasil yang sudah kamu izinkan. Dan karena protokolnya kini stateless, men-*deploy* *server* MCP nggak lagi butuh trik khusus. Ia bisa diperlakukan seperti layanan HTTP lain yang sudah biasa kamu urus, lengkap dengan *load balancer* dan *autoscaling*. Itu perubahan yang sebenarnya menarik buat kamu yang kerja di backend, lho!\n\n## Standarisasi dan siapa yang pegang protokolnya\n\nMCP diperkenalkan Anthropic pada 25 November 2024. Pada Desember 2025, protokol ini didonasikan ke Agentic AI Foundation, sebuah dana terarah di bawah Linux Foundation. [Pendirinya](https:\u002F\u002Fwww.anthropic.com\u002Fnews\u002Fdonating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation) adalah Anthropic, Block, dan OpenAI, dengan dukungan Google, Microsoft, AWS, Cloudflare, dan Bloomberg. Governance-nya nggak berubah, jadi proses pengambilan keputusan yang sudah berjalan tetap sama.\n\nSoal adopsi, tulisan donasi itu mencatat bahwa per Desember 2025 ada lebih dari 10.000 MCP *server* publik yang aktif. Protokolnya juga sudah diadopsi ChatGPT, Cursor, Gemini, Microsoft Copilot, dan VS Code. Angka itu cukup menjelaskan kenapa banyak *developer* memutuskan belajar MCP sekarang, bukan nanti 🚀.\n\nJadi, kalau endpoint internalmu sudah menunggu ditempelkan ke agent, kamu sudah punya jalan pintasnya. Mulai dari satu fungsi kecil, biarkan type hint jadi skema, dan simpan konektor lima puluh itu sebagai cerita lama. Tinggal pastikan versi spec yang kamu pakai sama dengan yang dipakai host-mu.",[],{"id":66,"title":15,"slug":16,"articles":67,"parent_series":107},"8",[68,70,80,86,93,100],{"id":49,"title":50,"slug":51,"excerpt":52,"thumbnail_image":48,"tags":69},[55,56,57,58,59,60],{"id":71,"title":72,"slug":73,"excerpt":74,"thumbnail_image":48,"tags":75},"3","Mengenal JEPA: Saat AI Mulai Belajar Punya \"Akal Sehat\"","kenapa-ai-suka-halu-dan-gimana-jepa-beresin-masalah-ini","AI sering 'halu' karena cuma nebak probabilitas data tanpa paham realita. Arsitektur JEPA mencoba mengubah itu dengan membangun model dunia di kepalanya.",[76,77,78,79],"artificial-intelligence","jepa","world-models","yann-lecun",{"id":81,"title":82,"slug":83,"excerpt":84,"thumbnail_image":48,"tags":85},"2","LLM Bakal Mentok, Terus Gimana Dong?","llm-bakal-mentok-terus-gimana-dong","LLM kayak ChatGPT itu jago ngerangkai kata, tapi nggak beneran paham realitas. Yann LeCun bilang arsitektur ini bakal mentok dan butuh solusi baru.",[76,58,79,77],{"id":87,"title":88,"slug":89,"excerpt":90,"thumbnail_image":48,"tags":91},"1","Kenapa AI Suka 'Halu'? Kenalan sama JEPA, Otak AI yang Punya Akal Sehat","kenapa-ai-suka-halu-kenalan-sama-jepa-otak-ai-yang-punya-akal-sehat","AI generatif sering 'halu' karena cuma jago nebak pola kata. JEPA coba ngerombak itu dengan ngajarin AI cara kerja dunia nyata kayak otak manusia.",[77,76,79,92],"agi",{"id":94,"title":95,"slug":96,"excerpt":97,"thumbnail_image":48,"tags":98},"4","Bukan Sekadar Generative AI, JEPA Coba Kejar Pemahaman Konsep ala Manusia","kenapa-ai-masih-gagal-paham-fisika-dasar-mengenal-arsitektur-jepa","AI biasanya cuma jago nebak piksel, tapi JEPA coba belajar lewat konsep abstrak di ruang laten. Ternyata, cara ini bisa sampai dipakai buat baca gelombang otak.",[77,79,99,92],"machine-learning",{"id":101,"title":102,"slug":103,"excerpt":104,"thumbnail_image":48,"tags":105},"5","Di Balik Dapur JEPA: Rahasia EMA, VICReg, dan Efisiensi Komputasi","di-balik-dapur-jepa-rahasia-ema-vicreg-dan-efisiensi-komputasi","Bosen sama AI yang cuma jago nebak kata atau ngafalin pixel? Kenalan sama JEPA, arsitektur revolusioner yang ngajarin mesin punya \"akal sehat\" secara super efisien. Yuk intip jeroan teknisnya!",[77,106],"artificial-intelligent",{"id":108,"title":8,"slug":9,"parent_series":48,"children_series":109},"9",[110,112,113],{"id":111,"title":12,"slug":13,"cover_image":48},"15",{"id":66,"title":15,"slug":16,"cover_image":48},{"id":114,"title":18,"slug":19,"cover_image":48},"12","\u003Cp>Kamu punya beberapa endpoint internal: satu buat data artikel, satu buat pengguna, satu lagi buat laporan. Lalu ada satu agent AI yang harus bisa mengakses semuanya. Cara paling cepat adalah menulis konektor per pasangan, yaitu satu kode khusus untuk model A dan sumber data X, satu lagi untuk model A dan sumber Y. Awalnya terasa beres. Semua jalan, demo lancar, dan kamu merasa cukup produktif hari itu.\u003C\u002Fp>\n\u003Cp>Masalahnya baru kelihatan begitu modelnya diganti. Format \u003Cem>tool calling\u003C\u002Fem> beda, cara mendeskripsikan argumen beda, penanganan \u003Cem>error\u003C\u002Fem> pun beda. Setengah kode konektor tadi mendadak jadi sampah, dan kamu harus mengulang dari awal 😅. Kalau dihitung kasar, lima model dikali sepuluh sumber data berarti lima puluh implementasi yang harus dirawat. Angka itu cuma ilustrasi, tapi rasa sakitnya nyata bagi siapa pun yang pernah menjaga kode perekat.\u003C\u002Fp>\n\n\u003Cdiv class=\"mermaid-block my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e]\" data-mermaid-diagram>\n  \u003Cdiv class=\"mermaid-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cspan class=\"uppercase tracking-wider\">Diagram\u003C\u002Fspan>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"flowchart%20LR%0A%20%20M1%5BModel%20A%5D%20--%3E%20K1%5Bkonektor%20khusus%5D%0A%20%20M2%5BModel%20B%5D%20--%3E%20K1%0A%20%20M3%5BModel%20C%5D%20--%3E%20K1%0A%20%20K1%20--%3E%20S1%5B(PostgreSQL)%5D%0A%20%20K1%20--%3E%20S2%5B(Git)%5D%0A%20%20K1%20--%3E%20S3%5B(REST%20internal)%5D\" title=\"Salin kode diagram\">\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"mermaid-canvas p-4 overflow-x-auto\">\n    \u003Cdiv class=\"mermaid-source text-sm font-mono leading-relaxed text-[#e1e4e8]\">flowchart LR\n  M1[Model A] --&gt; K1[konektor khusus]\n  M2[Model B] --&gt; K1\n  M3[Model C] --&gt; K1\n  K1 --&gt; S1[(PostgreSQL)]\n  K1 --&gt; S2[(Git)]\n  K1 --&gt; S3[(REST internal)]\u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Nah, di titik inilah \u003Cstrong>Model Context Protocol\u003C\u002Fstrong> (MCP) masuk. Ide dasarnya sederhana: daripada setiap model bicara dengan setiap sumber lewat jalur khusus, semuanya bicara lewat satu protokol standar. Sumber data cukup ditulis sekali sebagai \u003Cem>server\u003C\u002Fem> — dan model apa pun yang paham protokolnya bisa memakainya.\u003C\u002Fp>\n\u003Ch2 id=\"kenapa-masalah-remeh-ini-mahal\">Kenapa masalah remeh ini mahal?\u003C\u002Fh2>\n\u003Cp>Kode perekat itu jarang dianggap pekerjaan serius. Isinya cuma mengubah format, menyalin skema, dan menempelkan kredensial. Tapi justru bagian itu yang paling rapuh, karena setiap perubahan di salah satu ujung memaksa perubahan di ujung lain. Biayanya nggak kelihatan di \u003Cem>sprint planning\u003C\u002Fem>, tapi menumpuk diam-diam sampai satu hari kita sadar separuh waktu habis untuk menambal konektor.\u003C\u002Fp>\n\u003Cp>Kalau kamu pernah memakai editor modern, kamu sudah merasakan solusi serupa di dunia lain. Spesifikasi MCP sendiri menyebut bahwa protokol ini mengambil inspirasi dari \u003Ca href=\"https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2026-07-28\">Language Server Protocol\u003C\u002Fa>. Dulu setiap editor harus mengimplementasikan dukungan untuk setiap bahasa pemrograman. Setelah ada protokol bersama, satu \u003Cem>language server\u003C\u002Fem> bisa melayani banyak editor. MCP membawa pola yang sama ke dunia agent AI, jadi kamu menulis konektor sekali dan nggak perlu peduli siapa yang memakainya nanti.\u003C\u002Fp>\n\u003Ch2 id=\"siapa-yang-ngobrol-dengan-siapa\">Siapa yang ngobrol dengan siapa\u003C\u002Fh2>\n\u003Cp>Arsitekturnya punya tiga peran. \u003Cstrong>Host\u003C\u002Fstrong> adalah aplikasi yang kamu pakai langsung, misalnya aplikasi desktop atau ekstensi editor, dan di dalamnya model AI berjalan. \u003Cem>Client\u003C\u002Fem> adalah komponen di dalam host yang mengurus komunikasi. \u003Cem>Server\u003C\u002Fem> adalah program yang membuka kemampuan atau data, dan di sinilah kode yang kamu tulis nanti berada.\u003C\u002Fp>\n\u003Cp>Satu hal yang perlu diingat: satu \u003Cem>client\u003C\u002Fem> berpasangan dengan tepat satu \u003Cem>server\u003C\u002Fem>. Kalau host terhubung ke tiga \u003Cem>server\u003C\u002Fem>, berarti ada tiga \u003Cem>client\u003C\u002Fem> di dalamnya. Pembagian ini bukan kebetulan, karena dari sinilah batas keamanannya terbentuk. Menurut \u003Ca href=\"https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002F2026-07-28\u002Farchitecture\">prinsip arsitektur di spec\u003C\u002Fa>, \u003Cem>server\u003C\u002Fem> nggak boleh bisa membaca seluruh percakapan dan nggak boleh bisa melihat ke dalam \u003Cem>server\u003C\u002Fem> lain. Riwayat percakapan tetap tinggal di host.\u003C\u002Fp>\n\u003Cp>Kredensial juga ikut aman. Token \u003Cem>database\u003C\u002Fem> atau kunci API tetap berada di sisi \u003Cem>server\u003C\u002Fem>, jadi nggak pernah ikut masuk ke \u003Cem>prompt\u003C\u002Fem>. Model cuma tahu bahwa ada \u003Cem>tool\u003C\u002Fem> bernama sekian dengan argumen sekian, bukan password di belakangnya. Itu keputusan desain yang menenangkan, kan.\u003C\u002Fp>\n\u003Ch2 id=\"tiga-primitif-dan-siapa-yang-pegang-kendali\">Tiga primitif, dan siapa yang pegang kendali\u003C\u002Fh2>\n\n\u003Cdiv class=\"mermaid-block my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e]\" data-mermaid-diagram>\n  \u003Cdiv class=\"mermaid-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cspan class=\"uppercase tracking-wider\">Diagram\u003C\u002Fspan>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"sequenceDiagram%0A%20%20autonumber%0A%20%20participant%20H%20as%20Host%0A%20%20participant%20S%20as%20MCP%20Server%0A%20%20Note%20over%20H%2CS%3A%20Sebelum%202026-07-28%20(stateful)%0A%20%20H-%3E%3ES%3A%20initialize%0A%20%20S--%3E%3EH%3A%20Mcp-Session-Id%0A%20%20H-%3E%3ES%3A%20tools%2Fcall%20%2B%20Mcp-Session-Id%0A%20%20Note%20over%20H%2CS%3A%20Sejak%202026-07-28%20(stateless)%0A%20%20H-%3E%3ES%3A%20tools%2Fcall%20%2B%20_meta%0A%20%20S--%3E%3EH%3A%20hasil\" title=\"Salin kode diagram\">\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"mermaid-canvas p-4 overflow-x-auto\">\n    \u003Cdiv class=\"mermaid-source text-sm font-mono leading-relaxed text-[#e1e4e8]\">sequenceDiagram\n  autonumber\n  participant H as Host\n  participant S as MCP Server\n  Note over H,S: Sebelum 2026-07-28 (stateful)\n  H-&gt;&gt;S: initialize\n  S--&gt;&gt;H: Mcp-Session-Id\n  H-&gt;&gt;S: tools\u002Fcall + Mcp-Session-Id\n  Note over H,S: Sejak 2026-07-28 (stateless)\n  H-&gt;&gt;S: tools\u002Fcall + _meta\n  S--&gt;&gt;H: hasil\u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Server bisa menawarkan tiga jenis hal, dan perbedaannya terletak pada siapa yang memutuskan kapan dipakai.\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cem>Tools\u003C\u002Fem> dikendalikan model. Model memutuskan sendiri kapan memanggilnya, dan \u003Cem>tool\u003C\u002Fem> biasanya punya efek samping seperti menulis data atau mengirim sesuatu.\u003C\u002Fli>\n\u003Cli>\u003Cem>Resources\u003C\u002Fem> dikendalikan aplikasi. Isinya data yang dibaca lewat URI, dan host yang menentukan apa yang masuk ke konteks.\u003C\u002Fli>\n\u003Cli>\u003Cem>Prompts\u003C\u002Fem> dikendalikan user. Bentuknya template alur kerja yang dipilih manusia secara sadar.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Buat kita yang terbiasa bikin web API, ada padanan yang gampang diingat. Resource itu seperti \u003Ccode>GET\u003C\u002Fcode> — cuma membaca dan nggak mengubah apa-apa. \u003Cem>Tool\u003C\u002Fem> itu seperti \u003Ccode>POST\u003C\u002Fcode>, karena bisa mengubah keadaan di dunia luar. Dengan cara pikir ini, memutuskan sebuah fungsi harus jadi resource atau \u003Cem>tool\u003C\u002Fem> biasanya selesai dalam hitungan detik.\u003C\u002Fp>\n\u003Ch2 id=\"kenapa-protokolnya-dibongkar-ulang\">Kenapa protokolnya dibongkar ulang\u003C\u002Fh2>\n\u003Cp>Ini bagian terpenting, jadi yuk kita bahas pelan-pelan. MCP lahir dengan transport \u003Ccode>stdio\u003C\u002Fcode> untuk aplikasi lokal. Di situ \u003Cem>server\u003C\u002Fem> adalah proses anak yang hidup berdampingan dengan host, dan \u003Cem>state\u003C\u002Fem> itu wajar. Ada koneksi, ada sesi, dan semuanya berjalan di satu mesin.\u003C\u002Fp>\n\u003Cp>Masalah muncul ketika \u003Cem>server\u003C\u002Fem> mulai berjalan jauh dari host. \u003Cem>State\u003C\u002Fem> tadi ikut terbawa ke HTTP: urusan sesi, stream yang digantung terus, sampai \u003Cem>replay\u003C\u002Fem> pesan ketika koneksi putus. \u003Ca href=\"https:\u002F\u002Fblog.cloudflare.com\u002Fmcp-v2\">Tulisan Cloudflare\u003C\u002Fa> menyebut bahwa kritik utama ke MCP memang koneksi stateful-nya. Bebannya berupa mengatur rute \u003Cem>request\u003C\u002Fem> ke \u003Cem>sticky session\u003C\u002Fem>, menahan stream terbuka, dan memutar ulang pesan. Siapa sih yang senang mengoperasikan itu semua di produksi?\u003C\u002Fp>\n\u003Cp>Jawaban dari spesifikasi \u003Ccode>2026-07-28\u003C\u002Fcode> cukup tegas. Handshake \u003Ccode>initialize\u003C\u002Fcode> dan header \u003Ccode>Mcp-Session-Id\u003C\u002Fcode> \u003Cstrong>dihapus\u003C\u002Fstrong>. Sebagai gantinya, setiap \u003Cem>request\u003C\u002Fem> membawa versi protokol, identitas \u003Cem>client\u003C\u002Fem>, dan \u003Cem>capability\u003C\u002Fem>-nya sendiri. Client yang tetap ingin tahu kemampuan \u003Cem>server\u003C\u002Fem> lebih dulu bisa memanggil \u003Ccode>server\u002Fdiscover\u003C\u002Fcode>, tapi itu opsional, bukan syarat. Singkatnya, protokolnya sekarang \u003Cstrong>stateless di level protokol\u003C\u002Fstrong>.\u003C\u002Fp>\n\n\u003Cdiv class=\"mermaid-block my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e]\" data-mermaid-diagram>\n  \u003Cdiv class=\"mermaid-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cspan class=\"uppercase tracking-wider\">Diagram\u003C\u002Fspan>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"flowchart%20TD%0A%20%20H%5BHost%5D%20--%3E%20C1%5BClient%5D%0A%20%20C1%20--%3E%20SM%5BMCP%20Server%5D%0A%20%20SM%20--%3E%20T%5BTools%20-%20dipanggil%20model%5D%0A%20%20SM%20--%3E%20R%5BResources%20-%20dibaca%20aplikasi%5D%0A%20%20SM%20--%3E%20P%5BPrompts%20-%20dipilih%20user%5D\" title=\"Salin kode diagram\">\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"mermaid-canvas p-4 overflow-x-auto\">\n    \u003Cdiv class=\"mermaid-source text-sm font-mono leading-relaxed text-[#e1e4e8]\">flowchart TD\n  H[Host] --&gt; C1[Client]\n  C1 --&gt; SM[MCP Server]\n  SM --&gt; T[Tools - dipanggil model]\n  SM --&gt; R[Resources - dibaca aplikasi]\n  SM --&gt; P[Prompts - dipilih user]\u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Beberapa detail baru layak dicatat. Pertama, header \u003Ccode>Mcp-Method\u003C\u002Fcode> dan \u003Ccode>Mcp-Name\u003C\u002Fcode> kini wajib ada di \u003Cem>request\u003C\u002Fem> Streamable HTTP. Gateway, \u003Cem>rate limiter\u003C\u002Fem>, atau WAF jadi bisa memutuskan tanpa membedah body JSON, dan itu kabar bagus buat yang mengurus infrastruktur.\u003C\u002Fp>\n\u003Cp>Kedua, hasil \u003Ccode>tools\u002Flist\u003C\u002Fcode> dan kawan-kawannya membawa petunjuk cache \u003Ccode>ttlMs\u003C\u002Fcode> dan \u003Ccode>cacheScope\u003C\u002Fcode>, dengan urutan yang deterministik. Artinya katalog \u003Cem>tool\u003C\u002Fem> bisa di-\u003Cem>cache\u003C\u002Fem> oleh client dengan aman, tanpa khawatir urutannya berubah-ubah.\u003C\u002Fp>\n\u003Cp>Ketiga, ada \u003Cstrong>MRTR\u003C\u002Fstrong> (\u003Cem>Multi Round-Trip Request\u003C\u002Fem>). Kalau sebuah \u003Cem>tool\u003C\u002Fem> butuh konfirmasi, \u003Cem>server\u003C\u002Fem> membalas \u003Ccode>input_required\u003C\u002Fcode> beserta permintaan yang dibutuhkan. Client mengumpulkan jawaban dari user, lalu mengulang pemanggilan aslinya. Dulu urusan server-ke-client seperti ini butuh stream terbuka, sekarang cukup putaran \u003Cem>request\u003C\u002Fem> biasa.\u003C\u002Fp>\n\u003Cp>Konsekuensinya besar: \u003Cem>server\u003C\u002Fem> MCP sekarang bisa jadi \u003Cem>workload\u003C\u002Fem> HTTP biasa. Nggak ada sesi yang harus dijaga, dan \u003Cem>server\u003C\u002Fem> bisa jalan di \u003Cem>serverless\u003C\u002Fem>. Menurut Cloudflare, setelah protokolnya stateless, \u003Cem>server\u003C\u002Fem> MCP bisa jalan di Worker dan primitif \u003Ccode>McpAgent\u003C\u002Fcode> mereka nggak lagi diperlukan. Emang begitu hasilnya kalau \u003Cem>state\u003C\u002Fem> dipindahkan dari koneksi ke \u003Cem>request\u003C\u002Fem>.\u003C\u002Fp>\n\u003Cp>Satu catatan supaya nggak salah paham: stateless bukan berarti aplikasimu nggak boleh punya \u003Cem>state\u003C\u002Fem>. Kalau butuh, buat \u003Cem>handle\u003C\u002Fem> eksplisit dari sebuah \u003Cem>tool\u003C\u002Fem>, misalnya pengenal keranjang atau sesi kerja, lalu biarkan model membawanya balik sebagai argumen di panggilan berikutnya. \u003Cem>State\u003C\u002Fem>-nya pindah ke tempat yang kelihatan, bukan hilang.\u003C\u002Fp>\n\u003Ch2 id=\"yang-perlu-diwaspadai-kalau-baca-tutorial-lama\">Yang perlu diwaspadai kalau baca tutorial lama\u003C\u002Fh2>\n\u003Cp>Banyak \u003Cem>tutorial\u003C\u002Fem> MCP ditulis sebelum perubahan di atas, jadi ada beberapa jebakan yang gampang kita temui. Kalau kamu menemukan contoh yang kelihatan meyakinkan, cek dulu hal-hal ini:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Ccode>from mcp.server.fastmcp import FastMCP\u003C\u002Fcode> itu API versi lama. Sekarang yang dipakai \u003Ccode>from mcp.server import MCPServer\u003C\u002Fcode>, dan import lamanya langsung melempar \u003Ccode>ModuleNotFoundError\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>Transport HTTP+SSE sudah digantikan Streamable HTTP sejak revisi \u003Ccode>2025-03-26\u003C\u002Fcode>. Ia masih hidup demi kompatibilitas, tapi statusnya \u003Cem>deprecated\u003C\u002Fem>.\u003C\u002Fli>\n\u003Cli>Roots, Sampling, dan Logging juga \u003Cem>deprecated\u003C\u002Fem>, dengan masa transisi minimal 12 bulan. Sementara itu \u003Ccode>ping\u003C\u002Fcode> sudah dihapus dari protokol.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Artikel ini sendiri punya tanggal kedaluwarsa. Revisi spec datang dengan jarak 3 sampai 8 bulan, dengan urutan \u003Ccode>2024-11-05\u003C\u002Fcode>, \u003Ccode>2025-03-26\u003C\u002Fcode>, \u003Ccode>2025-06-18\u003C\u002Fcode>, \u003Ccode>2025-11-25\u003C\u002Fcode>, lalu \u003Ccode>2026-07-28\u003C\u002Fcode>. Versi yang dipakai di sini adalah \u003Ccode>2026-07-28\u003C\u002Fcode>, jadi kalau kamu membaca ini jauh setelahnya, \u003Ca href=\"https:\u002F\u002Fmodelcontextprotocol.io\u002Fspecification\u002Fversioning\">cek versi terbaru\u003C\u002Fa> sebelum menyalin apa pun.\u003C\u002Fp>\n\u003Ch2 id=\"server-mcp-pertama-sedikit-baris\">Server MCP pertama, sedikit baris\u003C\u002Fh2>\n\u003Cp>Cukup teorinya, sekarang kita lihat kodenya. Server di bawah nih punya satu resource berisi skema tabel dan satu \u003Cem>tool\u003C\u002Fem> pencarian. Isinya sengaja dibuat sederhana, dan fungsi pencariannya cuma mengembalikan teks, bukan \u003Cem>query\u003C\u002Fem> sungguhan.\u003C\u002Fp>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%23%20server.py%0Afrom%20mcp.server%20import%20MCPServer%0A%0Amcp%20%3D%20MCPServer(%22Invasikode%20Database%20Server%22)%0A%0A%0A%40mcp.resource(%22db%3A%2F%2Farticles%2Fschema%22)%0Adef%20get_articles_schema()%20-%3E%20str%3A%0A%20%20%20%20%22%22%22Skema%20DDL%20tabel%20artikel%2C%20buat%20konteks%20LLM.%22%22%22%0A%20%20%20%20return%20%22%22%22%0A%20%20%20%20CREATE%20TABLE%20articles%20(%0A%20%20%20%20%20%20%20%20id%20SERIAL%20PRIMARY%20KEY%2C%0A%20%20%20%20%20%20%20%20title%20VARCHAR(255)%20NOT%20NULL%2C%0A%20%20%20%20%20%20%20%20slug%20VARCHAR(255)%20UNIQUE%20NOT%20NULL%2C%0A%20%20%20%20%20%20%20%20tags%20VARCHAR(255)%2C%0A%20%20%20%20%20%20%20%20status%20VARCHAR(32)%20DEFAULT%20'draft'%0A%20%20%20%20)%3B%0A%20%20%20%20%22%22%22%0A%0A%0A%40mcp.tool()%0Adef%20search_articles_by_keyword(keyword%3A%20str%2C%20limit%3A%20int%20%3D%205)%20-%3E%20str%3A%0A%20%20%20%20%22%22%22Cari%20artikel%20berdasarkan%20kata%20kunci%20judul.%0A%0A%20%20%20%20Args%3A%0A%20%20%20%20%20%20%20%20keyword%3A%20Kata%20kunci%20pencarian.%0A%20%20%20%20%20%20%20%20limit%3A%20Batas%20maksimum%20artikel%20yang%20dikembalikan.%0A%20%20%20%20%22%22%22%0A%20%20%20%20return%20f%22Berhasil%20mengambil%20%7Blimit%7D%20artikel%20dengan%20kata%20kunci%20'%7Bkeyword%7D'.%22\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># server.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> mcp.server \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> MCPServer\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">mcp \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> MCPServer(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"Invasikode Database Server\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">@mcp.resource\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"db:\u002F\u002Farticles\u002Fschema\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">def\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> get_articles_schema\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">() -> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">str\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"\"\"Skema DDL tabel artikel, buat konteks LLM.\"\"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"\"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    CREATE TABLE articles (\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        id SERIAL PRIMARY KEY,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        title VARCHAR(255) NOT NULL,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        slug VARCHAR(255) UNIQUE NOT NULL,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        tags VARCHAR(255),\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        status VARCHAR(32) DEFAULT 'draft'\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    );\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"\"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#B392F0\">@mcp.tool\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">def\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> search_articles_by_keyword\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(keyword: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">str\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, limit: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">int\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 5\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">) -> \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">str\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"\"\"Cari artikel berdasarkan kata kunci judul.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    Args:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        keyword: Kata kunci pencarian.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">        limit: Batas maksimum artikel yang dikembalikan.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"\"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"Berhasil mengambil \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">limit\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> artikel dengan kata kunci '\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">keyword\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">'.\"\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Perhatikan apa yang nggak ada di kode tuh. Nggak ada JSON Schema yang ditulis tangan, karena \u003Cem>type hint\u003C\u002Fem> dan \u003Cem>docstring\u003C\u002Fem> sudah otomatis jadi skema. Nggak ada \u003Cem>request handler\u003C\u002Fem>, nggak ada deklarasi \u003Cem>capability\u003C\u002Fem>. Nama, deskripsi, dan skema argumen semuanya diturunkan dari fungsi Python-nya sendiri. Itulah poinnya — kamu menulis fungsi biasa, dan SDK mengurus sisanya. Kode ini sudah dijalankan pada SDK Python \u003Ccode>mcp\u003C\u002Fcode> 2.0.0, dengan protokol yang dinegosiasikan \u003Ccode>2026-07-28\u003C\u002Fcode>, dan \u003Cem>tool\u003C\u002Fem> serta resource-nya terdaftar. Ia belum diuji di \u003Cem>server\u003C\u002Fem> produksi, jadi perlakukan sebagai titik awal. Dokumentasi lengkapnya ada di \u003Ca href=\"https:\u002F\u002Fpy.sdk.modelcontextprotocol.io\u002Fget-started\u002Ffirst-steps\u002F\">panduan SDK Python\u003C\u002Fa>.\u003C\u002Fp>\n\u003Cp>Cara menjalankannya gampang kok: simpan sebagai \u003Ccode>server.py\u003C\u002Fcode>, pasang paketnya, lalu jalankan lewat SDK. Setelah itu kita daftarkan ke host. Di aplikasi desktop, biasanya lewat berkas konfigurasi seperti \u003Ccode>claude_desktop_config.json\u003C\u002Fcode>, dengan menunjuk perintah yang menjalankan servermu. Di editor, biasanya lewat ekstensi atau pengaturan MCP. Setelah terdaftar, coba tanya agent soal skema tabel artikel deh, lalu lihat apakah ia memakai resource yang baru kamu tulis 🙂.\u003C\u002Fp>\n\u003Ch2 id=\"kenapa-ini-penting-buat-kamu\">Kenapa ini penting buat kamu\u003C\u002Fh2>\n\u003Cp>Keuntungan paling nyata adalah sekali tulis, dipakai di mana-mana. Konektor ke \u003Cem>database\u003C\u002Fem> artikel yang tadi kamu tulis bisa dipakai oleh host mana pun yang mendukung MCP, tanpa perubahan di sisi \u003Cem>server\u003C\u002Fem>. Ganti model nggak lagi berarti nulis ulang konektor, dan itu menyelesaikan masalah di pembuka tadi.\u003C\u002Fp>\n\u003Cp>Kredensial juga tetap di sisimu. Server yang menyimpan token dan kunci, model cuma melihat hasil yang sudah kamu izinkan. Dan karena protokolnya kini stateless, men-\u003Cem>deploy\u003C\u002Fem> \u003Cem>server\u003C\u002Fem> MCP nggak lagi butuh trik khusus. Ia bisa diperlakukan seperti layanan HTTP lain yang sudah biasa kamu urus, lengkap dengan \u003Cem>load balancer\u003C\u002Fem> dan \u003Cem>autoscaling\u003C\u002Fem>. Itu perubahan yang sebenarnya menarik buat kamu yang kerja di backend, lho!\u003C\u002Fp>\n\u003Ch2 id=\"standarisasi-dan-siapa-yang-pegang-protokolnya\">Standarisasi dan siapa yang pegang protokolnya\u003C\u002Fh2>\n\u003Cp>MCP diperkenalkan Anthropic pada 25 November 2024. Pada Desember 2025, protokol ini didonasikan ke Agentic AI Foundation, sebuah dana terarah di bawah Linux Foundation. \u003Ca href=\"https:\u002F\u002Fwww.anthropic.com\u002Fnews\u002Fdonating-the-model-context-protocol-and-establishing-of-the-agentic-ai-foundation\">Pendirinya\u003C\u002Fa> adalah Anthropic, Block, dan OpenAI, dengan dukungan Google, Microsoft, AWS, Cloudflare, dan Bloomberg. Governance-nya nggak berubah, jadi proses pengambilan keputusan yang sudah berjalan tetap sama.\u003C\u002Fp>\n\u003Cp>Soal adopsi, tulisan donasi itu mencatat bahwa per Desember 2025 ada lebih dari 10.000 MCP \u003Cem>server\u003C\u002Fem> publik yang aktif. Protokolnya juga sudah diadopsi ChatGPT, Cursor, Gemini, Microsoft Copilot, dan VS Code. Angka itu cukup menjelaskan kenapa banyak \u003Cem>developer\u003C\u002Fem> memutuskan belajar MCP sekarang, bukan nanti 🚀.\u003C\u002Fp>\n\u003Cp>Jadi, kalau endpoint internalmu sudah menunggu ditempelkan ke agent, kamu sudah punya jalan pintasnya. Mulai dari satu fungsi kecil, biarkan type hint jadi skema, dan simpan konektor lima puluh itu sebagai cerita lama. Tinggal pastikan versi spec yang kamu pakai sama dengan yang dipakai host-mu.\u003C\u002Fp>\n","\u003Cul>\n\u003Cli>Model Context Protocol mengubah integrasi model-ke-sumber-data dari puluhan konektor buatan sendiri jadi satu protokol terbuka yang dipakai bersama.\u003C\u002Fli>\n\u003Cli>Server MCP membagi peran dengan rapi: tool dipanggil model, resource dibaca aplikasi, dan prompt dipilih user.\u003C\u002Fli>\n\u003Cli>Kredensial tetap di sisi server dan nggak pernah masuk ke prompt, karena server memang nggak boleh membaca seluruh percakapan.\u003C\u002Fli>\n\u003Cli>Sejak spec 2026-07-28 protokolnya stateless, jadi server MCP bisa dideploy seperti workload HTTP biasa tanpa sesi yang harus dijaga.\u003C\u002Fli>\n\u003Cli>Kalau tutorial yang kamu baca masih memakai FastMCP atau transport SSE, itu versi lama: nama API-nya sudah pindah dan transportnya sudah deprecated.\u003C\u002Fli>\n\u003C\u002Ful>\n",[118,129,138,147,156,167],{"id":119,"title":120,"slug":121,"excerpt":122,"thumbnail_image":48,"tags":123},"124","Rahasia Zero-Cost Abstraction di Rust, Dibedah dari Assembly","rahasia-zero-cost-abstraction-di-rust","\"Abstraksi tinggi selalu lebih lambat\" itu anggapan lama. Iterator Rust bisa menyamai loop manual, dan assembly-nya bisa kita baca sendiri. Yuk, kita bongkar!",[124,125,126,127,128],"rust","performance","system-programming","compiler","optimasi",{"id":130,"title":131,"slug":132,"excerpt":133,"thumbnail_image":48,"tags":134},"111","Rust Masuk Kernel Linux: Revolusi Nyata atau Cuma Euforia RIIR?","rust-di-kernel-linux-revolusi-atau-cuma-hype","Selama lebih dari 30 tahun kernel Linux cuma mau bahasa C, lalu tiba-tiba Rust resmi masuk di Linux 6.1. Itu revolusi beneran atau cuma kebawa euforia meme Rewrite It In Rust? Yuk lihat datanya, bukan cuma opininya.",[124,135,136,126,137],"linux","kernel","memory-safety",{"id":139,"title":140,"slug":141,"excerpt":142,"thumbnail_image":48,"tags":143},"112","Aplikasimu lambat, dan kamu udah kepikiran ganti bahasa. Tunggu dulu","aplikasimu-lambat-dan-kamu-udah-kepikiran-ganti-bahasa-tunggu-dulu","Ada endpoint yang grafiknya spike tiap beberapa menit, dan kepikiran buat pindah dari Go ke Rust? Discord dan Cloudflare beneran melakukannya — tapi cuma setelah kehabisan cara lain dan punya datanya. Yuk, bedah gejala mana yang beneran butuh rewrite, dan mana yang cuma butuh profiling. 🤔",[59,125,144,124,145,146],"golang","system-design","profiling",{"id":148,"title":149,"slug":150,"excerpt":151,"thumbnail_image":48,"tags":152},"113","Garbage Collector dituduh bikin aplikasi lemot. Seberapa adil tuduhan itu?","garbage-collector-dituduh-bikin-aplikasi-lemot","GC sering jadi tersangka utama tiap aplikasi melambat, dan banyak yang percaya dia jalan pakai timer tiap beberapa detik. Dua-duanya nggak sepenuhnya benar. Yuk bedah cara kerja GC dari dalam, plus satu pengecualian yang bikin Discord kesakitan tiap 2 menit. 🤔",[59,125,144,153,154,155],"jvm","garbage-collector","memory",{"id":157,"title":158,"slug":159,"excerpt":160,"thumbnail_image":48,"tags":161},"118","Belajar Idempotency dari Stok yang Keburu Kebeli","pub-sub-sendiri-lalu-belajar-idempotency","Tugas pertama saya di kerjaan pertama: sistem yang kewalahan menerima webhook. Saya putuskan membangun pub\u002Fsub sendiri dari nol, dan pelajaran yang akhirnya datang bukan dari situ — tapi dari stok gudang yang keburu kebeli orang.",[162,163,164,165,166],"idempotency","event-driven","celery","rabbitmq","post-mortem",{"id":49,"title":50,"slug":51,"excerpt":52,"thumbnail_image":48,"tags":168},[55,56,57,58,59,60],[170,174,177,180,183,186,189,192],{"text":171,"depth":172,"id":173},"Kenapa masalah remeh ini mahal?",2,"kenapa-masalah-remeh-ini-mahal",{"text":175,"depth":172,"id":176},"Siapa yang ngobrol dengan siapa","siapa-yang-ngobrol-dengan-siapa",{"text":178,"depth":172,"id":179},"Tiga primitif, dan siapa yang pegang kendali","tiga-primitif-dan-siapa-yang-pegang-kendali",{"text":181,"depth":172,"id":182},"Kenapa protokolnya dibongkar ulang","kenapa-protokolnya-dibongkar-ulang",{"text":184,"depth":172,"id":185},"Yang perlu diwaspadai kalau baca tutorial lama","yang-perlu-diwaspadai-kalau-baca-tutorial-lama",{"text":187,"depth":172,"id":188},"Server MCP pertama, sedikit baris","server-mcp-pertama-sedikit-baris",{"text":190,"depth":172,"id":191},"Kenapa ini penting buat kamu","kenapa-ini-penting-buat-kamu",{"text":193,"depth":172,"id":194},"Standarisasi dan siapa yang pegang protokolnya","standarisasi-dan-siapa-yang-pegang-protokolnya",1792112616062]