Model Context Protocol (MCP) adalah standar terbuka untuk menghubungkan aplikasi AI dengan sistem eksternal seperti file, database, API, mesin pencari, dan workflow. Dengan MCP, kita dapat membuat satu server yang mengekspos kemampuan secara terstruktur sehingga berbagai AI host dapat menemukan dan menggunakannya.

Dalam artikel ini kita akan membuat MCP server sederhana menggunakan Python. Server tersebut menyediakan satu tool untuk menjumlahkan dua angka dan satu resource untuk menghasilkan sapaan.

Memahami arsitektur MCP

MCP memisahkan beberapa komponen:

  • Host: aplikasi AI yang menjadi tempat model berjalan.

  • Client: komponen yang membuka koneksi dari host ke server MCP.

  • Server: program yang menyediakan tools, resources, atau prompts.

  • Transport: jalur komunikasi, misalnya stdio atau Streamable HTTP.

Server MCP tidak harus berisi model AI. Server bertugas menyediakan data atau action, sedangkan host menentukan kapan kemampuan tersebut ditawarkan dan digunakan oleh model.

Tiga kemampuan utama MCP

Tools

Tools adalah function yang dapat dipanggil model untuk melakukan tindakan, misalnya query database, memanggil API, menghitung data, atau membuat tiket. Karena tool dapat mengubah sistem, aplikasi sebaiknya memberi pengguna kesempatan untuk menyetujui atau menolak operasi sensitif.

Resources

Resources adalah data berbentuk file-like yang dapat dibaca client, misalnya isi file, hasil API, atau dokumen internal. Resource cocok untuk menyediakan konteks tanpa menjadikannya action yang dapat mengubah sistem.

Prompts

Prompts adalah template instruksi yang membantu pengguna menjalankan workflow tertentu secara konsisten. Ketiganya dapat dipakai sendiri atau digabungkan sesuai kebutuhan aplikasi.

Persiapan project Python

SDK Python resmi MCP membutuhkan Python 3.10 atau lebih baru. Gunakan uv agar environment terisolasi:

uv init mcp-demo
cd mcp-demo
uv venv
source .venv/bin/activate
uv add "mcp[cli]"

Di Windows, aktifkan virtual environment dengan .venv\Scripts\activate. Simpan dependency project dalam konfigurasi agar instalasi dapat direproduksi.

Membuat MCP server sederhana

Buat file server.py dengan isi berikut:

from mcp.server import MCPServer

