−25%

Windows รายปี ถึง 31 ต.ค. ดูแพ็กเกจ

EQVPS
เริ่มต้นใช้งาน

VPS สำหรับ MCP gateway: หลายเซิร์ฟเวอร์ MCP หลังที่อยู่เดียวและโทเคนเดียว

ทีมของคุณใช้เซิร์ฟเวอร์ MCP ที่โฮสต์เองสามตัว และทุกคนมีสาม URL กับสามความลับ ย้ายทั้งหมดไปไว้หลังที่อยู่ HTTPS เดียวบน VPS ขนาดเล็ก: Caddy ตรวจ bearer token กำหนดเส้นทางตาม path และกันตัวเซิร์ฟเวอร์ไว้จากอินเทอร์เน็ต เป็นการตั้งค่าที่ทดสอบแล้ว

เซิร์ฟเวอร์ MCP ที่โฮสต์เองมีแต่จะเพิ่มขึ้น ตอนแรกมีตัวหนึ่งสำหรับเอกสารภายใน แล้วอีกตัวสำหรับฐานข้อมูล แล้วมีคนเขียนตัวเล็ก ๆ ให้ pipeline ดีพลอย แต่ละตัวมีพอร์ต URL และความลับของตัวเอง และทุกคนในทีมก็วางทั้งสามไว้ในคอนฟิกไคลเอนต์ การเปลี่ยนโทเคนหมายถึงต้องแจ้งทุกคน

gateway เปลี่ยนเรื่องนี้ให้เหลือที่อยู่เดียวและโทเคนเดียว ไคลเอนต์เชื่อมต่อกับ https://mcp.example.com/docs/mcp, .../db/mcp และอื่น ๆ gateway ตรวจโทเคน ส่งแต่ละ path ไปยังเซิร์ฟเวอร์ที่ถูกต้องบน localhost และตัวเซิร์ฟเวอร์ไม่เคยถูกเปิดสู่ภายนอก ใช้ของน้อยมาก: VPS ขนาดเล็กที่มี IPv4 ของตัวเองกับ Caddy

เราตั้งค่าด้านล่างนี้บนเซิร์ฟเวอร์ทดสอบและตรวจกับไคลเอนต์จริงก่อนเขียน

สิ่งที่ต้องมี

  • VPS ที่มี IPv4 สาธารณะ เพื่อให้ไคลเอนต์เข้าถึง 443 ได้ Nano-IP ก็พอ เว้นแต่เซิร์ฟเวอร์ MCP ของคุณทำงานหนักเอง
  • โดเมนที่มี A record ชี้มาที่เซิร์ฟเวอร์ ในที่นี้คือ mcp.example.com
  • Ubuntu 24.04 หรือ Debian 12/13 Caddy มีอยู่ในคลังแพ็กเกจมาตรฐานของทั้งสอง

1. รันเซิร์ฟเวอร์ MCP บน localhost

แต่ละเซิร์ฟเวอร์รันเป็นบริการ systemd ที่นี่เราใช้เซิร์ฟเวอร์ตัวอย่าง server-everything สองครั้งเพื่อให้ตัวอย่างครบในตัว ให้เปลี่ยนเป็นของคุณ ต้องใช้ Node.js 20 ขึ้นไป:

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

ชุดที่สองใช้พอร์ต 3102 จากนั้น:

systemctl daemon-reload
systemctl enable --now mcp-everything-1 mcp-everything-2

สิ่งที่เราสังเกตตอนทดสอบ: เซิร์ฟเวอร์นี้ฟังทุกอินเทอร์เฟซ ไม่ใช่แค่ 127.0.0.1 และตัวอื่นอีกมากก็เป็นแบบนี้ ขั้นที่ 3 จัดการเรื่องนี้

2. Caddy: ตรวจโทเคนก่อน แล้วเลือกเส้นทางตาม path

สร้างโทเคนแล้วส่งให้ Caddy ผ่านไฟล์ 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:

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 เอง

บล็อก route ไม่ได้มีไว้ประดับ เวอร์ชันแรกของเราวางการตรวจโทเคนกับบล็อก handle_path ไว้ข้างกันในระดับบนสุด แล้วคำขอที่ไม่มีโทเคนก็ผ่านไปได้ด้วย 200 Caddy เรียงลำดับ directive ตามแบบของมันเอง และ handle_path ทำงานก่อน respond ภายใน route จะทำงานตามลำดับที่เขียน ถ้าคุณดัดแปลงคอนฟิกนี้ ให้ทดสอบกรณี "ไม่มีโทเคน" ก่อนอย่างอื่น

handle_path ตัด prefix ออก ดังนั้น /everything/mcp จะไปถึงเซิร์ฟเวอร์เป็น /mcp ส่วน flush_interval -1 ส่งอีเวนต์สตรีมต่อทันทีที่มาถึง

3. ปิดทุกอย่างยกเว้น SSH และ HTTPS

apt install -y ufw
ufw default deny incoming
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable

หลังจากนี้ ในการทดสอบของเรา พอร์ต 3101 และ 3102 เข้าจากภายนอกเซิร์ฟเวอร์ไม่ได้ ขณะที่ 22 และ 443 ตอบสนอง พอร์ต 80 เปิดไว้เพียงให้ Caddy ขอและต่ออายุใบรับรอง และเปลี่ยนเส้นทางไป HTTPS

4. ตรวจสอบ

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"

คำขอแรกควรพิมพ์ 401 และคำขอที่สองพิมพ์ 200 ในการทดสอบของเรา โทเคนผิดและโทเคนที่ถูกตัดได้ 401 ทั้งคู่ และ path ที่ไม่รู้จักได้ 404 แม้ใช้โทเคนถูกต้อง

