achmadya.dev
~/projects / mcp-query

MCP Query

A suite of MCP servers for querying Excel and four databases over npx and stdio, with a small runtime and explicit error handling.

MCP Query preview
Content language

Mengapa saya membuatnya

Banyak MCP server dapat langsung dipakai, tetapi sulit saya percaya. Saya tidak memahami alur function call-nya, dependency yang dibawa cukup banyak, dan beberapa server memerlukan Python atau Docker hanya untuk dijalankan.

Saya membuat MCP Query untuk mempelajari MCP dari dalam. Saya ingin melihat sendiri bagaimana client menemukan tool, mengirim input, menjalankan handler, dan menerima hasil atau error.

Targetnya sederhana: server harus berguna untuk query data, mudah dijalankan, dan cukup kecil agar seluruh alurnya dapat dibaca serta diuji.

Repository: github.com/achmadya-dev/mcp-query

Apa yang saya bangun

MCP Query menghubungkan AI client dengan Excel, MySQL, PostgreSQL, SQL Server, dan SQLite. Setiap sumber data memiliki adapter sendiri karena koneksi, tipe data, lifecycle, dan bentuk error-nya berbeda.

Di tengahnya terdapat core handler yang dipakai semua tool. Handler ini mengurus bagian yang harus konsisten:

  • Memvalidasi input function call.
  • Memilih adapter dan fungsi yang sesuai.
  • Menormalisasi hasil query.
  • Menangkap error tanpa menghentikan server.
  • Mengubah hasil atau error menjadi response MCP.

Core handler menjaga batas protocol. Adapter tetap bertanggung jawab atas perilaku sumber data. Dengan begitu, detail error tidak hilang, tetapi bentuk response ke client tetap konsisten.

Cara MCP menjadi jembatan

MCP memisahkan AI client dari implementasi tool. Client tidak perlu memahami driver PostgreSQL atau parser Excel. Client cukup mengetahui nama tool, input yang diterima, dan bentuk hasilnya.

Protocol menentukan pesan yang dipertukarkan. Transport menentukan cara pesan tersebut dikirim. Pada MCP Query, pesan protocol dikirim melalui transport stdio.

Alurnya seperti berikut:

Merender diagram...

Saat terhubung, client meminta daftar tool beserta input schema-nya. Model kemudian dapat memilih tool yang sesuai. Server tetap menentukan validasi, akses data, dan response akhir.

MCP menjadi jembatan karena kedua sisi hanya bergantung pada contract protocol. Implementasi database dapat berubah tanpa membuat AI client perlu memahami detail internalnya.

Mengapa memakai npx dan stdio

npx menjalankan package npm tanpa instalasi global. Jika package belum tersedia, npx mengunduhnya ke cache lalu menjalankan entry point yang tercantum pada package.

Konfigurasi client dapat dibuat seperti berikut:

{
  "mcpServers": {
    "database": {
      "command": "npx",
      "args": ["-y", "<package-mcp>@<version>"],
      "env": {
        "DATABASE_URL": "<connection-string>"
      }
    }
  }
}

Versi package sebaiknya di-pin agar kode yang dijalankan tetap dapat ditinjau dan diulang. npx menyederhanakan instalasi, tetapi bukan jaminan keamanan.

Saya memilih stdio karena server dijalankan sebagai proses lokal oleh MCP client. Client menulis pesan ke stdin dan membaca response dari stdout.

Transport ini tidak memerlukan port HTTP, service yang selalu aktif, atau konfigurasi jaringan tambahan. Saat client berhenti, proses MCP juga dapat dihentikan.

stdout harus khusus untuk pesan MCP. Log dan informasi debug dikirim ke stderr agar tidak merusak pertukaran pesan protocol.

Pilihan ini cocok untuk tool lokal dan akses data milik pengguna. Untuk server jarak jauh atau banyak client, transport berbasis HTTP dapat lebih sesuai karena kebutuhan lifecycle dan autentikasinya berbeda.

Cara menangani query dan error

Setiap tool call masuk melalui core handler. Input diperiksa sebelum diteruskan ke adapter. Query hanya dijalankan jika konfigurasi dan argumennya valid.

Jika query berhasil, adapter mengembalikan data yang kemudian dinormalisasi. Jika gagal, handler menangkap error dan mengubahnya menjadi response yang dapat dipahami client.

Error PostgreSQL tidak disamakan dengan error SQLite. Informasi penting dari sumber masalah tetap dipertahankan, tetapi semuanya melewati jalur response MCP yang sama.

Pendekatan ini mencegah exception yang tidak tertangani menghentikan proses server. AI client tetap menerima hasil yang dapat dijelaskan atau digunakan untuk menentukan langkah berikutnya.

Cara pengujian

Docker Compose hanya digunakan untuk development dan integration test. Ia menyediakan MySQL, PostgreSQL, dan SQL Server secara konsisten. SQLite dan Excel diuji menggunakan file lokal.

Alur pengujiannya:

  1. Menjalankan database yang dibutuhkan.
  2. Menjalankan package dari local build atau versi yang di-pin.
  3. Memanggil tool melalui MCP client.
  4. Menguji hasil sukses, input salah, koneksi gagal, dan error engine.
  5. Mempublikasikan package setelah handler dan adapter lulus test.

Docker bukan syarat runtime tersembunyi. Jika database sudah tersedia, pengguna cukup menjalankan package MCP melalui client.

Pelajaran yang saya dapat

Memahami satu tool call dari awal sampai akhir lebih berguna daripada langsung membuat banyak tool. Alur yang kecil lebih mudah diuji, di-debug, dan dipercaya.

Abstraction seharusnya menghapus pengulangan, bukan menyembunyikan perbedaan. Validasi dan format response dapat dibagikan, tetapi lifecycle dan error database tetap harus berada di adapter.

Error handling adalah bagian dari contract MCP. Client membutuhkan response yang dapat diproses ketika query gagal, bukan exception mentah atau proses server yang tiba-tiba berhenti.

Runtime minimal mempermudah penggunaan, tetapi tidak menggantikan pemeriksaan kode dan dependency. npx, versi yang di-pin, serta implementasi yang transparan harus digunakan bersama.

MCP Query membantu saya memahami MCP sebagai jembatan, bukan sebagai kotak hitam. Nilai utamanya ada pada alur yang jelas dari AI client sampai sumber data, lalu kembali sebagai response yang dapat dipercaya.

metadata
role
Developer / Maintainer
period
April 2026 - Present
stack
TypeScriptMCPDocker Composepnpm
Related