[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-membangun-server-mcp-pertama-panduan-praktis-developer":3},{"article":4,"author":50},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":30,"related_articles":31},"d0000000-0000-0000-0000-000000000501","a0000000-0000-0000-0000-000000000026","Membangun Server MCP Pertama Anda: Panduan Praktis untuk Developer","membangun-server-mcp-pertama-panduan-praktis-developer","Tutorial langkah demi langkah untuk membangun server Model Context Protocol (MCP) di TypeScript dan Python, menghubungkannya ke Claude Desktop atau Cursor, dan men-deploy ke produksi.","## Apa Itu Model Context Protocol (MCP)?\n\n**Model Context Protocol (MCP)** adalah standar terbuka yang dibuat oleh Anthropic yang mendefinisikan cara aplikasi AI berkomunikasi dengan sumber data dan alat eksternal. Bayangkan MCP sebagai **USB-C untuk integrasi AI**: seperti USB-C yang menyediakan satu konektor universal untuk pengisian daya, transfer data, dan output tampilan, MCP menyediakan satu protokol universal untuk menghubungkan model AI ke database, API, sistem file, dan layanan lainnya. MCP menghilangkan kebutuhan akan integrasi khusus antara setiap aplikasi AI dan setiap alat.\n\nPada tahun 2026, MCP telah menjadi standar dominan untuk komunikasi AI-alat. Gartner memprediksi bahwa **40% aplikasi enterprise akan menyertakan AI agent pada akhir 2026**, dan MCP adalah protokol yang membuatnya praktis dalam skala besar. Sebelum MCP, menghubungkan model AI ke N alat memerlukan N integrasi khusus. Dengan M aplikasi AI dan N alat, Anda memerlukan M x N adapter integrasi. MCP mengurangi ini menjadi M + N: setiap aplikasi AI mengimplementasikan satu MCP client, setiap alat mengimplementasikan satu MCP server.\n\n## Arsitektur MCP: Host, Client, Server, dan Transport\n\nMemahami arsitektur MCP sangat penting sebelum menulis kode apa pun. Protokol ini mendefinisikan empat peran kunci:\n\n| Komponen | Peran | Contoh |\n|----------|-------|--------|\n| **Host** | Aplikasi AI yang berinteraksi dengan pengguna akhir | Claude Desktop, Cursor, VS Code Copilot |\n| **Client** | Handler protokol MCP di dalam host | Dibangun ke dalam aplikasi host |\n| **Server** | Menyediakan tools, resources, dan prompts melalui MCP | Server kustom Anda (yang akan kita bangun) |\n| **Transport** | Lapisan komunikasi antara client dan server | stdio, HTTP+SSE, Streamable HTTP |\n\nAlur komunikasi bekerja seperti ini:\n\n1. **Host** memulai dan menginisialisasi MCP **client** untuk setiap server yang dikonfigurasi.\n2. **Client** terhubung ke **server** melalui **transport** (stdio untuk lokal, HTTP untuk remote).\n3. **Client** mengirim permintaan `initialize`, menegosiasikan versi protokol dan kemampuan.\n4. **Server** merespons dengan **tools**, **resources**, dan **prompts** yang tersedia.\n5. Ketika model AI membutuhkan data atau tindakan eksternal, **client** memanggil metode server yang sesuai.\n6. **Server** mengeksekusi operasi dan mengembalikan hasil melalui pesan JSON-RPC 2.0.\n\n### Tools vs Resources vs Prompts\n\nMCP server dapat menyediakan tiga jenis kemampuan:\n\n- **Tools** adalah fungsi yang dapat dipanggil oleh model AI. Mereka menerima input terstruktur dan mengembalikan output terstruktur. Contoh: `query_database(sql: string)` atau `send_email(to: string, subject: string, body: string)`.\n- **Resources** adalah data yang dapat dibaca oleh model AI. Mereka diidentifikasi oleh URI dan mengembalikan konten. Contoh: `file:\u002F\u002F\u002Fpath\u002Fto\u002Fdocument.md` atau `postgres:\u002F\u002Flocalhost\u002Fmydb\u002Fusers`.\n- **Prompts** adalah template prompt yang dapat digunakan kembali yang disediakan server. Mereka membantu menstandarkan cara AI berinteraksi dengan domain server. Contoh: template `summarize_ticket` untuk Jira MCP server.\n\n## Langkah demi Langkah: Membangun MCP Server di TypeScript\n\nMari kita bangun MCP server praktis yang menyediakan tool untuk melakukan query ke database SQLite. Ini adalah kasus penggunaan umum: memberikan model AI akses baca-saja yang aman ke data aplikasi Anda.\n\n### Langkah 1: Inisialisasi Proyek\n\n```bash\nmkdir mcp-sqlite-server && cd mcp-sqlite-server\nnpm init -y\nnpm install @modelcontextprotocol\u002Fsdk better-sqlite3\nnpm install -D typescript @types\u002Fnode @types\u002Fbetter-sqlite3\nnpx tsc --init\n```\n\nKonfigurasi `tsconfig.json`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"outDir\": \".\u002Fdist\",\n    \"rootDir\": \".\u002Fsrc\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"declaration\": true\n  },\n  \"include\": [\"src\u002F**\u002F*\"]\n}\n```\n\n### Langkah 2: Implementasi Server\n\nBuat `src\u002Findex.ts`:\n\n```typescript\nimport { McpServer } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\";\nimport Database from \"better-sqlite3\";\nimport { z } from \"zod\";\n\nconst db = new Database(process.env.DB_PATH || \".\u002Fdata.db\", {\n  readonly: true,\n});\n\nconst server = new McpServer({\n  name: \"sqlite-query\",\n  version: \"1.0.0\",\n});\n\nserver.tool(\n  \"query\",\n  \"Eksekusi query SQL read-only terhadap database SQLite\",\n  {\n    sql: z.string().describe(\"Query SQL SELECT yang akan dieksekusi\"),\n  },\n  async ({ sql }) => {\n    const normalized = sql.trim().toUpperCase();\n    if (!normalized.startsWith(\"SELECT\")) {\n      return {\n        content: [{ type: \"text\", text: \"Error: Hanya query SELECT yang diperbolehkan.\" }],\n        isError: true,\n      };\n    }\n    try {\n      const rows = db.prepare(sql).all();\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(rows, null, 2) }],\n      };\n    } catch (error) {\n      return {\n        content: [{ type: \"text\", text: `Error query: ${(error as Error).message}` }],\n        isError: true,\n      };\n    }\n  }\n);\n\nserver.tool(\n  \"list_tables\",\n  \"Daftar semua tabel dalam database beserta skemanya\",\n  {},\n  async () => {\n    const tables = db\n      .prepare(\n        `SELECT name, sql FROM sqlite_master\n         WHERE type='table' AND name NOT LIKE 'sqlite_%'\n         ORDER BY name`\n      )\n      .all();\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(tables, null, 2) }],\n    };\n  }\n);\n```\n\n### Langkah 3: Build dan Uji Secara Lokal\n\n```bash\nnpx tsc\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-03-26\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' | node dist\u002Findex.js\n```\n\nAnda akan melihat respons JSON-RPC dengan kemampuan server.\n\n### Langkah 4: Bangun Server yang Sama di Python\n\nUntuk developer Python, berikut implementasi setara menggunakan SDK Python MCP resmi:\n\n```python\nimport sqlite3\nimport json\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"sqlite-query\")\nDB_PATH = \"data.db\"\n\n@mcp.tool()\ndef query(sql: str) -> str:\n    \"\"\"Eksekusi query SQL read-only terhadap database SQLite.\"\"\"\n    normalized = sql.strip().upper()\n    if not normalized.startswith(\"SELECT\"):\n        raise ValueError(\"Hanya query SELECT yang diperbolehkan.\")\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(sql)\n        rows = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(rows, indent=2, default=str)\n    finally:\n        conn.close()\n\n@mcp.tool()\ndef list_tables() -> str:\n    \"\"\"Daftar semua tabel dalam database beserta skemanya.\"\"\"\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(\n            \"SELECT name, sql FROM sqlite_master \"\n            \"WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n        )\n        tables = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(tables, indent=2)\n    finally:\n        conn.close()\n\nif __name__ == \"__main__\":\n    mcp.run(transport=\"stdio\")\n```\n\n## Menghubungkan ke Claude Desktop\n\nClaude Desktop mendukung MCP server secara native. Untuk menghubungkan server Anda, edit file konfigurasi Claude Desktop:\n\n**macOS:** `~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.json`\n**Windows:** `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \"\u002Fabsolute\u002Fpath\u002Fto\u002Fyour\u002Fdata.db\"\n      }\n    }\n  }\n}\n```\n\nRestart Claude Desktop. Anda akan melihat ikon palu di antarmuka chat yang menunjukkan tool MCP yang tersedia. Sekarang Anda dapat bertanya kepada Claude seperti \"Tabel apa saja yang ada di database?\" atau \"Tampilkan 10 pengguna teratas berdasarkan tanggal pendaftaran\" dan Claude akan menggunakan MCP server Anda untuk melakukan query database secara langsung.\n\n## Menghubungkan ke Cursor\n\nCursor juga mendukung MCP server. Tambahkan konfigurasi ke `.cursor\u002Fmcp.json` di root proyek Anda:\n\n```json\n{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\".\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \".\u002Fdata.db\"\n      }\n    }\n  }\n}\n```\n\nSetelah menyimpan, restart Cursor. Tool MCP akan muncul di panel asisten AI dan dapat dipanggil selama sesi pembuatan kode dan debugging.\n\n## Pengujian dan Debugging MCP Server Anda\n\n### Menggunakan MCP Inspector\n\nMCP Inspector adalah tool debugging resmi. Ini menyediakan antarmuka web untuk berinteraksi dengan server Anda:\n\n```bash\nnpx @modelcontextprotocol\u002Finspector node dist\u002Findex.js\n```\n\nIni membuka antarmuka browser di `http:\u002F\u002Flocalhost:5173` di mana Anda dapat:\n\n- Melihat semua tools, resources, dan prompts yang terdaftar\n- Memanggil tools dengan input kustom dan memeriksa respons\n- Memantau aliran pesan JSON-RPC secara real time\n- Menguji penanganan error dengan mengirim permintaan yang salah format\n\n### Masalah Debugging Umum\n\n| Masalah | Penyebab | Solusi |\n|---------|----------|--------|\n| Server tidak muncul di Claude Desktop | Path konfigurasi atau error sintaks JSON | Validasi JSON, periksa path absolut |\n| Error \"Tool not found\" | Server tidak mendaftarkan tools sebelum connect | Daftarkan tools sebelum memanggil `server.connect()` |\n| Timeout pada panggilan tool | Operasi berjalan lama tanpa progres | Tambahkan notifikasi progres via `server.sendProgress()` |\n| Output stderr merusak protokol | Console.log menulis ke stdout (transport stdio) | Gunakan `console.error()` untuk logging dengan stdio |\n| Koneksi terputus setelah idle | Timeout transport | Implementasikan heartbeat atau gunakan transport HTTP |\n\n## Praktik Terbaik untuk Produksi\n\n1. **Validasi input**: Selalu validasi dan sanitasi input tool. Gunakan skema Zod (TypeScript) atau model Pydantic (Python) untuk pemeriksaan tipe yang ketat.\n\n2. **Read-only secara default**: Mulai dengan akses read-only. Hanya tambahkan kemampuan tulis ketika benar-benar diperlukan, dan selalu minta konfirmasi untuk operasi destruktif.\n\n3. **Penanganan error**: Kembalikan pesan error terstruktur dengan `isError: true`. Jangan pernah mengekspos stack trace internal atau string koneksi database.\n\n4. **Logging**: Log semua pemanggilan tool dengan timestamp, input, dan durasi eksekusi. Gunakan stderr untuk log (bukan stdout) saat menggunakan transport stdio.\n\n5. **Rate limiting**: Implementasikan batas rate per-tool untuk mencegah loop AI yang tidak terkendali dari membanjiri layanan backend Anda.\n\n6. **Timeout**: Tetapkan timeout eksekusi pada semua handler tool. Model AI mungkin memanggil tool yang memicu query mahal — lindungi infrastruktur Anda.\n\n7. **Pemisahan environment**: Gunakan variabel environment untuk semua konfigurasi. Jangan pernah hardcode URL database, API key, atau path file.\n\n8. **Versioning**: Ikuti semantic versioning untuk MCP server Anda. Handshake `initialize` mencakup negosiasi versi — perubahan breaking memerlukan bump versi major.\n\n## FAQ\n\n**T: Apa perbedaan antara MCP dan function calling?**\nJ: Function calling (digunakan oleh OpenAI, Anthropic, dan lainnya) mendefinisikan tools secara inline dalam setiap permintaan API. MCP mengeksternalisasi definisi tool ke server mandiri yang dapat ditemukan dan digunakan oleh host yang kompatibel dengan MCP. Function calling bersifat per-permintaan; MCP adalah protokol persisten dengan sesi stateful.\n\n**T: Bisakah saya menggunakan MCP dengan model selain Claude?**\nJ: Ya. MCP adalah protokol terbuka. OpenAI, Google DeepMind, dan Microsoft telah mengadopsi dukungan MCP di platform mereka sejak awal 2026. Aplikasi AI apa pun yang mengimplementasikan MCP client dapat terhubung ke MCP server mana pun.\n\n**T: Apakah MCP hanya untuk tool lokal?**\nJ: Tidak. Meskipun transport stdio dirancang untuk server lokal, transport HTTP+SSE dan Streamable HTTP mendukung MCP server remote. Anda dapat men-deploy MCP server sebagai layanan cloud yang dapat diakses melalui jaringan.\n\n**T: Bagaimana MCP menangani autentikasi?**\nJ: Protokol ini mendukung OAuth 2.0 untuk server remote. Server stdio lokal mewarisi konteks keamanan dari proses host. Untuk deployment enterprise, MCP gateway dapat memusatkan autentikasi dan otorisasi.\n\n**T: Bahasa apa yang dapat digunakan untuk membangun MCP server?**\nJ: SDK resmi tersedia untuk TypeScript, Python, Java, Kotlin, C#, dan Swift. SDK komunitas mencakup Rust, Go, Ruby, dan PHP. Protokolnya agnostik bahasa — bahasa apa pun yang dapat membaca\u002Fmenulis JSON-RPC melalui stdio atau HTTP dapat mengimplementasikan MCP server.\n\n**T: Bagaimana cara memperbarui MCP server tanpa me-restart host?**\nJ: MCP mendukung notifikasi perubahan kemampuan. Ketika tools server Anda berubah, server dapat mengirim pesan `notifications\u002Ftools\u002Flist_changed`, yang mendorong client untuk mengambil ulang daftar tool. Untuk server stdio, host biasanya perlu restart. Server HTTP dapat diperbarui tanpa restart host.","\u003Ch2 id=\"apa-itu-model-context-protocol-mcp\">Apa Itu Model Context Protocol (MCP)?\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Model Context Protocol (MCP)\u003C\u002Fstrong> adalah standar terbuka yang dibuat oleh Anthropic yang mendefinisikan cara aplikasi AI berkomunikasi dengan sumber data dan alat eksternal. Bayangkan MCP sebagai \u003Cstrong>USB-C untuk integrasi AI\u003C\u002Fstrong>: seperti USB-C yang menyediakan satu konektor universal untuk pengisian daya, transfer data, dan output tampilan, MCP menyediakan satu protokol universal untuk menghubungkan model AI ke database, API, sistem file, dan layanan lainnya. MCP menghilangkan kebutuhan akan integrasi khusus antara setiap aplikasi AI dan setiap alat.\u003C\u002Fp>\n\u003Cp>Pada tahun 2026, MCP telah menjadi standar dominan untuk komunikasi AI-alat. Gartner memprediksi bahwa \u003Cstrong>40% aplikasi enterprise akan menyertakan AI agent pada akhir 2026\u003C\u002Fstrong>, dan MCP adalah protokol yang membuatnya praktis dalam skala besar. Sebelum MCP, menghubungkan model AI ke N alat memerlukan N integrasi khusus. Dengan M aplikasi AI dan N alat, Anda memerlukan M x N adapter integrasi. MCP mengurangi ini menjadi M + N: setiap aplikasi AI mengimplementasikan satu MCP client, setiap alat mengimplementasikan satu MCP server.\u003C\u002Fp>\n\u003Ch2 id=\"arsitektur-mcp-host-client-server-dan-transport\">Arsitektur MCP: Host, Client, Server, dan Transport\u003C\u002Fh2>\n\u003Cp>Memahami arsitektur MCP sangat penting sebelum menulis kode apa pun. Protokol ini mendefinisikan empat peran kunci:\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Komponen\u003C\u002Fth>\u003Cth>Peran\u003C\u002Fth>\u003Cth>Contoh\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Cstrong>Host\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Aplikasi AI yang berinteraksi dengan pengguna akhir\u003C\u002Ftd>\u003Ctd>Claude Desktop, Cursor, VS Code Copilot\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Client\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Handler protokol MCP di dalam host\u003C\u002Ftd>\u003Ctd>Dibangun ke dalam aplikasi host\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Server\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Menyediakan tools, resources, dan prompts melalui MCP\u003C\u002Ftd>\u003Ctd>Server kustom Anda (yang akan kita bangun)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Transport\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>Lapisan komunikasi antara client dan server\u003C\u002Ftd>\u003Ctd>stdio, HTTP+SSE, Streamable HTTP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>Alur komunikasi bekerja seperti ini:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Host\u003C\u002Fstrong> memulai dan menginisialisasi MCP \u003Cstrong>client\u003C\u002Fstrong> untuk setiap server yang dikonfigurasi.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Client\u003C\u002Fstrong> terhubung ke \u003Cstrong>server\u003C\u002Fstrong> melalui \u003Cstrong>transport\u003C\u002Fstrong> (stdio untuk lokal, HTTP untuk remote).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Client\u003C\u002Fstrong> mengirim permintaan \u003Ccode>initialize\u003C\u002Fcode>, menegosiasikan versi protokol dan kemampuan.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Server\u003C\u002Fstrong> merespons dengan \u003Cstrong>tools\u003C\u002Fstrong>, \u003Cstrong>resources\u003C\u002Fstrong>, dan \u003Cstrong>prompts\u003C\u002Fstrong> yang tersedia.\u003C\u002Fli>\n\u003Cli>Ketika model AI membutuhkan data atau tindakan eksternal, \u003Cstrong>client\u003C\u002Fstrong> memanggil metode server yang sesuai.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Server\u003C\u002Fstrong> mengeksekusi operasi dan mengembalikan hasil melalui pesan JSON-RPC 2.0.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch3>Tools vs Resources vs Prompts\u003C\u002Fh3>\n\u003Cp>MCP server dapat menyediakan tiga jenis kemampuan:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Tools\u003C\u002Fstrong> adalah fungsi yang dapat dipanggil oleh model AI. Mereka menerima input terstruktur dan mengembalikan output terstruktur. Contoh: \u003Ccode>query_database(sql: string)\u003C\u002Fcode> atau \u003Ccode>send_email(to: string, subject: string, body: string)\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Resources\u003C\u002Fstrong> adalah data yang dapat dibaca oleh model AI. Mereka diidentifikasi oleh URI dan mengembalikan konten. Contoh: \u003Ccode>file:\u002F\u002F\u002Fpath\u002Fto\u002Fdocument.md\u003C\u002Fcode> atau \u003Ccode>postgres:\u002F\u002Flocalhost\u002Fmydb\u002Fusers\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Prompts\u003C\u002Fstrong> adalah template prompt yang dapat digunakan kembali yang disediakan server. Mereka membantu menstandarkan cara AI berinteraksi dengan domain server. Contoh: template \u003Ccode>summarize_ticket\u003C\u002Fcode> untuk Jira MCP server.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"langkah-demi-langkah-membangun-mcp-server-di-typescript\">Langkah demi Langkah: Membangun MCP Server di TypeScript\u003C\u002Fh2>\n\u003Cp>Mari kita bangun MCP server praktis yang menyediakan tool untuk melakukan query ke database SQLite. Ini adalah kasus penggunaan umum: memberikan model AI akses baca-saja yang aman ke data aplikasi Anda.\u003C\u002Fp>\n\u003Ch3>Langkah 1: Inisialisasi Proyek\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-bash\">mkdir mcp-sqlite-server &amp;&amp; cd mcp-sqlite-server\nnpm init -y\nnpm install @modelcontextprotocol\u002Fsdk better-sqlite3\nnpm install -D typescript @types\u002Fnode @types\u002Fbetter-sqlite3\nnpx tsc --init\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Konfigurasi \u003Ccode>tsconfig.json\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"outDir\": \".\u002Fdist\",\n    \"rootDir\": \".\u002Fsrc\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"declaration\": true\n  },\n  \"include\": [\"src\u002F**\u002F*\"]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Langkah 2: Implementasi Server\u003C\u002Fh3>\n\u003Cp>Buat \u003Ccode>src\u002Findex.ts\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">import { McpServer } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\";\nimport Database from \"better-sqlite3\";\nimport { z } from \"zod\";\n\nconst db = new Database(process.env.DB_PATH || \".\u002Fdata.db\", {\n  readonly: true,\n});\n\nconst server = new McpServer({\n  name: \"sqlite-query\",\n  version: \"1.0.0\",\n});\n\nserver.tool(\n  \"query\",\n  \"Eksekusi query SQL read-only terhadap database SQLite\",\n  {\n    sql: z.string().describe(\"Query SQL SELECT yang akan dieksekusi\"),\n  },\n  async ({ sql }) =&gt; {\n    const normalized = sql.trim().toUpperCase();\n    if (!normalized.startsWith(\"SELECT\")) {\n      return {\n        content: [{ type: \"text\", text: \"Error: Hanya query SELECT yang diperbolehkan.\" }],\n        isError: true,\n      };\n    }\n    try {\n      const rows = db.prepare(sql).all();\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(rows, null, 2) }],\n      };\n    } catch (error) {\n      return {\n        content: [{ type: \"text\", text: `Error query: ${(error as Error).message}` }],\n        isError: true,\n      };\n    }\n  }\n);\n\nserver.tool(\n  \"list_tables\",\n  \"Daftar semua tabel dalam database beserta skemanya\",\n  {},\n  async () =&gt; {\n    const tables = db\n      .prepare(\n        `SELECT name, sql FROM sqlite_master\n         WHERE type='table' AND name NOT LIKE 'sqlite_%'\n         ORDER BY name`\n      )\n      .all();\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(tables, null, 2) }],\n    };\n  }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Langkah 3: Build dan Uji Secara Lokal\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-bash\">npx tsc\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-03-26\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' | node dist\u002Findex.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Anda akan melihat respons JSON-RPC dengan kemampuan server.\u003C\u002Fp>\n\u003Ch3>Langkah 4: Bangun Server yang Sama di Python\u003C\u002Fh3>\n\u003Cp>Untuk developer Python, berikut implementasi setara menggunakan SDK Python MCP resmi:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-python\">import sqlite3\nimport json\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"sqlite-query\")\nDB_PATH = \"data.db\"\n\n@mcp.tool()\ndef query(sql: str) -&gt; str:\n    \"\"\"Eksekusi query SQL read-only terhadap database SQLite.\"\"\"\n    normalized = sql.strip().upper()\n    if not normalized.startswith(\"SELECT\"):\n        raise ValueError(\"Hanya query SELECT yang diperbolehkan.\")\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(sql)\n        rows = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(rows, indent=2, default=str)\n    finally:\n        conn.close()\n\n@mcp.tool()\ndef list_tables() -&gt; str:\n    \"\"\"Daftar semua tabel dalam database beserta skemanya.\"\"\"\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(\n            \"SELECT name, sql FROM sqlite_master \"\n            \"WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n        )\n        tables = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(tables, indent=2)\n    finally:\n        conn.close()\n\nif __name__ == \"__main__\":\n    mcp.run(transport=\"stdio\")\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"menghubungkan-ke-claude-desktop\">Menghubungkan ke Claude Desktop\u003C\u002Fh2>\n\u003Cp>Claude Desktop mendukung MCP server secara native. Untuk menghubungkan server Anda, edit file konfigurasi Claude Desktop:\u003C\u002Fp>\n\u003Cp>\u003Cstrong>macOS:\u003C\u002Fstrong> \u003Ccode>~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.json\u003C\u002Fcode>\n\u003Cstrong>Windows:\u003C\u002Fstrong> \u003Ccode>%APPDATA%\\Claude\\claude_desktop_config.json\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \"\u002Fabsolute\u002Fpath\u002Fto\u002Fyour\u002Fdata.db\"\n      }\n    }\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Restart Claude Desktop. Anda akan melihat ikon palu di antarmuka chat yang menunjukkan tool MCP yang tersedia. Sekarang Anda dapat bertanya kepada Claude seperti “Tabel apa saja yang ada di database?” atau “Tampilkan 10 pengguna teratas berdasarkan tanggal pendaftaran” dan Claude akan menggunakan MCP server Anda untuk melakukan query database secara langsung.\u003C\u002Fp>\n\u003Ch2 id=\"menghubungkan-ke-cursor\">Menghubungkan ke Cursor\u003C\u002Fh2>\n\u003Cp>Cursor juga mendukung MCP server. Tambahkan konfigurasi ke \u003Ccode>.cursor\u002Fmcp.json\u003C\u002Fcode> di root proyek Anda:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\".\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \".\u002Fdata.db\"\n      }\n    }\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Setelah menyimpan, restart Cursor. Tool MCP akan muncul di panel asisten AI dan dapat dipanggil selama sesi pembuatan kode dan debugging.\u003C\u002Fp>\n\u003Ch2 id=\"pengujian-dan-debugging-mcp-server-anda\">Pengujian dan Debugging MCP Server Anda\u003C\u002Fh2>\n\u003Ch3>Menggunakan MCP Inspector\u003C\u002Fh3>\n\u003Cp>MCP Inspector adalah tool debugging resmi. Ini menyediakan antarmuka web untuk berinteraksi dengan server Anda:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">npx @modelcontextprotocol\u002Finspector node dist\u002Findex.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Ini membuka antarmuka browser di \u003Ccode>http:\u002F\u002Flocalhost:5173\u003C\u002Fcode> di mana Anda dapat:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Melihat semua tools, resources, dan prompts yang terdaftar\u003C\u002Fli>\n\u003Cli>Memanggil tools dengan input kustom dan memeriksa respons\u003C\u002Fli>\n\u003Cli>Memantau aliran pesan JSON-RPC secara real time\u003C\u002Fli>\n\u003Cli>Menguji penanganan error dengan mengirim permintaan yang salah format\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>Masalah Debugging Umum\u003C\u002Fh3>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Masalah\u003C\u002Fth>\u003Cth>Penyebab\u003C\u002Fth>\u003Cth>Solusi\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Server tidak muncul di Claude Desktop\u003C\u002Ftd>\u003Ctd>Path konfigurasi atau error sintaks JSON\u003C\u002Ftd>\u003Ctd>Validasi JSON, periksa path absolut\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Error “Tool not found”\u003C\u002Ftd>\u003Ctd>Server tidak mendaftarkan tools sebelum connect\u003C\u002Ftd>\u003Ctd>Daftarkan tools sebelum memanggil \u003Ccode>server.connect()\u003C\u002Fcode>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Timeout pada panggilan tool\u003C\u002Ftd>\u003Ctd>Operasi berjalan lama tanpa progres\u003C\u002Ftd>\u003Ctd>Tambahkan notifikasi progres via \u003Ccode>server.sendProgress()\u003C\u002Fcode>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Output stderr merusak protokol\u003C\u002Ftd>\u003Ctd>Console.log menulis ke stdout (transport stdio)\u003C\u002Ftd>\u003Ctd>Gunakan \u003Ccode>console.error()\u003C\u002Fcode> untuk logging dengan stdio\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Koneksi terputus setelah idle\u003C\u002Ftd>\u003Ctd>Timeout transport\u003C\u002Ftd>\u003Ctd>Implementasikan heartbeat atau gunakan transport HTTP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"praktik-terbaik-untuk-produksi\">Praktik Terbaik untuk Produksi\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>Validasi input\u003C\u002Fstrong>: Selalu validasi dan sanitasi input tool. Gunakan skema Zod (TypeScript) atau model Pydantic (Python) untuk pemeriksaan tipe yang ketat.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Read-only secara default\u003C\u002Fstrong>: Mulai dengan akses read-only. Hanya tambahkan kemampuan tulis ketika benar-benar diperlukan, dan selalu minta konfirmasi untuk operasi destruktif.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Penanganan error\u003C\u002Fstrong>: Kembalikan pesan error terstruktur dengan \u003Ccode>isError: true\u003C\u002Fcode>. Jangan pernah mengekspos stack trace internal atau string koneksi database.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Logging\u003C\u002Fstrong>: Log semua pemanggilan tool dengan timestamp, input, dan durasi eksekusi. Gunakan stderr untuk log (bukan stdout) saat menggunakan transport stdio.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Rate limiting\u003C\u002Fstrong>: Implementasikan batas rate per-tool untuk mencegah loop AI yang tidak terkendali dari membanjiri layanan backend Anda.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Timeout\u003C\u002Fstrong>: Tetapkan timeout eksekusi pada semua handler tool. Model AI mungkin memanggil tool yang memicu query mahal — lindungi infrastruktur Anda.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Pemisahan environment\u003C\u002Fstrong>: Gunakan variabel environment untuk semua konfigurasi. Jangan pernah hardcode URL database, API key, atau path file.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Versioning\u003C\u002Fstrong>: Ikuti semantic versioning untuk MCP server Anda. Handshake \u003Ccode>initialize\u003C\u002Fcode> mencakup negosiasi versi — perubahan breaking memerlukan bump versi major.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"faq\">FAQ\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>T: Apa perbedaan antara MCP dan function calling?\u003C\u002Fstrong>\nJ: Function calling (digunakan oleh OpenAI, Anthropic, dan lainnya) mendefinisikan tools secara inline dalam setiap permintaan API. MCP mengeksternalisasi definisi tool ke server mandiri yang dapat ditemukan dan digunakan oleh host yang kompatibel dengan MCP. Function calling bersifat per-permintaan; MCP adalah protokol persisten dengan sesi stateful.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bisakah saya menggunakan MCP dengan model selain Claude?\u003C\u002Fstrong>\nJ: Ya. MCP adalah protokol terbuka. OpenAI, Google DeepMind, dan Microsoft telah mengadopsi dukungan MCP di platform mereka sejak awal 2026. Aplikasi AI apa pun yang mengimplementasikan MCP client dapat terhubung ke MCP server mana pun.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Apakah MCP hanya untuk tool lokal?\u003C\u002Fstrong>\nJ: Tidak. Meskipun transport stdio dirancang untuk server lokal, transport HTTP+SSE dan Streamable HTTP mendukung MCP server remote. Anda dapat men-deploy MCP server sebagai layanan cloud yang dapat diakses melalui jaringan.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bagaimana MCP menangani autentikasi?\u003C\u002Fstrong>\nJ: Protokol ini mendukung OAuth 2.0 untuk server remote. Server stdio lokal mewarisi konteks keamanan dari proses host. Untuk deployment enterprise, MCP gateway dapat memusatkan autentikasi dan otorisasi.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bahasa apa yang dapat digunakan untuk membangun MCP server?\u003C\u002Fstrong>\nJ: SDK resmi tersedia untuk TypeScript, Python, Java, Kotlin, C#, dan Swift. SDK komunitas mencakup Rust, Go, Ruby, dan PHP. Protokolnya agnostik bahasa — bahasa apa pun yang dapat membaca\u002Fmenulis JSON-RPC melalui stdio atau HTTP dapat mengimplementasikan MCP server.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bagaimana cara memperbarui MCP server tanpa me-restart host?\u003C\u002Fstrong>\nJ: MCP mendukung notifikasi perubahan kemampuan. Ketika tools server Anda berubah, server dapat mengirim pesan \u003Ccode>notifications\u002Ftools\u002Flist_changed\u003C\u002Fcode>, yang mendorong client untuk mengambil ulang daftar tool. Untuk server stdio, host biasanya perlu restart. Server HTTP dapat diperbarui tanpa restart host.\u003C\u002Fp>\n","id","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:38.342974Z","Tutorial langkah demi langkah untuk membangun MCP server di TypeScript dan Python. Hubungkan ke Claude Desktop atau Cursor, uji dengan MCP Inspector, dan deploy ke produksi.","tutorial mcp server",null,"index, follow",[21,26],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000008","AI","ai","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000002","TypeScript","typescript","Rekayasa",[32,38,44],{"id":33,"title":34,"slug":35,"excerpt":36,"locale":12,"category_name":30,"published_at":37},"d0000000-0000-0000-0000-000000000548","Dari Autocomplete ke Otonom: Evolusi Alat AI Coding (2022-2026)","dari-autocomplete-ke-otonom-evolusi-alat-ai-coding-2022-2026","Kronik tentang bagaimana alat AI coding berevolusi dari autocomplete satu baris di 2022 menjadi agen multi-file otonom di 2026. Empat tahun yang mengubah pengembangan perangkat lunak selamanya, dengan pandangan tentang apa yang akan datang.","2026-03-28T10:44:41.351824Z",{"id":39,"title":40,"slug":41,"excerpt":42,"locale":12,"category_name":30,"published_at":43},"d0000000-0000-0000-0000-000000000547","Bagaimana Kami Menggunakan Claude Code untuk Memelihara Monorepo Nuxt 4 + Rust","bagaimana-kami-menggunakan-claude-code-nuxt-rust-monorepo","Pandangan di balik layar tentang bagaimana Open Soft menggunakan Claude Code sebagai alat pengembangan harian untuk monorepo produksi kami. Alur kerja nyata untuk refactoring multi-file, penulisan migrasi, pembuatan tes, code review, dan tooling kustom dengan hook dan server MCP.","2026-03-28T10:44:41.342024Z",{"id":45,"title":46,"slug":47,"excerpt":48,"locale":12,"category_name":30,"published_at":49},"d0000000-0000-0000-0000-000000000546","Cursor vs Claude Code vs Copilot: Alat AI Coding Mana untuk Pekerjaan Apa?","cursor-vs-claude-code-vs-copilot-perbandingan-alat-ai-coding","Perbandingan praktis head-to-head dari tiga alat AI coding terkemuka di 2026. Cursor unggul sebagai IDE AI-first, Claude Code mendominasi penalaran multi-file kompleks dari CLI, dan Copilot tetap menjadi autocomplete inline terbaik di editor yang sudah ada.","2026-03-28T10:44:41.316209Z",{"id":13,"name":51,"slug":52,"bio":53,"photo_url":18,"linkedin":18,"role":54,"created_at":55,"updated_at":55},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]