จากนั้นลองจากไคลเอนต์ เช่น Claude Code:

claude mcp add --transport http everything https://mcp.example.com/everything/mcp \
  --header "Authorization: Bearer $TOKEN"
claude mcp list

เซิร์ฟเวอร์ทั้งสองแสดง ✔ Connected ไคลเอนต์เดียวกันที่ใช้โทเคนผิดแสดง ✘ Failed to connect อ่านเพิ่มเรื่องการตั้งค่าไคลเอนต์ได้ใน เชื่อมต่อ EQVPS MCP กับ Claude Code และ Codex

การเพิ่มเซิร์ฟเวอร์ตัวถัดไป

เริ่มมันบนพอร์ต localhost ใหม่ เพิ่มบล็อก handle_path หนึ่งบล็อก แล้วรีโหลด Caddy ไม่มีคอนฟิกของใครเปลี่ยน นอกจาก URL ใหม่ภายใต้โฮสต์เดิมและโทเคนเดิม

ข้อจำกัดที่ควรรู้

  • โทเคนเดียวสำหรับทุกคน เรียบง่าย และเปลี่ยนได้ด้วยไฟล์เดียว แต่คุณเพิกถอนสิทธิ์ของคนเดียวโดยไม่เปลี่ยนของทุกคนไม่ได้ ถ้าต้องการสิทธิ์รายผู้ใช้ ให้วาง proxy ยืนยันตัวตนไว้ข้างหน้า หรือให้แต่ละคนมี route และโทเคนของตัวเอง
  • gateway ไม่ได้ทำให้เซิร์ฟเวอร์ปลอดภัย เซิร์ฟเวอร์ MCP ที่รันคำสั่ง shell ก็ยังเป็น shell สำหรับใครก็ตามที่ถือโทเคน อย่าเก็บโทเคนไว้ในคอนฟิกที่แชร์กันหรือใน git
  • เลือกขนาดตามเซิร์ฟเวอร์ ไม่ใช่ตาม gateway Caddy ใช้เพียงไม่กี่สิบเมกะไบต์ ถ้าเซิร์ฟเวอร์ตัวใดรันโมเดลในเครื่องหรือทำดัชนี repository ขนาดใหญ่ ตัวนั้นคือผู้กำหนดแพ็กเกจ ไม่ใช่ proxy

มีเซิร์ฟเวอร์ MCP ตัวเดียว? VPS สำหรับเซิร์ฟเวอร์ MCP อธิบายกรณีที่ง่ายกว่านั้น อยากให้เอเจนต์ดูแลเซิร์ฟเวอร์ที่มันอาศัยอยู่ด้วย? เซิร์ฟเวอร์ MCP ของ EQVPS ทำได้ (หรือ REST API ถ้าคุณชอบเขียนสคริปต์) และแพ็กเกจที่มี IPv4 ของตัวเอง เริ่มต้นที่ $8 ต่อเดือน

FAQ

ทำไมต้องเอาเซิร์ฟเวอร์ MCP ไว้หลัง gateway

ที่อยู่เดียวและโทเคนเดียวต่อทีม แทนที่จะเป็นหนึ่งชุดต่อเซิร์ฟเวอร์ TLS อยู่ที่เดียว และตัวเซิร์ฟเวอร์ฟังเฉพาะ localhost การเพิ่มเซิร์ฟเวอร์ตัวที่สี่กลายเป็นการแก้สามบรรทัดใน gateway ไม่ใช่ความลับใหม่สำหรับทุกคน

ต้องใช้แพ็กเกจไหน

แพ็กเกจที่มี IPv4 ของตัวเอง เพราะไคลเอนต์ต้องเข้าถึงพอร์ต 80 และ 443 ได้ Nano-IP ($8/เดือน, 2 vCPU, 1 GB) พอสำหรับ gateway และเซิร์ฟเวอร์ MCP เบา ๆ ไม่กี่ตัว ถ้ามีเซิร์ฟเวอร์ที่ทำงานหนักเอง ให้เลือกขนาดตามตัวนั้น

สตรีมมิงผ่าน Caddy ได้ไหม

ได้ Streamable HTTP ใช้คำขอ POST ปกติร่วมกับ server-sent events ตั้ง flush_interval -1 ที่ reverse proxy เพื่อให้อีเวนต์ส่งต่อทันทีแทนที่จะค้างในบัฟเฟอร์

โทเคนร่วมตัวเดียวปลอดภัยพอไหม

สำหรับทีมเล็กถือเป็นจุดเริ่มต้นที่สมเหตุสมผล: โทเคนไม่เคยออกนอก HTTPS และเปลี่ยนได้ด้วยการแก้ไฟล์เดียว เมื่อต้องการสิทธิ์รายบุคคลหรือการเพิกถอน ให้วางชั้นยืนยันตัวตนจริงไว้ข้างหน้า โทเคนร่วมคือพื้น ไม่ใช่เพดาน

ใช้กับแพ็กเกจ NAT ได้ไหม

ไม่ได้ถ้าเป็น gateway สาธารณะ แพ็กเกจ NAT มีพอร์ตส่งต่อหนึ่งพอร์ตสำหรับ SSH และไม่มีขาเข้าอื่น ไคลเอนต์จึงเข้าถึง 443 ไม่ได้ ใช้ได้เฉพาะเมื่อไคลเอนต์ทั้งหมดอยู่บนเซิร์ฟเวอร์เดียวกัน

ความคิดเห็น

ยังไม่มีความคิดเห็น เป็นคนแรกสิ

แสดงความคิดเห็น

ความคิดเห็นจะถูกตรวจสอบก่อนแสดง