تتكاثر خوادم MCP المستضافة ذاتيًا. أولًا يوجد واحد للتوثيق الداخلي، ثم واحد لقاعدة البيانات، ثم يكتب أحدهم خادمًا صغيرًا لمسار النشر. لكل منها منفذه وعنوانه وسرّه، ويلصق كل فرد في الفريق الثلاثة في إعدادات عميله. تغيير رمز يعني مراسلة الجميع.
البوابة تحوّل ذلك إلى عنوان واحد ورمز واحد. يتصل العملاء بـ https://mcp.example.com/docs/mcp و.../db/mcp وهكذا. تتحقق البوابة من الرمز، وترسل كل مسار إلى الخادم الصحيح على localhost، ولا تُكشف الخوادم نفسها أبدًا. لا يلزم سوى القليل: VPS صغير بعنوان IPv4 خاص وCaddy.
بنينا الإعداد التالي على خادم اختبار وتحققنا منه بعملاء حقيقيين قبل كتابته.
ما تحتاجه
- VPS بعنوان IPv4 عام، ليصل العملاء إلى 443. تكفي Nano-IP ما لم تكن خوادم MCP لديك تؤدي عملًا ثقيلًا بنفسها.
- نطاق بسجل A يشير إلى الخادم، هنا
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: تحقق من الرمز أولًا، ثم وجّه حسب المسار
أنشئ رمزًا ومرّره إلى Caddy عبر ملف بيئة:
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 التوجيهات بترتيبه الخاص، وhandle_path يُنفَّذ قبل respond. داخل route تُنفَّذ بالترتيب المكتوب. إذا عدّلت هذا الإعداد، فاختبر حالة «بلا رمز» قبل أي شيء.
يزيل handle_path البادئة، فيصل /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، وحصل مسار غير معروف على 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 جديد تحت المضيف نفسه وبالرمز نفسه.
حدود تستحق المعرفة
- رمز واحد للجميع بسيط وتغييره ملف واحد، لكن لا يمكنك سحب وصول شخص واحد دون تغييره للجميع. للوصول لكل مستخدم، ضع وكيل مصادقة أمامه أو أعطِ كل شخص مساره ورمزه.
- البوابة لا تجعل الخادم آمنًا. خادم MCP ينفّذ أوامر shell يبقى shell لكل من يملك الرمز. أبعد الرموز عن الإعدادات المشتركة وعن git.
- اختر الحجم بحسب الخوادم، لا البوابة. يستهلك Caddy نفسه بضع عشرات من الميغابايت. إذا كان أحد خوادمك يشغّل نموذجًا محليًا أو يفهرس مستودعًا كبيرًا، فهو من يحدد الخطة، لا الوكيل.
لديك خادم MCP واحد فقط؟ تتناول VPS لخوادم MCP تلك الحالة الأبسط. تريد أن يدير وكلاؤك أيضًا الخادم الذي يعيشون عليه؟ يقوم بذلك خادم MCP من EQVPS (أو REST API إن فضّلت السكربتات)، والخطط ذات IPv4 خاص تبدأ من $8 شهريًا.
التعليقات
لا تعليقات بعد. كن الأول.