[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-mcp-produksi-transport-auth-scaling-tantangan":3},{"article":4,"author":55},{"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":16,"meta_description":17,"focus_keyword":18,"og_image":19,"canonical_url":19,"robots_meta":20,"created_at":15,"updated_at":15,"tags":21,"category_name":35,"related_articles":36},"d0000000-0000-0000-0000-000000000502","a0000000-0000-0000-0000-000000000026","MCP di Produksi: Mengatasi Tantangan Transport, Auth, dan Scaling","mcp-produksi-transport-auth-scaling-tantangan","Pembahasan mendalam tentang menjalankan server Model Context Protocol di produksi — pemilihan transport, pola autentikasi, strategi scaling, audit logging, dan arsitektur gateway untuk deployment enterprise.","## Dari Prototipe ke Produksi: Apa yang Berubah\n\nMembangun MCP server yang berfungsi di laptop Anda cukup mudah. Menjalankannya untuk menangani ribuan sesi AI agent secara bersamaan di seluruh infrastruktur terdistribusi adalah tantangan engineering yang sangat berbeda. Deployment MCP di produksi harus menangani lima masalah yang dapat diabaikan oleh prototipe: **skalabilitas transport**, **autentikasi dan otorisasi**, **manajemen sesi dalam skala besar**, **jejak audit**, dan **orkestrasi multi-server**.\n\nArtikel ini adalah panduan teknis untuk tim engineering yang memindahkan MCP server dari development ke produksi. Kami mengasumsikan Anda telah membangun setidaknya satu MCP server dan memahami dasar-dasar protokol. Jika belum, mulailah dengan artikel pendamping kami tentang membangun MCP server pertama Anda.\n\n## Skalabilitas Transport: stdio vs SSE vs Streamable HTTP\n\nMCP mendefinisikan tiga mekanisme transport. Memilih yang tepat untuk produksi adalah keputusan arsitektur pertama Anda.\n\n### Transport stdio\n\nTransport stdio berkomunikasi melalui stream input\u002Foutput standar. Aplikasi host menjalankan MCP server sebagai proses anak dan bertukar pesan JSON-RPC melalui stdin\u002Fstdout.\n\n**Kelebihan:**\n- Nol konfigurasi jaringan\n- Isolasi tingkat proses\n- Tidak ada konflik port\n- Latensi terendah (tanpa stack jaringan)\n\n**Keterbatasan:**\n- Server harus berjalan di mesin yang sama dengan host\n- Satu proses server per sesi client\n- Tidak dapat di-load balance\n- Tidak ada horizontal scaling\n\n**Terbaik untuk:** Tool development lokal, ekstensi IDE, aplikasi desktop pengguna tunggal.\n\n### Transport SSE (Server-Sent Events)\n\nTransport SSE menggunakan HTTP untuk pesan client-ke-server dan Server-Sent Events untuk pesan server-ke-client. Server berjalan sebagai layanan HTTP.\n\n**Kelebihan:**\n- Dapat diakses melalui jaringan (server remote)\n- Kompatibel dengan infrastruktur HTTP yang ada\n- Mendukung beberapa client bersamaan\n- Bekerja melalui firewall dan proxy\n\n**Keterbatasan:**\n- Streaming unidirectional (server-ke-client saja via SSE)\n- Memerlukan session affinity (koneksi stateful)\n- Beberapa load balancer kesulitan dengan koneksi SSE yang berumur panjang\n- Tidak ada semantik reconnection bawaan dalam protokol\n\n**Terbaik untuk:** Deployment kecil hingga menengah, tool internal, tim dengan infrastruktur HTTP yang ada.\n\n### Transport Streamable HTTP\n\nStreamable HTTP adalah transport terbaru, dirancang khusus untuk deployment produksi. Menggunakan HTTP POST standar untuk semua pesan, dengan SSE streaming opsional untuk operasi yang berjalan lama.\n\n**Kelebihan:**\n- Model request\u002Fresponse sepenuhnya stateless\n- Bekerja dengan HTTP load balancer mana pun\n- Manajemen sesi bawaan melalui header `Mcp-Session-Id`\n- Mendukung respons streaming dan non-streaming\n- Kompatibel dengan CDN dan proxy\n\n**Keterbatasan:**\n- Memerlukan penyimpanan sesi sisi server (Redis, database)\n- Overhead per-pesan sedikit lebih tinggi dari stdio\n- Transport lebih baru — tooling ekosistem lebih sedikit\n\n**Terbaik untuk:** Deployment cloud produksi, platform multi-tenant, lingkungan enterprise.\n\n### Matriks Perbandingan Transport\n\n| Fitur | stdio | SSE | Streamable HTTP |\n|-------|-------|-----|-----------------|\n| Akses jaringan | Lokal saja | Remote | Remote |\n| Load balancing | Tidak memungkinkan | Session-sticky | HTTP LB standar |\n| Horizontal scaling | Tidak | Terbatas | Ya |\n| Firewall-friendly | N\u002FA | Ya | Ya |\n| Reconnection | N\u002FA | Manual | Bawaan |\n| Client bersamaan | 1 | Banyak | Banyak |\n| Latensi | Terendah | Rendah | Rendah |\n| Statelessness | Stateful | Stateful | Stateless memungkinkan |\n| Kesiapan produksi | Dev saja | Menengah | Tinggi |\n\n## Autentikasi: Integrasi SSO, API Key, dan OAuth\n\nMCP server di produksi harus mengautentikasi baik aplikasi AI host maupun pengguna akhir atas nama siapa AI bertindak.\n\n### OAuth 2.0 untuk Server Remote\n\nSpesifikasi MCP mencakup alur OAuth 2.0 bawaan untuk server remote (berbasis HTTP). Alurnya bekerja sebagai berikut:\n\n1. MCP client mengirim permintaan `initialize` tanpa kredensial.\n2. Server merespons dengan HTTP 401 dan header `WWW-Authenticate` yang mengarah ke endpoint otorisasi OAuth-nya.\n3. Aplikasi host membuka browser untuk autentikasi pengguna.\n4. Setelah autentikasi berhasil, host menerima access token.\n5. Permintaan MCP berikutnya menyertakan token di header `Authorization: Bearer`.\n\n```typescript\nimport { McpServer } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002FstreamableHttp.js\";\nimport express from \"express\";\n\nconst app = express();\n\napp.use(\"\u002Fmcp\", async (req, res, next) => {\n  const token = req.headers.authorization?.replace(\"Bearer \", \"\");\n  if (!token) {\n    res.status(401).json({\n      error: \"unauthorized\",\n      oauth_url: \"https:\u002F\u002Fauth.example.com\u002Foauth\u002Fauthorize\",\n    });\n    return;\n  }\n  const user = await validateToken(token);\n  if (!user) {\n    res.status(403).json({ error: \"invalid_token\" });\n    return;\n  }\n  req.mcpUser = user;\n  next();\n});\n```\n\n### Autentikasi API Key\n\nUntuk komunikasi MCP service-to-service (di mana tidak ada pengguna manusia yang terlibat), API key lebih sederhana:\n\n```typescript\nconst API_KEYS = new Map([\n  [\"sk-prod-abc123\", { name: \"analytics-service\", scopes: [\"read\"] }],\n  [\"sk-prod-def456\", { name: \"admin-service\", scopes: [\"read\", \"write\"] }],\n]);\n\nfunction authenticateApiKey(key: string) {\n  return API_KEYS.get(key) || null;\n}\n```\n\n### Pola Integrasi SSO\n\nUntuk deployment enterprise, integrasikan dengan SSO yang ada (SAML, OIDC):\n\n```\nUser -> AI Host -> MCP Client -> MCP Server -> SSO Provider\n                                      |\n                                      v\n                              Validasi OIDC token\n                              Ekstrak peran pengguna\n                              Terapkan RBAC tingkat tool\n```\n\nSetiap MCP tool dapat memeriksa peran pengguna yang terautentikasi sebelum mengeksekusi:\n\n```typescript\nserver.tool(\n  \"delete_record\",\n  \"Hapus record database berdasarkan ID\",\n  { table: z.string(), id: z.string() },\n  async ({ table, id }, { authContext }) => {\n    if (!authContext.roles.includes(\"admin\")) {\n      return {\n        content: [{ type: \"text\", text: \"Terlarang: diperlukan peran admin\" }],\n        isError: true,\n      };\n    }\n    \u002F\u002F Lanjutkan penghapusan\n  }\n);\n```\n\n## Scaling: Sesi Stateful vs Load Balancer\n\nSesi MCP pada dasarnya stateful: handshake `initialize` menegosiasikan kemampuan, dan server mungkin mempertahankan konteks di seluruh panggilan tool dalam satu sesi. Ini menciptakan ketegangan dengan horizontal scaling.\n\n### Arsitektur Session Store\n\nEkstrak state sesi dari proses server ke penyimpanan eksternal:\n\n```typescript\ninterface McpSession {\n  id: string;\n  userId: string;\n  capabilities: ServerCapabilities;\n  createdAt: Date;\n  lastActivityAt: Date;\n  metadata: Record\u003Cstring, unknown>;\n}\n\nclass RedisSessionStore {\n  constructor(private redis: Redis) {}\n\n  async create(session: McpSession): Promise\u003Cvoid> {\n    await this.redis.set(\n      `mcp:session:${session.id}`,\n      JSON.stringify(session),\n      \"EX\", 3600\n    );\n  }\n\n  async get(sessionId: string): Promise\u003CMcpSession | null> {\n    const data = await this.redis.get(`mcp:session:${sessionId}`);\n    return data ? JSON.parse(data) : null;\n  }\n}\n```\n\n### Horizontal Scaling dengan Streamable HTTP\n\nDengan sesi yang dieksternalisasi dan transport Streamable HTTP, Anda dapat menjalankan beberapa instance MCP server di belakang load balancer standar. Tidak diperlukan routing session-sticky. Instance server mana pun dapat menangani permintaan apa pun dengan memuat sesi dari Redis.\n\n### Konfigurasi Auto-Scaling\n\nContoh Kubernetes HPA untuk MCP server:\n\n```yaml\napiVersion: autoscaling\u002Fv2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: mcp-server\nspec:\n  scaleTargetRef:\n    apiVersion: apps\u002Fv1\n    kind: Deployment\n    name: mcp-server\n  minReplicas: 2\n  maxReplicas: 20\n  metrics:\n    - type: Resource\n      resource:\n        name: cpu\n        target:\n          type: Utilization\n          averageUtilization: 70\n    - type: Pods\n      pods:\n        metric:\n          name: mcp_active_sessions\n        target:\n          type: AverageValue\n          averageValue: \"100\"\n```\n\n## Jejak Audit dan Logging\n\nSetiap pemanggilan MCP tool di produksi harus dicatat untuk keamanan, kepatuhan, dan debugging.\n\n### Skema Structured Logging\n\n```typescript\ninterface McpAuditLog {\n  timestamp: string;\n  sessionId: string;\n  userId: string;\n  toolName: string;\n  toolInput: Record\u003Cstring, unknown>;\n  toolOutput: string;\n  durationMs: number;\n  success: boolean;\n  errorMessage?: string;\n  ipAddress: string;\n  userAgent: string;\n}\n```\n\n### Pertimbangan Kepatuhan\n\n| Persyaratan | Implementasi |\n|-------------|--------------|\n| Akses data GDPR | Catat data pengguna mana yang diakses AI melalui MCP tools |\n| Jejak audit SOC 2 | Log immutable dari semua pemanggilan tool dengan timestamp |\n| Perlindungan PII | Redaksi field sensitif dalam input tool sebelum logging |\n| Retensi data | Tetapkan TTL log sesuai persyaratan kepatuhan Anda |\n| Review akses | Catat event autentikasi dan pemeriksaan izin |\n\n## Pola Gateway untuk Deployment Multi-Server\n\nLingkungan enterprise sering memerlukan lusinan MCP server — satu untuk setiap sistem internal. **MCP Gateway** memusatkan manajemen:\n\nGateway menyediakan:\n\n1. **Autentikasi terpadu**: Satu alur auth untuk semua server backend.\n2. **Routing namespace tool**: Tool diberi prefix dengan nama server (`jira.create_issue`, `slack.send_message`).\n3. **Rate limiting terpusat**: Batas per-pengguna, per-tool, dan per-server.\n4. **Routing permintaan**: Arahkan panggilan tool ke server backend yang sesuai.\n5. **Circuit breaking**: Jika server backend tidak sehat, gateway mengembalikan error yang graceful alih-alih menggantung.\n\n## FAQ\n\n**T: Haruskah saya menggunakan transport stdio atau HTTP di produksi?**\nJ: Gunakan Streamable HTTP untuk deployment apa pun yang perlu di-scale melebihi satu mesin. Gunakan stdio hanya untuk integrasi desktop lokal di mana AI host dan MCP server berjalan di mesin yang sama.\n\n**T: Berapa banyak sesi bersamaan yang dapat ditangani satu MCP server?**\nJ: Dengan Streamable HTTP dan sesi yang dieksternalisasi, satu instance server Node.js biasanya menangani 500-1.000 sesi bersamaan. Dengan server Rust atau Go, 5.000-10.000 dapat dicapai. Scale secara horizontal melebihi itu.\n\n**T: Bagaimana cara menangani downtime MCP server?**\nJ: Implementasikan health check (endpoint `\u002Fhealth`), gunakan Kubernetes liveness\u002Freadiness probes, dan konfigurasi gateway Anda dengan circuit breaker. MCP client akan menerima error koneksi yang dapat ditampilkan oleh AI host sebagai \"tool sementara tidak tersedia.\"\n\n**T: Bisakah MCP server memanggil MCP server lain?**\nJ: Ya. MCP server juga dapat menjadi MCP client, membuat rantai. Ini adalah dasar komunikasi agent-to-agent. Gunakan pola ini dengan hati-hati — rantai yang dalam meningkatkan latensi dan probabilitas kegagalan.\n\n**T: Bagaimana cara mengelola versi API MCP server saya?**\nJ: Gunakan field versi server dalam respons `initialize`. Untuk perubahan breaking (menghapus tools, mengubah skema), naikkan versi major dan dukung versi lama dan baru selama periode migrasi.\n\n**T: Berapa ukuran pesan maksimum untuk MCP?**\nJ: Protokol tidak mendefinisikan maksimum, tetapi batas praktis tergantung pada transport. Untuk Streamable HTTP, jaga respons di bawah 10 MB. Untuk stdio, buffer pipe sistem (biasanya 64 KB) mungkin memerlukan chunking untuk respons besar.","\u003Ch2 id=\"dari-prototipe-ke-produksi-apa-yang-berubah\">Dari Prototipe ke Produksi: Apa yang Berubah\u003C\u002Fh2>\n\u003Cp>Membangun MCP server yang berfungsi di laptop Anda cukup mudah. Menjalankannya untuk menangani ribuan sesi AI agent secara bersamaan di seluruh infrastruktur terdistribusi adalah tantangan engineering yang sangat berbeda. Deployment MCP di produksi harus menangani lima masalah yang dapat diabaikan oleh prototipe: \u003Cstrong>skalabilitas transport\u003C\u002Fstrong>, \u003Cstrong>autentikasi dan otorisasi\u003C\u002Fstrong>, \u003Cstrong>manajemen sesi dalam skala besar\u003C\u002Fstrong>, \u003Cstrong>jejak audit\u003C\u002Fstrong>, dan \u003Cstrong>orkestrasi multi-server\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003Cp>Artikel ini adalah panduan teknis untuk tim engineering yang memindahkan MCP server dari development ke produksi. Kami mengasumsikan Anda telah membangun setidaknya satu MCP server dan memahami dasar-dasar protokol. Jika belum, mulailah dengan artikel pendamping kami tentang membangun MCP server pertama Anda.\u003C\u002Fp>\n\u003Ch2 id=\"skalabilitas-transport-stdio-vs-sse-vs-streamable-http\">Skalabilitas Transport: stdio vs SSE vs Streamable HTTP\u003C\u002Fh2>\n\u003Cp>MCP mendefinisikan tiga mekanisme transport. Memilih yang tepat untuk produksi adalah keputusan arsitektur pertama Anda.\u003C\u002Fp>\n\u003Ch3>Transport stdio\u003C\u002Fh3>\n\u003Cp>Transport stdio berkomunikasi melalui stream input\u002Foutput standar. Aplikasi host menjalankan MCP server sebagai proses anak dan bertukar pesan JSON-RPC melalui stdin\u002Fstdout.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Kelebihan:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Nol konfigurasi jaringan\u003C\u002Fli>\n\u003Cli>Isolasi tingkat proses\u003C\u002Fli>\n\u003Cli>Tidak ada konflik port\u003C\u002Fli>\n\u003Cli>Latensi terendah (tanpa stack jaringan)\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Keterbatasan:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Server harus berjalan di mesin yang sama dengan host\u003C\u002Fli>\n\u003Cli>Satu proses server per sesi client\u003C\u002Fli>\n\u003Cli>Tidak dapat di-load balance\u003C\u002Fli>\n\u003Cli>Tidak ada horizontal scaling\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Terbaik untuk:\u003C\u002Fstrong> Tool development lokal, ekstensi IDE, aplikasi desktop pengguna tunggal.\u003C\u002Fp>\n\u003Ch3>Transport SSE (Server-Sent Events)\u003C\u002Fh3>\n\u003Cp>Transport SSE menggunakan HTTP untuk pesan client-ke-server dan Server-Sent Events untuk pesan server-ke-client. Server berjalan sebagai layanan HTTP.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Kelebihan:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Dapat diakses melalui jaringan (server remote)\u003C\u002Fli>\n\u003Cli>Kompatibel dengan infrastruktur HTTP yang ada\u003C\u002Fli>\n\u003Cli>Mendukung beberapa client bersamaan\u003C\u002Fli>\n\u003Cli>Bekerja melalui firewall dan proxy\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Keterbatasan:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Streaming unidirectional (server-ke-client saja via SSE)\u003C\u002Fli>\n\u003Cli>Memerlukan session affinity (koneksi stateful)\u003C\u002Fli>\n\u003Cli>Beberapa load balancer kesulitan dengan koneksi SSE yang berumur panjang\u003C\u002Fli>\n\u003Cli>Tidak ada semantik reconnection bawaan dalam protokol\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Terbaik untuk:\u003C\u002Fstrong> Deployment kecil hingga menengah, tool internal, tim dengan infrastruktur HTTP yang ada.\u003C\u002Fp>\n\u003Ch3>Transport Streamable HTTP\u003C\u002Fh3>\n\u003Cp>Streamable HTTP adalah transport terbaru, dirancang khusus untuk deployment produksi. Menggunakan HTTP POST standar untuk semua pesan, dengan SSE streaming opsional untuk operasi yang berjalan lama.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Kelebihan:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Model request\u002Fresponse sepenuhnya stateless\u003C\u002Fli>\n\u003Cli>Bekerja dengan HTTP load balancer mana pun\u003C\u002Fli>\n\u003Cli>Manajemen sesi bawaan melalui header \u003Ccode>Mcp-Session-Id\u003C\u002Fcode>\u003C\u002Fli>\n\u003Cli>Mendukung respons streaming dan non-streaming\u003C\u002Fli>\n\u003Cli>Kompatibel dengan CDN dan proxy\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Keterbatasan:\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cul>\n\u003Cli>Memerlukan penyimpanan sesi sisi server (Redis, database)\u003C\u002Fli>\n\u003Cli>Overhead per-pesan sedikit lebih tinggi dari stdio\u003C\u002Fli>\n\u003Cli>Transport lebih baru — tooling ekosistem lebih sedikit\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>\u003Cstrong>Terbaik untuk:\u003C\u002Fstrong> Deployment cloud produksi, platform multi-tenant, lingkungan enterprise.\u003C\u002Fp>\n\u003Ch3>Matriks Perbandingan Transport\u003C\u002Fh3>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Fitur\u003C\u002Fth>\u003Cth>stdio\u003C\u002Fth>\u003Cth>SSE\u003C\u002Fth>\u003Cth>Streamable HTTP\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Akses jaringan\u003C\u002Ftd>\u003Ctd>Lokal saja\u003C\u002Ftd>\u003Ctd>Remote\u003C\u002Ftd>\u003Ctd>Remote\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Load balancing\u003C\u002Ftd>\u003Ctd>Tidak memungkinkan\u003C\u002Ftd>\u003Ctd>Session-sticky\u003C\u002Ftd>\u003Ctd>HTTP LB standar\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Horizontal scaling\u003C\u002Ftd>\u003Ctd>Tidak\u003C\u002Ftd>\u003Ctd>Terbatas\u003C\u002Ftd>\u003Ctd>Ya\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Firewall-friendly\u003C\u002Ftd>\u003Ctd>N\u002FA\u003C\u002Ftd>\u003Ctd>Ya\u003C\u002Ftd>\u003Ctd>Ya\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Reconnection\u003C\u002Ftd>\u003Ctd>N\u002FA\u003C\u002Ftd>\u003Ctd>Manual\u003C\u002Ftd>\u003Ctd>Bawaan\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Client bersamaan\u003C\u002Ftd>\u003Ctd>1\u003C\u002Ftd>\u003Ctd>Banyak\u003C\u002Ftd>\u003Ctd>Banyak\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Latensi\u003C\u002Ftd>\u003Ctd>Terendah\u003C\u002Ftd>\u003Ctd>Rendah\u003C\u002Ftd>\u003Ctd>Rendah\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Statelessness\u003C\u002Ftd>\u003Ctd>Stateful\u003C\u002Ftd>\u003Ctd>Stateful\u003C\u002Ftd>\u003Ctd>Stateless memungkinkan\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Kesiapan produksi\u003C\u002Ftd>\u003Ctd>Dev saja\u003C\u002Ftd>\u003Ctd>Menengah\u003C\u002Ftd>\u003Ctd>Tinggi\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"autentikasi-integrasi-sso-api-key-dan-oauth\">Autentikasi: Integrasi SSO, API Key, dan OAuth\u003C\u002Fh2>\n\u003Cp>MCP server di produksi harus mengautentikasi baik aplikasi AI host maupun pengguna akhir atas nama siapa AI bertindak.\u003C\u002Fp>\n\u003Ch3>OAuth 2.0 untuk Server Remote\u003C\u002Fh3>\n\u003Cp>Spesifikasi MCP mencakup alur OAuth 2.0 bawaan untuk server remote (berbasis HTTP). Alurnya bekerja sebagai berikut:\u003C\u002Fp>\n\u003Col>\n\u003Cli>MCP client mengirim permintaan \u003Ccode>initialize\u003C\u002Fcode> tanpa kredensial.\u003C\u002Fli>\n\u003Cli>Server merespons dengan HTTP 401 dan header \u003Ccode>WWW-Authenticate\u003C\u002Fcode> yang mengarah ke endpoint otorisasi OAuth-nya.\u003C\u002Fli>\n\u003Cli>Aplikasi host membuka browser untuk autentikasi pengguna.\u003C\u002Fli>\n\u003Cli>Setelah autentikasi berhasil, host menerima access token.\u003C\u002Fli>\n\u003Cli>Permintaan MCP berikutnya menyertakan token di header \u003Ccode>Authorization: Bearer\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cpre>\u003Ccode class=\"language-typescript\">import { McpServer } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002FstreamableHttp.js\";\nimport express from \"express\";\n\nconst app = express();\n\napp.use(\"\u002Fmcp\", async (req, res, next) =&gt; {\n  const token = req.headers.authorization?.replace(\"Bearer \", \"\");\n  if (!token) {\n    res.status(401).json({\n      error: \"unauthorized\",\n      oauth_url: \"https:\u002F\u002Fauth.example.com\u002Foauth\u002Fauthorize\",\n    });\n    return;\n  }\n  const user = await validateToken(token);\n  if (!user) {\n    res.status(403).json({ error: \"invalid_token\" });\n    return;\n  }\n  req.mcpUser = user;\n  next();\n});\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Autentikasi API Key\u003C\u002Fh3>\n\u003Cp>Untuk komunikasi MCP service-to-service (di mana tidak ada pengguna manusia yang terlibat), API key lebih sederhana:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">const API_KEYS = new Map([\n  [\"sk-prod-abc123\", { name: \"analytics-service\", scopes: [\"read\"] }],\n  [\"sk-prod-def456\", { name: \"admin-service\", scopes: [\"read\", \"write\"] }],\n]);\n\nfunction authenticateApiKey(key: string) {\n  return API_KEYS.get(key) || null;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Pola Integrasi SSO\u003C\u002Fh3>\n\u003Cp>Untuk deployment enterprise, integrasikan dengan SSO yang ada (SAML, OIDC):\u003C\u002Fp>\n\u003Cpre>\u003Ccode>User -&gt; AI Host -&gt; MCP Client -&gt; MCP Server -&gt; SSO Provider\n                                      |\n                                      v\n                              Validasi OIDC token\n                              Ekstrak peran pengguna\n                              Terapkan RBAC tingkat tool\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Setiap MCP tool dapat memeriksa peran pengguna yang terautentikasi sebelum mengeksekusi:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">server.tool(\n  \"delete_record\",\n  \"Hapus record database berdasarkan ID\",\n  { table: z.string(), id: z.string() },\n  async ({ table, id }, { authContext }) =&gt; {\n    if (!authContext.roles.includes(\"admin\")) {\n      return {\n        content: [{ type: \"text\", text: \"Terlarang: diperlukan peran admin\" }],\n        isError: true,\n      };\n    }\n    \u002F\u002F Lanjutkan penghapusan\n  }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"scaling-sesi-stateful-vs-load-balancer\">Scaling: Sesi Stateful vs Load Balancer\u003C\u002Fh2>\n\u003Cp>Sesi MCP pada dasarnya stateful: handshake \u003Ccode>initialize\u003C\u002Fcode> menegosiasikan kemampuan, dan server mungkin mempertahankan konteks di seluruh panggilan tool dalam satu sesi. Ini menciptakan ketegangan dengan horizontal scaling.\u003C\u002Fp>\n\u003Ch3>Arsitektur Session Store\u003C\u002Fh3>\n\u003Cp>Ekstrak state sesi dari proses server ke penyimpanan eksternal:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">interface McpSession {\n  id: string;\n  userId: string;\n  capabilities: ServerCapabilities;\n  createdAt: Date;\n  lastActivityAt: Date;\n  metadata: Record&lt;string, unknown&gt;;\n}\n\nclass RedisSessionStore {\n  constructor(private redis: Redis) {}\n\n  async create(session: McpSession): Promise&lt;void&gt; {\n    await this.redis.set(\n      `mcp:session:${session.id}`,\n      JSON.stringify(session),\n      \"EX\", 3600\n    );\n  }\n\n  async get(sessionId: string): Promise&lt;McpSession | null&gt; {\n    const data = await this.redis.get(`mcp:session:${sessionId}`);\n    return data ? JSON.parse(data) : null;\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Horizontal Scaling dengan Streamable HTTP\u003C\u002Fh3>\n\u003Cp>Dengan sesi yang dieksternalisasi dan transport Streamable HTTP, Anda dapat menjalankan beberapa instance MCP server di belakang load balancer standar. Tidak diperlukan routing session-sticky. Instance server mana pun dapat menangani permintaan apa pun dengan memuat sesi dari Redis.\u003C\u002Fp>\n\u003Ch3>Konfigurasi Auto-Scaling\u003C\u002Fh3>\n\u003Cp>Contoh Kubernetes HPA untuk MCP server:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-yaml\">apiVersion: autoscaling\u002Fv2\nkind: HorizontalPodAutoscaler\nmetadata:\n  name: mcp-server\nspec:\n  scaleTargetRef:\n    apiVersion: apps\u002Fv1\n    kind: Deployment\n    name: mcp-server\n  minReplicas: 2\n  maxReplicas: 20\n  metrics:\n    - type: Resource\n      resource:\n        name: cpu\n        target:\n          type: Utilization\n          averageUtilization: 70\n    - type: Pods\n      pods:\n        metric:\n          name: mcp_active_sessions\n        target:\n          type: AverageValue\n          averageValue: \"100\"\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"jejak-audit-dan-logging\">Jejak Audit dan Logging\u003C\u002Fh2>\n\u003Cp>Setiap pemanggilan MCP tool di produksi harus dicatat untuk keamanan, kepatuhan, dan debugging.\u003C\u002Fp>\n\u003Ch3>Skema Structured Logging\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-typescript\">interface McpAuditLog {\n  timestamp: string;\n  sessionId: string;\n  userId: string;\n  toolName: string;\n  toolInput: Record&lt;string, unknown&gt;;\n  toolOutput: string;\n  durationMs: number;\n  success: boolean;\n  errorMessage?: string;\n  ipAddress: string;\n  userAgent: string;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>Pertimbangan Kepatuhan\u003C\u002Fh3>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>Persyaratan\u003C\u002Fth>\u003Cth>Implementasi\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>Akses data GDPR\u003C\u002Ftd>\u003Ctd>Catat data pengguna mana yang diakses AI melalui MCP tools\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Jejak audit SOC 2\u003C\u002Ftd>\u003Ctd>Log immutable dari semua pemanggilan tool dengan timestamp\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Perlindungan PII\u003C\u002Ftd>\u003Ctd>Redaksi field sensitif dalam input tool sebelum logging\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Retensi data\u003C\u002Ftd>\u003Ctd>Tetapkan TTL log sesuai persyaratan kepatuhan Anda\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>Review akses\u003C\u002Ftd>\u003Ctd>Catat event autentikasi dan pemeriksaan izin\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"pola-gateway-untuk-deployment-multi-server\">Pola Gateway untuk Deployment Multi-Server\u003C\u002Fh2>\n\u003Cp>Lingkungan enterprise sering memerlukan lusinan MCP server — satu untuk setiap sistem internal. \u003Cstrong>MCP Gateway\u003C\u002Fstrong> memusatkan manajemen:\u003C\u002Fp>\n\u003Cp>Gateway menyediakan:\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cstrong>Autentikasi terpadu\u003C\u002Fstrong>: Satu alur auth untuk semua server backend.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Routing namespace tool\u003C\u002Fstrong>: Tool diberi prefix dengan nama server (\u003Ccode>jira.create_issue\u003C\u002Fcode>, \u003Ccode>slack.send_message\u003C\u002Fcode>).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Rate limiting terpusat\u003C\u002Fstrong>: Batas per-pengguna, per-tool, dan per-server.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Routing permintaan\u003C\u002Fstrong>: Arahkan panggilan tool ke server backend yang sesuai.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Circuit breaking\u003C\u002Fstrong>: Jika server backend tidak sehat, gateway mengembalikan error yang graceful alih-alih menggantung.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"faq\">FAQ\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>T: Haruskah saya menggunakan transport stdio atau HTTP di produksi?\u003C\u002Fstrong>\nJ: Gunakan Streamable HTTP untuk deployment apa pun yang perlu di-scale melebihi satu mesin. Gunakan stdio hanya untuk integrasi desktop lokal di mana AI host dan MCP server berjalan di mesin yang sama.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Berapa banyak sesi bersamaan yang dapat ditangani satu MCP server?\u003C\u002Fstrong>\nJ: Dengan Streamable HTTP dan sesi yang dieksternalisasi, satu instance server Node.js biasanya menangani 500-1.000 sesi bersamaan. Dengan server Rust atau Go, 5.000-10.000 dapat dicapai. Scale secara horizontal melebihi itu.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bagaimana cara menangani downtime MCP server?\u003C\u002Fstrong>\nJ: Implementasikan health check (endpoint \u003Ccode>\u002Fhealth\u003C\u002Fcode>), gunakan Kubernetes liveness\u002Freadiness probes, dan konfigurasi gateway Anda dengan circuit breaker. MCP client akan menerima error koneksi yang dapat ditampilkan oleh AI host sebagai “tool sementara tidak tersedia.”\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bisakah MCP server memanggil MCP server lain?\u003C\u002Fstrong>\nJ: Ya. MCP server juga dapat menjadi MCP client, membuat rantai. Ini adalah dasar komunikasi agent-to-agent. Gunakan pola ini dengan hati-hati — rantai yang dalam meningkatkan latensi dan probabilitas kegagalan.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Bagaimana cara mengelola versi API MCP server saya?\u003C\u002Fstrong>\nJ: Gunakan field versi server dalam respons \u003Ccode>initialize\u003C\u002Fcode>. Untuk perubahan breaking (menghapus tools, mengubah skema), naikkan versi major dan dukung versi lama dan baru selama periode migrasi.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>T: Berapa ukuran pesan maksimum untuk MCP?\u003C\u002Fstrong>\nJ: Protokol tidak mendefinisikan maksimum, tetapi batas praktis tergantung pada transport. Untuk Streamable HTTP, jaga respons di bawah 10 MB. Untuk stdio, buffer pipe sistem (biasanya 64 KB) mungkin memerlukan chunking untuk respons besar.\u003C\u002Fp>\n","id","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:38.363388Z","MCP di Produksi: Transport, Auth, dan Tantangan Scaling","Panduan teknis untuk menjalankan MCP server di produksi. Membahas pemilihan transport, autentikasi OAuth, horizontal scaling dengan sesi Redis, audit logging, dan pola gateway.","mcp produksi scaling",null,"index, follow",[22,27,31],{"id":23,"name":24,"slug":25,"created_at":26},"c0000000-0000-0000-0000-000000000008","AI","ai","2026-03-28T10:44:21.513630Z",{"id":28,"name":29,"slug":30,"created_at":26},"c0000000-0000-0000-0000-000000000012","DevOps","devops",{"id":32,"name":33,"slug":34,"created_at":26},"c0000000-0000-0000-0000-000000000013","Security","security","Rekayasa",[37,43,49],{"id":38,"title":39,"slug":40,"excerpt":41,"locale":12,"category_name":29,"published_at":42},"d0000000-0000-0000-0000-000000000644","Platform Engineering Memakan DevOps: Membangun Internal Developer Platform di 2026","platform-engineering-memakan-devops-membangun-idp-2026","80% organisasi engineering besar kini memiliki tim platform khusus, naik dari 45% di 2024. Internal developer platform — portal self-service, infrastruktur yang sudah disetujui, guardrail otomatis — telah menjadi cara standar untuk menghadirkan DevOps secara besar-besaran.","2026-03-28T10:44:47.476351Z",{"id":44,"title":45,"slug":46,"excerpt":47,"locale":12,"category_name":29,"published_at":48},"d0000000-0000-0000-0000-000000000643","Observabilitas Tanpa Instrumentasi: Bagaimana eBPF Menggantikan Armada Sidecar","observabilitas-tanpa-instrumentasi-ebpf-menggantikan-armada-sidecar","67% tim Kubernetes kini menggunakan alat observabilitas berbasis eBPF, naik dari 29% di 2024. Dengan memindahkan pengumpulan telemetri ke kernel, eBPF menghilangkan kontainer sidecar, memangkas penggunaan RAM sebesar 84%, dan memberikan overhead CPU di bawah 1%.","2026-03-28T10:44:47.469045Z",{"id":50,"title":51,"slug":52,"excerpt":53,"locale":12,"category_name":29,"published_at":54},"d0000000-0000-0000-0000-000000000642","WASI 0.3 dan Kematian Cold Start: Wasm Sisi Server di Produksi","wasi-0-3-kematian-cold-start-wasm-sisi-server-di-produksi","WASI 0.3 dirilis pada Februari 2026 dengan async I\u002FO native, tipe stream, dan dukungan socket penuh. WebAssembly sisi server kini menghadirkan cold start dalam hitungan mikrodetik, dan setiap penyedia cloud besar menawarkan Wasm serverless.","2026-03-28T10:44:47.445780Z",{"id":13,"name":56,"slug":57,"bio":58,"photo_url":19,"linkedin":19,"role":59,"created_at":60,"updated_at":60},"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"]