−25%

yıllık Windows ödemesinde, 31 Ekim'e kadar. Paketlere git

EQVPS
Hemen başla

MCP ağ geçidi için VPS: tek adres ve tek token arkasında birden çok MCP sunucusu

Ekibiniz kendi barındırdığı üç MCP sunucusu kullanıyor ve herkesin üç URL'si, üç sırrı var. Bunları küçük bir VPS'te tek bir HTTPS adresinin arkasına alın: Caddy bearer token'ı kontrol eder, yola göre yönlendirir ve sunucuları internetten uzak tutar. Test edilmiş bir yapılandırma.

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.

SSS

MCP sunucularını neden bir ağ geçidinin arkasına koymalı?

Sunucu başına değil ekip başına tek adres ve tek token, TLS tek bir yerde ve sunucuların kendisi yalnızca localhost'ta dinliyor. Dördüncü sunucuyu eklemek, herkese yeni bir sır değil, ağ geçidinde üç satırlık bir değişiklik olur.

Hangi pakete ihtiyacım var?

Kendi IPv4'ü olan bir paket, çünkü istemcilerin 80 ve 443 portlarına ulaşması gerekir. Nano-IP (ayda $8, 2 vCPU, 1 GB) bir ağ geçidi ve birkaç hafif MCP sunucusu için yeterlidir. Bir sunucu ağır iş yapıyorsa boyutu ona göre seçin.

Caddy üzerinden streaming çalışır mı?

Evet. Streamable HTTP sıradan POST istekleri ve server-sent events kullanır. Olayların ara belleğe alınmadan hemen iletilmesi için ters proxy'de flush_interval -1 ayarlayın.

Tek bir paylaşılan token yeterince güvenli mi?

Küçük bir ekip için makul bir başlangıç: Token HTTPS'in dışına hiç çıkmaz ve tek bir dosyayı değiştirerek yenilenir. Kişi bazında erişim veya iptal gerektiğinde önüne gerçek bir kimlik doğrulama katmanı koyun. Paylaşılan token taban, tavan değil.

Bunu NAT paketinde çalıştırabilir miyim?

Herkese açık bir ağ geçidi olarak hayır. NAT paketinde SSH için tek bir yönlendirilmiş port vardır ve başka gelen bağlantı yoktur, bu yüzden istemciler 443'e ulaşamaz. Ancak tüm istemciler aynı sunucudaysa çalışır.

Yorumlar

Henüz yorum yok. İlk olun.

Bir yorum bırakın

Yorumlar görünmeden önce denetlenir.