mcp = MCPServer("Demo")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Menjumlahkan dua bilangan bulat."""
    return a + b

@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
    """Menghasilkan sapaan untuk nama tertentu."""
    return f"Halo, {name}!"

if __name__ == "__main__":
    mcp.run(transport="stdio")

Decorator @mcp.tool() mendaftarkan function sebagai tool. Type hint membantu SDK membentuk schema input, sedangkan docstring menjelaskan kemampuan tersebut kepada client dan model. Decorator @mcp.resource() membuat resource dengan URI template.

Menjalankan dan menguji server

Jalankan server melalui uv:

uv run server.py

Untuk pengujian interaktif, gunakan MCP Inspector melalui command CLI:

uv run mcp dev server.py

Inspector dapat menampilkan tool yang tersedia, membentuk input berdasarkan type hint, memanggil tool, dan membaca resource. Coba tool add dengan a=1 dan b=2; hasil yang diharapkan adalah 3. Kemudian baca resource greeting://World.

Menghubungkan server ke MCP host

Setiap host memiliki format konfigurasi sendiri, tetapi pola umumnya menyimpan nama server, command, dan argument yang diperlukan untuk menjalankan program:

{
  "mcpServers": {
    "demo": {
      "command": "uv",
      "args": [
        "--directory",
        "/ABSOLUTE/PATH/TO/mcp-demo",
        "run",
        "server.py"
      ]
    }
  }
}

Gunakan absolute path agar host tidak gagal menemukan project ketika dijalankan dari working directory yang berbeda. Setelah konfigurasi berubah, restart host sepenuhnya jika diperlukan.

Transport stdio dan HTTP

Stdio cocok untuk server lokal yang diluncurkan langsung oleh host. Server dan host berkomunikasi melalui standard input/output sehingga tidak memerlukan port jaringan.

Streamable HTTP cocok untuk server yang perlu diakses melalui jaringan atau dipasang sebagai bagian dari service. Ketika menggunakan HTTP, tambahkan autentikasi, TLS, rate limit, validasi origin, dan pembatasan jaringan. Jangan menganggap endpoint MCP yang terbuka sebagai endpoint publik yang aman.

Aturan logging yang penting

Untuk server berbasis stdio, jangan menulis log ke stdout karena stdout digunakan untuk pesan JSON-RPC. Output tambahan dapat merusak protokol dan membuat server gagal dipakai.

import logging

logger = logging.getLogger(__name__)
logger.info("Tool dipanggil")  # arahkan logging ke stderr

Gunakan modul logging dan atur handler ke stderr. Untuk HTTP server, logging stdout tidak mengganggu response HTTP, tetapi tetap hindari mencatat secret, token, atau data pribadi.

Validasi input dan error handling

Semua input tool harus divalidasi di server walaupun schema sudah tersedia. Type hint dan schema membantu client, tetapi tidak boleh menjadi satu-satunya lapisan keamanan.

@mcp.tool()
def divide(a: float, b: float) -> float:
    """Membagi a dengan b."""
    if b == 0:
        raise ValueError("Pembagi tidak boleh nol")
    return a / b

Bedakan error protokol dari error eksekusi tool. Error input atau business logic sebaiknya memberikan pesan yang dapat membantu model memperbaiki parameter, tanpa membocorkan path internal, credential, atau detail infrastruktur.

Keamanan MCP dalam production

  • Berikan permission minimum pada account yang menjalankan server.

  • Jangan membuat tool shell generik jika function yang lebih sempit sudah cukup.

  • Validasi dan sanitasi seluruh input dari model atau client.

  • Gunakan allowlist untuk file, host, command, dan operasi yang boleh dilakukan.

  • Tambahkan timeout, rate limit, dan pembatasan ukuran input/output.

  • Minta konfirmasi manusia untuk penghapusan data, transaksi, atau perubahan production.

  • Audit pemanggilan tool dan simpan log tanpa secret.

  • Gunakan TLS serta autentikasi untuk transport HTTP.

  • Review plugin atau server pihak ketiga sebelum memasangnya.

Model dapat dipengaruhi prompt injection atau konteks berbahaya. Karena itu, MCP server tidak boleh menyerahkan keputusan otorisasi hanya kepada model. Server tetap harus memeriksa identitas, scope, dan izin pada setiap request.

Kesalahan umum saat membuat MCP server

Menulis log ke stdout

Ini sering terjadi pada server stdio dan menyebabkan pesan protokol korup. Arahkan log ke stderr.

Menggunakan path relatif

Host bisa menjalankan process dari directory berbeda. Gunakan absolute path pada konfigurasi dan validasi lokasi file.

Tool terlalu luas

Tool seperti “jalankan command apa saja” memiliki blast radius besar. Ganti dengan beberapa tool sempit yang memvalidasi parameter dan tujuan operasi.

Tidak menguji policy

Uji tool dengan input valid, kosong, terlalu besar, tipe salah, dan data berbahaya. Uji pula perilaku ketika API eksternal timeout atau mengembalikan error.

Kapan memakai MCP?

MCP berguna ketika sebuah kemampuan perlu dipakai oleh beberapa AI host atau ketika integrasi ingin dipisahkan dari aplikasi utama. Contohnya server untuk knowledge base internal, query database read-only, kalender, sistem tiket, monitoring, atau workflow deployment yang memiliki approval.

Untuk integrasi sederhana di satu aplikasi, function call internal mungkin lebih ringan. Pilih MCP ketika standardisasi, portabilitas, dan reuse lintas host memberikan manfaat nyata.

Kesimpulan

MCP menyediakan cara standar untuk menghubungkan AI dengan tools, resources, dan prompts. Dengan SDK Python, server sederhana dapat dibuat hanya dari function yang memiliki type hint dan docstring, lalu diuji menggunakan MCP Inspector.

Nilai utama MCP bukan hanya kemampuan memanggil function, tetapi kontrak yang jelas antara host, model, dan sistem eksternal. Mulai dari tool read-only yang sempit, gunakan transport yang sesuai, validasi input di server, dan pertahankan human-in-the-loop untuk operasi sensitif.

Referensi resmi: MCP Introduction, Build an MCP Server, dan MCP Python SDK.