Kamu bikin MCP server, server-nya jalan normal sendirian, terus pas disambungkan ke client, tool-nya nggak muncul. Atau ada tool yang error, tapi cuma pas dipanggil model, dan nggak ada pesan error yang bisa kamu lihat. Debug dengan mata buta kayak gini nyebelin banget.
MCP Inspector adalah debugger resmi untuk Model Context Protocol, dan dia mengubah proses buta itu jadi loop yang rapat. Kamu jalanin server di dalamnya, lihat tool persis yang diekspos, panggil satu tool manual, lalu baca respons JSON mentahnya. Bug-bug membosankan ketangkap sebelum client ikut campur.
Panduan ini membahas seluruh alur kerja dengan server Python beneran: web UI, mode CLI buat scripting dan CI, lalu failure mode yang paling sering muncul pas nyambung ke Claude Desktop. Semua command di sini sudah saya jalanin dan cek.
Prerequisites
- Node.js 18 atau lebih baru (Inspector jalan lewat npx)
- Python 3.10+ dan FastMCP:
pip install fastmcp - Server yang mau di-test. Server MCP apa pun bisa. Yang di Step 0 tinggal salin.
Step 0: server kecil yang layak di-test
Kamu nggak bisa debug server kosong, jadi ini server yang ngekspos dua tool. server_health baca statistik proses dan memory Linux. save_note nambahin satu baris ke file.
from __future__ import annotations
from datetime import datetime
from pathlib import Path
from fastmcp import FastMCP
mcp = FastMCP("dev-utils")
@mcp.tool()
def server_health() -> dict[str, str]:
"""Return uptime, load, and memory usage of this machine."""
now = datetime.now().isoformat(timespec="seconds")
try:
with open("/proc/uptime") as fh:
uptime_sec = float(fh.read().split()[0])
uptime = f"{int(uptime_sec // 86400)}d {int(uptime_sec % 86400 // 3600)}h"
except OSError:
uptime = "n/a"
try:
mem = {}
with open("/proc/meminfo") as fh:
for line in fh:
key, value = line.split(":", 1)
mem[key] = value.strip()
total_kb = int(mem["MemTotal"].split()[0])
avail_kb = int(mem["MemAvailable"].split()[0])
memory = f"{round(100 * (total_kb - avail_kb) / total_kb, 1)}% used"
except (OSError, KeyError, ValueError):
memory = "n/a"
return {"time": now, "uptime": uptime, "memory": memory}
@mcp.tool()
def save_note(path: str, line: str) -> str:
"""Append one line to a file."""
p = Path(path).expanduser().resolve()
with p.open("a") as fh:
fh.write(line.rstrip() + "\n")
return f"appended {len(line)} chars to {p}"
if __name__ == "__main__":
mcp.run()
Simpan sebagai server.py dan jalanin sekali buat mastiin dia start:
python server.py
Dia duduk nunggu di stdio, persis yang diharapkan client lokal. Matiin dengan Ctrl+C dan lanjut ke Inspector.
Step 1: jalankan Inspector
Inspector dikasih sebagai package npm, jadi nggak ada install terpisah. Arahkan ke command start server kamu:
npx -y @modelcontextprotocol/inspector \
.venv/bin/python server.py
Inspector nge-start dua komponen dan nge-print sebuah URL, biasanya http://localhost:6274. Buka di browser. Kalau server kamu dikelola pake uv, polanya sama, tinggal arahkan ke uv:
npx @modelcontextprotocol/inspector \
uv --directory path/to/server run server.py
Step 2: web UI
Web UI dipakai buat cek harian. Setelah connect, panel kiri mendaftar setiap tool yang diekspos server, lengkap dengan JSON schema-nya. Satu cek ini nangkep error paling umum: tool yang nggak pernah ke-register. Kalau ada tool yang nggak muncul di daftar, bug-nya ada di registrasi atau decorator, sebelum logika client ikut campur.
Untuk tiap tool kamu isi argumen dan pencet tombol call. Panel respons menampilkan pesan mentah dalam bentuk persis yang bakal diterima client, termasuk flag isError. Kamu bisa liat save_note nulis file dan konfirmasi nilai return-nya sebelum model mana pun nyentuh tool itu.
Manggil server_health manual hasilnya kira-kira begini:
{"time": "2026-08-28T13:03:15", "uptime": "11d 9h", "memory": "55.4% used"}
Kalau tool error di sini, debug langsung di kode server, bukan nebak dari log client. Itu loop yang dibeli dari Inspector.
Step 3: mode CLI buat scripting dan CI
Web UI buat manusia. Mode CLI buat semua yang berulang, dan ngehemat kamu dari bikin test harness sendiri-sendiri. Tambahin --cli dan satu method:
npx @modelcontextprotocol/inspector --cli \
.venv/bin/python server.py --method tools/list
Ini nge-print seluruh daftar schema tool sebagai JSON, pas buat sanity check. Buat manggil tool dengan argumen dari command line:
npx @modelcontextprotocol/inspector --cli \
.venv/bin/python server.py \
--method tools/call --tool-name save_note \
--tool-arg path=/tmp/notes.txt --tool-arg line="hello from mcp"
Argumen terstruktur juga bisa; kasih sebagai JSON:
npx @modelcontextprotocol/inspector --cli \
.venv/bin/python server.py \
--method tools/call --tool-name save_note \
--tool-arg 'options={"format": "markdown"}'
Karena CLI balikin JSON yang bersih, kamu bisa taruh cek tools/list atau tools/call di job CI atau pre-commit hook. Tool yang keluar dari schema bakal bikin pipeline gagal sebelum di-ship, bukan gagal di laptop engineer.
Step 4: sambungkan ke Claude Desktop, lalu debug kalau gagal
Cek manual lolos, sekarang tes sebenarnya: daftarin server di Claude Desktop dan liat apakah client-nya bisa menjangkau.
Di macOS config-nya ada di ~/Library/Application Support/Claude/claude_desktop_config.json. Di Windows %APPDATA%\Claude\claude_desktop_config.json; di Linux ~/.config/Claude/claude_desktop_config.json. Tambahin blok mcpServers:
{
"mcpServers": {
"dev-utils": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["/absolute/path/to/server.py"]
}
}
}
Terus quit total Claude Desktop (nutup jendela aja nggak cukup di macOS) dan buka lagi.
Kalau server nggak muncul, cek dengan urutan ini:
- Ikon palu. Muncul ikon kecil di kiri bawah kotak input kalau MCP server sudah connect. Nggak ada ikon berarti ada error config. Klik buat liat server yang connect dan daftar tool-nya.
- Log-nya. Di macOS,
tail -n 20 -f ~/Library/Logs/Claude/mcp*.lognunjukin apa yang dicetak server saat start dan saat tool dipanggil. - Print ke stderr, bukan stdout. Server MCP ngomong JSON-RPC lewat stdout.
print()yang nyasar ke stdout merusak protokol dan client akan liat sampah atau nggak ada apa-apa. Pakeprint(..., file=sys.stderr)atau module logging buat output debug.
Step 5: failure mode yang paling sering muncul
Banyak laporan "server saya nggak mau connect" sebenarnya cuma tiga penyebab, dan semuanya soal config atau transport, bukan logika:
- Koma menggantung di config JSON. JSON nggak ngizinin itu, dan beberapa client gagal secara diam-diam. Validasi file di jsonlint.com sebelum restart.
- Path
commandyang relatif. Client desktop jalan dengan PATH minimal, jadinpxataupythonpolos bisa nggak ke-resolve. Pake path absolut. Jalankanwhich python(atauwhere pythondi Windows) buat cari lokasinya. - Print ke stdout. Ini yang paling penting diulang karena keliatannya kayak bug logika padahal bug transport.
- Nggak restart client sepenuhnya. Windows dan macOS dua-duanya nyimpen app jalan di background. Quit penuh dan buka ulang, kalau nggak config lama tetap ke-load.
Kapan pake Inspector vs langsung shipping
Pake Inspector tiap kali kamu nambah atau ngubah tool. Ini paling cepat buat server lokal dengan stdio.
Buat server remote lewat Streamable HTTP, kamu tetep bisa jalanin CLI ke sebuah URL, kasih header kayak API key dengan -e atau --header. Hubungan MCP berbasis subscription punya alur auth sendiri, jadi buat itu kamu tetep nulis integration test dan assert apa yang balik dari callback asli.
Buat codebase server yang makin besar, pake dua-duanya: Inspector buat debug interaktif, dan test harness berbasis official client SDK buat assert yang mau kamu taruh di CI. Inspector nggak menggantikan test. Dia bikin bagian manual cukup cepat jadi kamu beneran ngerjainnya.
Langkah selanjutnya
- Baca Inspector README buat daftar flag lengkap (env vars, mode config file, dukungan header).
- Baca panduan resmi build an MCP server buat nambah resource dan prompt ke server yang sama.
- Lihat cara connect local servers dan lokasi file log di tiap OS.
Payout-nya sederhana. Tool yang udah kamu test manual adalah tool yang bisa kamu percaya. Inspector bikin cek ini cuma butuh beberapa detik, bukan sesi membosankan di depan client yang menampilkan apa-apa.