Server MCP yang di-host sendiri terus bertambah. Mula-mula ada satu untuk dokumentasi internal, lalu satu untuk database, lalu seseorang menulis yang kecil untuk pipeline deploy. Masing-masing punya port, URL, dan rahasianya sendiri, dan setiap orang di tim menempelkan ketiganya ke konfigurasi klien. Mengganti token berarti mengabari semua orang.
Gateway mengubahnya menjadi satu alamat dan satu token. Klien terhubung ke https://mcp.example.com/docs/mcp, .../db/mcp, dan seterusnya. Gateway memeriksa token, mengirim setiap path ke server yang tepat di localhost, dan server itu sendiri tidak pernah terbuka. Yang dibutuhkan sangat sedikit: VPS kecil dengan IPv4 sendiri dan Caddy.
Kami membangun pengaturan di bawah ini di server uji dan memeriksanya dengan klien sungguhan sebelum menulisnya.
Yang Anda butuhkan
- VPS dengan IPv4 publik, agar klien bisa menjangkau 443. Nano-IP sudah cukup, kecuali server MCP Anda mengerjakan tugas berat sendiri.
- Domain dengan record A yang mengarah ke server, di sini
mcp.example.com. - Ubuntu 24.04 atau Debian 12/13. Caddy ada di repositori standar keduanya.
1. Jalankan server MCP di localhost
Setiap server berjalan sebagai layanan systemd. Di sini kami memakai server referensi server-everything dua kali agar contohnya lengkap; ganti dengan milik Anda. Butuh Node.js 20 atau lebih baru:
mkdir -p /opt/mcp && cd /opt/mcp
npm install @modelcontextprotocol/server-everything
# /etc/systemd/system/mcp-everything-1.service
[Unit]
Description=MCP server everything #1
After=network.target
[Service]
WorkingDirectory=/opt/mcp
Environment=PORT=3101
ExecStart=/opt/mcp/node_modules/.bin/mcp-server-everything streamableHttp
Restart=always
User=nobody
[Install]
WantedBy=multi-user.target
Salinan kedua memakai port 3102. Lalu:
systemctl daemon-reload
systemctl enable --now mcp-everything-1 mcp-everything-2
Satu hal yang kami lihat saat pengujian: server ini mendengarkan di semua antarmuka, bukan hanya 127.0.0.1, dan banyak server lain juga begitu. Langkah 3 menangani hal itu.
2. Caddy: periksa token dulu, lalu rutekan per path
Buat token dan berikan ke Caddy lewat file environment:
apt install -y caddy
echo "MCP_GATEWAY_TOKEN=$(openssl rand -hex 32)" > /etc/caddy/gateway.env
chmod 600 /etc/caddy/gateway.env
mkdir -p /etc/systemd/system/caddy.service.d
printf '[Service]\nEnvironmentFile=/etc/caddy/gateway.env\n' > /etc/systemd/system/caddy.service.d/env.conf
systemctl daemon-reload
Caddyfile-nya:
mcp.example.com {
route {
@unauthorized not header Authorization "Bearer {$MCP_GATEWAY_TOKEN}"
respond @unauthorized 401
handle_path /everything/* {
reverse_proxy 127.0.0.1:3101 {
flush_interval -1
}
}
handle_path /tools2/* {
reverse_proxy 127.0.0.1:3102 {
flush_interval -1
}
}
respond 404
}
}
caddy validate --config /etc/caddy/Caddyfile && systemctl restart caddy
Caddy mengambil sertifikat untuk mcp.example.com sendiri.
Blok route bukan hiasan. Versi pertama kami menaruh pemeriksaan token dan blok handle_path berdampingan di tingkat atas, dan permintaan tanpa token langsung lolos dengan 200. Caddy mengurutkan direktif menurut urutannya sendiri, dan handle_path dijalankan sebelum respond. Di dalam route, direktif dijalankan sesuai urutan tulisan. Jika Anda mengadaptasi konfigurasi ini, uji kasus „tanpa token“ lebih dulu.
handle_path membuang prefiks, jadi /everything/mcp sampai ke server sebagai /mcp. flush_interval -1 meneruskan event streaming begitu tiba.
3. Tutup semuanya kecuali SSH dan HTTPS
apt install -y ufw
ufw default deny incoming
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable
Setelah itu, dalam pengujian kami port 3101 dan 3102 tidak bisa dijangkau dari luar server, sedangkan 22 dan 443 menjawab. Port 80 tetap terbuka hanya agar Caddy bisa mengambil dan memperbarui sertifikat serta mengalihkan ke HTTPS.
4. Periksa
TOKEN=$(cut -d= -f2 /etc/caddy/gateway.env)
INIT='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"check","version":"1"}}}'
curl -s -o /dev/null -w '%{http_code}\n' -X POST https://mcp.example.com/everything/mcp \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d "$INIT"
curl -s -o /dev/null -w '%{http_code}\n' -X POST https://mcp.example.com/everything/mcp \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' -d "$INIT"
Permintaan pertama harus mencetak 401 dan yang kedua 200. Dalam uji kami, token yang salah dan token yang terpotong sama-sama mendapat 401, dan path yang tidak dikenal mendapat 404 bahkan dengan token yang benar.
Lalu dari klien, misalnya Claude Code:
claude mcp add --transport http everything https://mcp.example.com/everything/mcp \
--header "Authorization: Bearer $TOKEN"
claude mcp list
Kedua server menampilkan ✔ Connected. Klien yang sama dengan token salah menampilkan ✘ Failed to connect. Lebih lanjut tentang pengaturan klien di Hubungkan EQVPS MCP ke Claude Code dan Codex.
Menambah server berikutnya
Jalankan di port localhost baru, tambahkan satu blok handle_path, muat ulang Caddy. Konfigurasi siapa pun tidak berubah, kecuali URL baru di bawah host yang sama dengan token yang sama.
Batasan yang perlu diketahui
- Satu token untuk semua itu sederhana dan menggantinya cukup satu file, tetapi Anda tidak bisa mencabut akses satu orang tanpa menggantinya untuk semua. Untuk akses per pengguna, pasang proxy autentikasi di depan atau beri setiap orang route dan token sendiri.
- Gateway tidak membuat server aman. Server MCP yang menjalankan perintah shell tetap merupakan shell bagi siapa pun yang memegang token. Jauhkan token dari konfigurasi bersama dan git.
- Tentukan ukuran berdasarkan server, bukan gateway. Caddy sendiri hanya memakai beberapa puluh megabyte. Jika salah satu server menjalankan model lokal atau mengindeks repositori besar, server itulah yang menentukan paket, bukan proxy.
Hanya punya satu server MCP? VPS untuk server MCP membahas kasus yang lebih sederhana itu. Ingin agen Anda juga mengurus server tempat mereka tinggal? Server MCP EQVPS bisa melakukannya (atau REST API jika Anda lebih suka skrip), dan paket dengan IPv4 sendiri mulai $8 per bulan.
Komentar
Belum ada komentar. Jadilah yang pertama.