Kendi barındırılan MCP sunucuları çoğalır. Önce iç dokümantasyon için bir tane olur, sonra veritabanı için bir tane, sonra biri dağıtım hattı için küçük bir tane yazar. Her birinin kendi portu, kendi URL'si ve kendi sırrı olur; ekipteki herkes üçünü de istemci yapılandırmasına yapıştırır. Bir token'ı yenilemek herkese mesaj atmak demektir.
Ağ geçidi bunu tek adres ve tek token'a indirir. İstemciler https://mcp.example.com/docs/mcp, .../db/mcp gibi adreslere bağlanır. Ağ geçidi token'ı kontrol eder, her yolu localhost'taki doğru sunucuya gönderir ve sunucuların kendisi asla dışarı açılmaz. Çok az şey gerekir: kendi IPv4'ü olan küçük bir VPS ve Caddy.
Aşağıdaki kurulumu bir test sunucusunda kurduk ve yazmadan önce gerçek istemcilerle kontrol ettik.
Gerekenler
- İstemcilerin 443'e ulaşabilmesi için genel IPv4'ü olan bir VPS. MCP sunucularınız ağır iş yapmıyorsa Nano-IP yeterlidir.
- Sunucuyu gösteren A kaydı olan bir alan adı, burada
mcp.example.com. - Ubuntu 24.04 veya Debian 12/13. Caddy her ikisinin standart depolarında var.
1. MCP sunucularını localhost'ta çalıştırın
Her sunucu bir systemd hizmeti olarak çalışır. Örnek kendi başına çalışsın diye burada referans sunucusu server-everything'i iki kez kullanıyoruz; kendi sunucularınızı koyun. Node.js 20 veya daha yenisi gerekir:
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
İkinci kopya 3102 portunu kullanır. Ardından:
systemctl daemon-reload
systemctl enable --now mcp-everything-1 mcp-everything-2
Test sırasında fark ettiğimiz bir şey: Bu sunucu yalnızca 127.0.0.1'de değil tüm arayüzlerde dinliyor ve diğer birçoğu da aynısını yapıyor. 3. adım bununla ilgilenir.
2. Caddy: önce token kontrolü, sonra yola göre yönlendirme
Bir token üretin ve bir ortam dosyasıyla Caddy'ye verin:
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:
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 mcp.example.com sertifikasını kendisi alır.
route bloğu süs değildir. İlk sürümümüzde token kontrolü ve handle_path blokları üst düzeyde yan yanaydı ve token'sız istekler 200 ile doğrudan geçiyordu. Caddy yönergeleri kendi sırasına göre dizer ve handle_path, respond'dan önce çalışır. route içinde ise yazıldıkları sırayla çalışırlar. Bu yapılandırmayı uyarlarsanız önce “token yok” durumunu test edin.
handle_path öneki kaldırır, yani /everything/mcp sunucuya /mcp olarak ulaşır. flush_interval -1 akış olaylarını geldikleri anda iletir.
3. SSH ve HTTPS dışında her şeyi kapatın
apt install -y ufw
ufw default deny incoming
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable
Bundan sonra testimizde 3101 ve 3102 portlarına sunucunun dışından ulaşılamıyordu, 22 ve 443 ise yanıt veriyordu. 80 numaralı port yalnızca Caddy sertifika alıp yenileyebilsin ve HTTPS'e yönlendirebilsin diye açık kalır.
4. Kontrol edin
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"
İlk istek 401, ikincisi 200 yazdırmalı. Bizim denememizde yanlış bir token ve kırpılmış bir token ikisi de 401 aldı; bilinmeyen bir yol doğru token'la bile 404 aldı.
Ardından bir istemciden, örneğin Claude Code'dan:
claude mcp add --transport http everything https://mcp.example.com/everything/mcp \
--header "Authorization: Bearer $TOKEN"
claude mcp list
İki sunucu da ✔ Connected gösterdi. Aynı istemci yanlış token'la ✘ Failed to connect gösterdi. İstemci kurulumu hakkında daha fazlası: EQVPS MCP'yi Claude Code ve Codex'e bağlayın.
Sonraki sunucuyu eklemek
Onu yeni bir localhost portunda başlatın, bir handle_path bloğu ekleyin, Caddy'yi yeniden yükleyin. Aynı host altında aynı token'la yeni bir URL dışında kimsenin yapılandırması değişmez.
Bilinmesi gereken sınırlar
- Herkes için tek token basittir ve yenilemek tek bir dosyadır, ama herkes için değiştirmeden tek bir kişinin erişimini iptal edemezsiniz. Kullanıcı bazında erişim için önüne bir kimlik doğrulama proxy'si koyun ya da her kişiye kendi rotasını ve token'ını verin.
- Ağ geçidi bir sunucuyu güvenli yapmaz. Kabuk komutları çalıştıran bir MCP sunucusu, token'a sahip herkes için hâlâ bir kabuktur. Token'ları paylaşılan yapılandırmalardan ve git'ten uzak tutun.
- Boyutu ağ geçidine göre değil sunuculara göre seçin. Caddy'nin kendisi birkaç on megabayt kullanır. Sunucularınızdan biri yerel bir model çalıştırıyor veya büyük bir depoyu indeksliyorsa, paketi proxy değil o belirler.
Tek bir MCP sunucunuz mu var? MCP sunucuları için VPS bu daha basit durumu anlatıyor. Ajanlarınızın üzerinde yaşadıkları sunucuyu da yönetmesini mi istiyorsunuz? Bunu EQVPS MCP sunucusu yapar (ya da betik yazmayı tercih ederseniz REST API) ve kendi IPv4'ü olan paketler ayda $8'dan başlar.
Yorumlar
Henüz yorum yok. İlk olun.