تشغيل خوادم MCP على VPS لوكلاء البرمجة بالذكاء الاصطناعي
شغّل خوادم MCP على VPS خاص بك لوكلاء البرمجة، مع شرح stdio وHTTP البعيد وsystemd وTLS والمصادقة، وحل خطأ JSON-RPC الشائع وتأمين نقطة النهاية.
ما الذي ستبنيه
إعدادان عاملان لـMCP على VPS واحد. أولاً، خادم stdio، وهو أداة لنظام الملفات أو قاعدة البيانات يشغّلها Claude Code كعملية فرعية ويتصل بها عبر pipe. ثم خادم HTTP بعيد يعمل كخدمة شبكية طويلة التشغيل خلف systemd ووكيل nginx العكسي مع TLS، ويمكن لأي عميل MCP توجهه إليه الوصول إليه. عملية تثبيت أي منهما قصيرة. يركّز معظم هذا الدليل على نقطتين تسببان المشكلات فعلياً: الحفاظ على نظافة تدفق JSON-RPC، وعدم إتاحة نقطة نهاية أداة غير موثّقة على الإنترنت العامة مطلقاً.
ما هو MCP فعلياً
يمثّل Model Context Protocol طريقة قياسية لكي يستدعي عميل ذكاء اصطناعي، مثل Claude Code أو Claude Desktop أو Gemini CLI على VPS أو نص برمجي تكتبه بنفسك، أدوات خارجية ويقرأ موارد خارجية. لا يشغّل النموذج نفسه أي شيء. بل يطلب من العميل ذلك، ويتحدث العميل باستخدام JSON-RPC 2.0 مع خادم MCP، ثم يشغّل الخادم الأداة ويعيد النتيجة. وهذا العميل هو المقصود عادةً عند استخدام مصطلح إطار تشغيل الوكيل: الحلقة المحيطة بالنموذج التي تدير قائمة الأدوات، وفحوصات الأذونات، وحالة الجلسة. أما MCP فليس سوى الطريقة التي توسّع بها جانب الأدوات. يتيح لك استخدام بروتوكول واحد كتابة الخادم مرة واحدة وتشغيله مع كل عميل يدعم MCP. إذا كان هذا الفصل جديداً عليك، وخصوصاً إذا كنت تتساءل كيف يقرر النموذج استخدام أداة أصلاً، فسيكون مسار تدريجي عبر أساسيات الوكلاء مفيداً قبل منح أحد هذه الخوادم بيانات اعتماد حقيقية.
يوجد ناقلان، وينقسم باقي هذا الدليل وفقاً لهما:
- stdio. يشغّل العميل الخادم كعملية فرعية، ويتبادل معه رسائل JSON-RPC مفصولة بأسطر عبر الإدخال والإخراج القياسيين. لا توجد شبكة، ولا منفذ، ولا مصادقة؛ فحد الثقة هو العملية نفسها. تعمل معظم الأدوات المحلية بهذه الطريقة.
- Streamable HTTP (وقريبه الأقدم HTTP+SSE). الخادم خدمة ويب طويلة التشغيل. يتصل العميل عبر HTTP، ويمكن للخادم بث الاستجابات مرة أخرى كأحداث Server-Sent Events. تُستخدم هذه الطريقة لمشاركة خادم واحد مع عدة عملاء، أو لتشغيل أداة يجب أن تبقى موجودة على الخادم باستمرار.
استخدم stdio عندما تكون الأداة مخصّصة لجهاز واحد ومستخدم واحد. واستخدم HTTP عندما تكون الأداة خدمة مشتركة.
المتطلبات الأساسية والمشكلات المتوقعة بوضوح
افترض أنك تستخدم KVM VPS جديداً يعمل بنظام Ubuntu 24.04، ولديك صلاحية root أو sudo. وبخلاف ذلك:
- بيئة التشغيل التي كُتب بها الخادم. معظم الخوادم المرجعية مكتوبة بلغة Node أو Python. يوفّر Ubuntu 24.04 الإصدار Node 18، بينما تتطلب عدة حزم MCP الحالية الإصدار Node 20 أو أحدث، لذلك ثبّت إصدار LTS حديثاً من NodeSource أو nvm بدلاً من الاعتماد على
apt. الإصدار Python 3.12 موجود مسبقاً. - نطاق وسجل DNS من النوع A، ولكن ذلك مطلوب فقط لخادم HTTP البعيد؛ إذ يحتاج TLS إلى اسم نطاق يُحلّ إلى عنوان VPS هذا. لا يحتاج مثال stdio إلى DNS إطلاقاً.
- تُعد سعة 512 MB من الذاكرة كافية. خوادم MCP عمليات JSON-RPC بسيطة؛ وتعتمد تكلفة الذاكرة على الأداة التي تصل إليها، مثل مشغّل قاعدة بيانات أو ذاكرة تخزين مؤقت للملفات، وليس على البروتوكول.
- المواصفة حديثة وتتغير باستمرار. استبدل إصدار 2025-03-26 بروتوكول HTTP+SSE بـ Streamable HTTP، واعتبر SSE مهجوراً. لا يزال SSE يعمل، ولا يزال العديد من الخوادم يستخدمه، لذلك تعامل مع تثبيت وسيلة النقل على أنه أمر يجب التحقق منه مجدداً في ملاحظات إصدار الخادم، وليس حقيقة ثابتة.
الخطوة 1: وصّل خادم stdio بـClaude Code
ابدأ بخادم نظام الملفات؛ فهو رسمي، ويخضع للصيانة بنشاط، ولا يحتاج إلا إلى Node. يسجّله الأمر التالي مع Claude Code ويقيّده بالمشروع الحالي، بحيث يُحفظ في ملف يمكن إيداعه في المستودع:
cd /home/matt/projects/api
claude mcp add --scope project --transport stdio filesystem \
-- npx -y @modelcontextprotocol/server-filesystem /home/matt/projects/apiالفاصل -- مهم: كل ما يليه هو الأمر الذي سيشغّله Claude Code، وليس خياراً لـClaude Code. ينشئ ذلك ملف .mcp.json في جذر المشروع:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/home/matt/projects/api"
]
}
}
}لا يعمل شيء بعد. عند تشغيل Claude Code مجدداً في هذا الدليل، يقرأ الوكيل .mcp.json، ويشغّل npx -y @modelcontextprotocol/server-filesystem ... كعملية فرعية، وينفّذ مصافحة MCP عبر الإدخال والإخراج القياسيين لتلك العملية. تحقّق من نجاح العملية:
claude mcp listيعرض الخادم السليم أمره وعلامة خضراء، filesystem: npx -y @modelcontextprotocol/server-filesystem ... - ✓ Connected. داخل الجلسة، يعرض أمر الشرطة المائلة /mcp الأدوات التي يوفّرها الخادم (read_file وwrite_file وlist_directory)، ويمكن للوكيل الآن استدعاءها ضمن المسارات التي سمحت بها. تعمل أداة قاعدة البيانات بالطريقة نفسها؛ بدّل الحزمة ومرّر سلسلة اتصال باعتبارها الوسيط الأخير، لكن راجع مستودع الخادم نفسه لمعرفة اسم الحزمة الحالي، لأن خادم Postgres المرجعي انتقلت ملكيته أكثر من مرة.
هذا هو الهدف الأساسي من تشغيل الوكيل على الخادم: تعمل جلسة Claude Code على VPS داخل tmux، وتعمل خوادم stdio بجانبها مباشرةً مع وصول مباشر إلى ملفات المشروع والخدمات المحلية، من دون رحلة ذهاب وإياب عبر الشبكة. عندما يمتلك الوكيل write_file وread_file أيضاً، فمن المفيد إقران هذا الوصول بـمهارة تدفعه نحو أصغر تغيير ينجح، لأن أداة نظام الملفات تجعل إعادة الكتابة الواسعة رخيصة تماماً مثل إصلاح يتكون من سطرين. يمتد هذا الربط إلى ما وراء الملفات المحلية: إذا كنت تشغّل محرك بحث على VPS، فيمكنك تزويد الوكيل بنسخة SearXNG الخاصة بك باعتبارها أداة بحث، مما يبقي الاستعلامات على خادمك، لكنه يدرج نص الصفحات غير الموثوق به مباشرةً في السياق الذي يتصرف الوكيل بناءً عليه.
الخطوة 2: إنشاء خادم HTTP بعيد
يتوقف خادم stdio عند توقف العملية الأب، كما يُنشأ مرة واحدة لكل عميل. لذلك، إذا شغّلت جلستي Claude Code على الخادم نفسه وتبادلت العمل بينهما، فستحصل كل جلسة على نسخة خاصة بها من الأداة. عندما تريد أداة تبقى قيد التشغيل لجميع العملاء، مثل أداة عمليات مشتركة أو بوابة قاعدة بيانات أو أداة يستدعيها كل من حاسوبك المحمول وCI، فأنت تحتاج إلى نقل HTTP وخدمة فعلية. إليك خادم Python بسيطاً يستخدم SDK الرسمي ويعرّض أداة واحدة:
# /opt/mcp-ops/server.py
from mcp.server.fastmcp import FastMCP
import subprocess
mcp = FastMCP("ops-tools", host="127.0.0.1", port=8000)
@mcp.tool()
def disk_free() -> str:
"""Return `df -h` for the server."""
out = subprocess.run(["df", "-h"], capture_output=True, text=True)
return out.stdout
if __name__ == "__main__":
# Serves Streamable HTTP at /mcp on 127.0.0.1:8000
mcp.run(transport="streamable-http")لاحظ host="127.0.0.1". يرتبط الخادم بـlocalhost فقط، لذلك لا يستطيع أي شيء خارج الخادم الوصول إليه مباشرة. وهذا هو السلوك المطلوب تماماً قبل إعداد المصادقة. ثبّته في virtualenv مستقل، حتى يكون لدى systemd مسار مفسّر ثابت:
sudo useradd --system --home /opt/mcp-ops --shell /usr/sbin/nologin mcp
sudo install -d -o mcp -g mcp /opt/mcp-ops
sudo -H -u mcp python3 -m venv /opt/mcp-ops/.venv
sudo -H -u mcp /opt/mcp-ops/.venv/bin/pip install "mcp[cli]"الخطوة 3: أبقِ الخدمة قيد التشغيل باستخدام systemd
الأداة المتوقفة عندما يحاول الوكيل استخدامها أسوأ من عدم وجود أداة. يهم ذلك خصوصاً عندما يكون العميل نفسه عملية طويلة التشغيل: سيستدعي وكيل يعمل دائماً ويحافظ على ذاكرته وجداوله الزمنية بعد إعادة التشغيل هذه الأدوات وفق جدول زمني من دون مراقبة، لذلك يجب أن يعود الخادم إلى العمل تلقائياً أيضاً. اكتب /etc/systemd/system/mcp-ops.service:
[Unit]
Description=MCP ops-tools server
After=network.target
[Service]
Type=simple
User=mcp
WorkingDirectory=/opt/mcp-ops
ExecStart=/opt/mcp-ops/.venv/bin/python /opt/mcp-ops/server.py
Restart=on-failure
RestartSec=2
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
[Install]
WantedBy=multi-user.targetالمسار المطلق إلى Python في venv داخل ExecStart ليس اختيارياً. وجّهه إلى /usr/bin/python3، وابدأ العملية باستخدام ModuleNotFoundError: No module named 'mcp'، لأن مفسّر النظام لم يرَ pip install. فعّل الخدمة وتحقق منها:
sudo systemctl daemon-reload
sudo systemctl enable --now mcp-ops
sudo systemctl status mcp-ops
curl -si -H 'Accept: application/json, text/event-stream' \
-H 'Content-Type: application/json' \
-X POST http://127.0.0.1:8000/mcpيجب أن يعرض status القيمة active (running). يعيد curl القيمة HTTP/1.1 400 Bad Request مع خطأ JSON-RPC في جسم الاستجابة، لأن الطلب لم يتضمن جلسة ولا حمولة JSON صالحة. وهذا هو المطلوب تماماً: فهو يثبت أن المنفذ يستجيب ويتحدث البروتوكول. تعني Connection refused أو الاستجابة الفارغة أن العملية لا تستمع على العنوان الذي تتوقعه؛ اقرأ journalctl -u mcp-ops -n 50.
الخطوة 4: ضع TLS وreverse proxy أمام الخدمة
يستمع الخادم على localhost. وللوصول إليه من أي مكان، أنهِ TLS عند nginx ومرّر الطلبات إلى الداخل عبر proxy. ثبّت nginx، واحصل على شهادة باستخدام Certbot وLet's Encrypt مع nginx، ثم اكتب كتلة location. النقطة المهمة هي تعطيل التخزين المؤقت، لأن سلوك nginx الافتراضي يحتفظ بالاستجابة حتى تكتمل، ما يؤدي إلى إيقاف تدفق SSE إلى أجل غير محدد:
server {
listen 443 ssl;
server_name mcp.example.com;
# ssl_certificate lines managed by Certbot
location /mcp {
proxy_pass http://127.0.0.1:8000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
# The four lines that make SSE work through nginx:
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600s;
chunked_transfer_encoding off;
}
}أعد التحميل باستخدام sudo nginx -t && sudo systemctl reload nginx. إذا كنت تشغّل مجموعة من الحاويات، يتولى Traefik reverse proxy مع TLS تلقائي المهمة نفسها؛ إذ يُصدر الشهادة ويوجّه الطلبات حسب اسم المضيف، وكل ما عليك فعله هو إضافة labels إلى حاوية MCP. في كلتا الحالتين، يصبح reverse proxy الآن المكوّن الوحيد الذي يستمع على منفذ عام، وهو يوجّه الطلبات إلى خدمة لم تؤمّنها بعد. أصلح ذلك قبل تسجيل عنوان URL في أي مكان.
الخطوة 5: قاعدة الأمان الحاسمة في هذا الموضوع
لا تُعرِّض نقطة نهاية MCP غير موثَّقة للمصادقة مطلقاً. خادم MCP ليس واجهة API للقراءة فقط. فهو يمنح الوصول إلى الأدوات، بما في ذلك ملفاتك وقاعدة بياناتك وأحياناً shell. إن فتح /mcp على الإنترنت العام يعني منح شخص غريب نطاق الوصول نفسه الذي يملكه وكيل الذكاء الاصطناعي لديك: إذ يمكنه عرض أدواتك ثم استدعاءها. تعامل معه تماماً كما تتعامل مع socket إدارية غير موثَّقة للمصادقة، لأن هذا هو واقعها. ويعتمد مقدار ما يتيحه token مسروق أيضاً على الخادم الذي يقف خلفه: خادم MCP للقراءة فقط الذي يأتي مع متعقّب تمارين openGym لا يمكنه إلا إعادة بيانات التدريب، بينما تتيح أداة نظام الملفات أو shell الوصول إلى الجهاز بالكامل.
ثلاث وسائل دفاع، مرتبة حسب الأفضلية:
- لا تنشرها. أبقِ الخادم على
127.0.0.1، واتصل به من حاسوبك المحمول عبر نفق SSH:ssh -L 8000:127.0.0.1:8000 matt@vps، ثم وجّه العميل إلىhttp://127.0.0.1:8000/mcp. لن يكون مكشوفاً على الإطلاق. - ضعه على شبكة خاصة. اربط عنوان النفق بشبكة WireGuard VPN مستضافة ذاتياً، واسمح لأقران VPN فقط بالوصول إليه. سيرى الإنترنت العام منفذاً مغلقاً.
- إذا كان لا بد من جعله عاماً، فاشترط رمزاً مميزاً. الحل المناسب هو تدفق MCP OAuth الذي يدعمه نقل HTTP أصلاً. والحد الأدنى العملي هو استخدام bearer token مشترك يتحقق منه الـproxy. هذا رخيص ويوقف الوصول العشوائي تماماً:
location /mcp {
if ($http_authorization != "Bearer REPLACE_WITH_LONG_RANDOM") {
return 401;
}
proxy_pass http://127.0.0.1:8000;
# ...buffering-off block from above...
}أنشئ الرمز باستخدام openssl rand -hex 32، ولا تربط الخادم نفسه بـ0.0.0.0 من دون وضع إحدى هذه الوسائل أمامه. يرسل العميل الرمز بعد ذلك في ترويسة. في Claude Code:
claude mcp add --scope project --transport http ops-tools https://mcp.example.com/mcp \
--header 'Authorization: Bearer ${MCP_TOKEN}'اضبط MCP_TOKEN في shell لديك حتى لا يظهر السر في .mcp.json بنص واضح؛ إذ يوسّع Claude Code قيمة ${MCP_TOKEN} من البيئة وقت القراءة.
تحمي كل وسيلة دفاع أعلاه نقطة النهاية، لا الوكيل الذي يملك الرمز بالفعل. وهذا هو الجانب الآخر من المشكلة: إذا كان عميلك هو DeepSeek Harness، فإن الإضافات التي تقيّد الأدوات التي يمكن للوكيل استدعاؤها وتفحص مخرجات الأدوات بحثاً عن تعليمات محقونة تتولى حماية ذلك الجانب.
الخطوة 6: تصحيح الأخطاء باستخدام MCP Inspector
عندما يتصرف الخادم بشكل غير صحيح، لا تخمّن السبب من داخل الوكيل. شغّله مباشرةً باستخدام Inspector، وهو عميل الاختبار الرسمي المستند إلى الويب. بالنسبة إلى خادم stdio، مرّر إليه الأمر نفسه الذي يشغّله الوكيل:
npx @modelcontextprotocol/inspector \
npx -y @modelcontextprotocol/server-filesystem /tmpيبدأ واجهة مستخدم على http://localhost:6274، وتطبع الإصدارات الحديثة عنوان URL يتضمن سلسلة استعلام MCP_PROXY_AUTH_TOKEN. استخدم الرابط نفسه تماماً، وإلا سترفضك الواجهة. كما يبدأ proxy على المنفذ 6277. انقر على Connect، ثم List Tools، ثم Call Tool مع وسيطات فعلية. إذا نجح الخادم في Inspector وفشل مع الوكيل، فالعطل في إعدادات عميلك وليس في الخادم. بالنسبة إلى خادم HTTP البعيد، اختر وسيلة النقل Streamable HTTP، وأدخل https://mcp.example.com/mcp، وأضف الرأس Authorization، ثم اتصل. هذه أسرع طريقة لإثبات صحة المصادقة وproxy قبل إشراك أي وكيل.
الحفاظ على تحديث الخوادم
يتطور MCP بسرعة، لذلك طبّق التصحيحات وفق جدول زمني. تجلب خوادم Node التي تُشغَّل باستخدام npx -y أحدث إصدار عند كل إنشاء، وهذا مريح لكنه لا يضمن قابلية إعادة الإنتاج؛ ثبّت الإصدار الدقيق الذي اختبرته، واقرأه من npm view @modelcontextprotocol/server-filesystem version وأضِفه إلى اسم الحزمة في .mcp.json (@modelcontextprotocol/server-filesystem@<version>) بعد أن يصبح الخادم مهماً، ثم حدّثه بشكل مقصود. حدّث خوادم Python التي تعمل ضمن systemd باستخدام sudo -H -u mcp /opt/mcp-ops/.venv/bin/pip install -U "mcp[cli]" ثم sudo systemctl restart mcp-ops. راقب مراجعة المواصفة التي يستهدفها SDK عند الترقية؛ فقد يؤدي الانتقال عبر الحد الفاصل بين SSE وStreamable-HTTP إلى تغيير وسيلة النقل التي يجب على العملاء طلبها.
أنماط الفشل، مع النصوص التي ستظهر لك
يُظهر الوكيل أن الخادم فشل. يطبع claude mcp list القيمة ✗ Failed to connect، وتعرض واجهة TUI النص MCP server 'filesystem' failed to start. شغّل claude --debug، وسترى عادةً Error: spawn npx ENOENT، أي إن الأمر غير موجود في PATH الخاص بالوكيل. بيئة التشغيل مفقودة أو ليست في المسار الذي يبحث فيه الوكيل: Node غير مثبّت، أو npx غير موجود، أو أن Python في virtualenv مُشار إليه باسم مختصر. صحّح الأمر باستخدام مسار مطلق أو ثبّت بيئة التشغيل، ثم أعد الاتصال.
يتصل خادم stdio ثم ينقطع فوراً. يسجّل العميل خطأ في تحليل JSON، مثل Unexpected token 'S', "Server sta"... is not valid JSON أو Failed to parse message. السبب واحد دائماً: كتب الخادم سطر سجل في stdout. في stdio، يكون stdout هو قناة JSON-RPC نفسها، لذلك يؤدي أي نص زائد إلى إفساد الدفق وفشل عملية المصافحة. في Node، يكتب console.log إلى stdout؛ استخدم console.error. في Python، يكتب print() المجرد إلى stdout؛ اكتب السجلات باستخدام logging المضبوط على sys.stderr، أو مرّر file=sys.stderr. القاعدة مطلقة: لا تضع في stdout مع stdio إلا JSON-RPC، وضع كل النص المخصص للقراءة البشرية في stderr.
تنتهي مهلة خادم بعيد أو يغلق الاتصال أثناء المصافحة. يفشل العميل مع MCP error -32000: Connection closed، أو تتوقف Inspector عند Connect ولا تعرض الأدوات مطلقاً. السبب خلف nginx هو التخزين المؤقت: يحتفظ الوكيل بدفق SSE بدلاً من إرساله، لذلك ينتظر العميل استجابة لا تصل. أضف proxy_buffering off;، مع بقية الكتلة في الخطوة 4، إلى location. تحقّق باستخدام curl -N مقابل عنوان URL العام؛ يجب أن ترى بيانات الأحداث تصل تدريجياً، لا أن تصل كلها دفعة واحدة في النهاية.
يُرفض التحقق من الهوية. يعرض العميل Error POSTing to endpoint (HTTP 401) أو 401 Unauthorized بوضوح. قد يكون الرأس مفقوداً، أو يكون الرمز المميز غير صحيح، أو تكون متغيرات shell فارغة عندما قرأ العميل الإعدادات. هذه حالة شائعة لأن ${MCP_TOKEN} يتمدد إلى لا شيء إذا لم يكن المتغير مضبوطاً، وعندها يرى nginx Bearer بلا قيمة. اطبع قيمة المتغير، وأضف الرأس من جديد، وتحقق من تطابق البايتات تماماً مع الرمز المميز الموجود في if الخاص بـnginx.
لا تبدأ الخدمة تحت systemd. يعرض journalctl -u mcp-ops القيمة ModuleNotFoundError: No module named 'mcp'، ويشير ExecStart إلى Python الموجود في النظام بدلاً من مفسّر virtualenv. أو يشير Address already in use إلى أن عملية أخرى تشغل المنفذ 8000؛ اعثر عليها باستخدام sudo ss -ltnp | grep 8000.
FAQ
ما خادم MCP تحديداً؟
إنه برنامج يوفّر أدوات وموارد لعميل يعمل بالذكاء الاصطناعي عبر Model Context Protocol باستخدام JSON-RPC 2.0. لا يشغّل نموذج الذكاء الاصطناعي الأداة بنفسه. بل يطلبها من العميل، ويستدعي العميل خادم MCP، ثم ينفّذ الخادم الأداة ويعيد النتيجة. وبما أن البروتوكول قياسي، يعمل الخادم الواحد مع أي عميل متوافق، سواء كان Claude Code أو Claude Desktop أو Gemini CLI.
ما الفرق بين نقل stdio ونقل HTTP؟
يشغّل العميل خادم stdio كعملية فرعية، ويتواصل معه عبر stdin/stdout. لذلك يبقى الخادم ويُنهى مع عميل واحد على جهاز واحد، ولا يحتاج إلى شبكة أو مصادقة. أما خادم HTTP فهو خدمة شبكة طويلة التشغيل يمكن لعدة عملاء الوصول إليها في الوقت نفسه. لذلك يحتاج إلى TLS ومصادقة. استخدم stdio للأدوات المحلية المخصصة لمستخدم واحد. واستخدم HTTP، وتحديداً Streamable HTTP في الخوادم الحالية، لأي شيء مشترك أو دائم التشغيل.
كيف أؤمّن خادم MCP بعيداً؟
افترض أن الخادم يتيح الوصول إلى أدوات تتعامل مع ملفاتك أو قاعدة بياناتك أو shell، ولا تعرّضه للشبكة من دون مصادقة. الخيار الأفضل هو إبقاؤه مرتبطاً بـlocalhost والوصول إليه عبر نفق SSH أو VPN خاص. وإذا كان يجب أن يكون متاحاً للعامة، فضعه خلف reverse proxy يفرض bearer token أو تدفق مصادقة MCP OAuth. أنشئ الرمز باستخدام openssl rand -hex 32، ولا تربط الخادم بـ0.0.0.0 من دون وضع أحد هذين الخيارين أمامه.
كيف أصلح مشكلة خادم لا يبدأ؟
تحقق أولاً من claude mcp list. يشير ✗ Failed to connect مع spawn ... ENOENT إلى أن الأمر أو بيئة التشغيل مفقودة. أصلح المسار أو ثبّت المكوّن المطلوب. إذا اتصل الخادم ثم انقطع مع ظهور خطأ في تحليل JSON، فهذا يعني أنه يكتب السجلات إلى stdout ويفسد تدفق JSON-RPC. انقل كل السجلات إلى stderr. في الحالات الأخرى، شغّل الأمر نفسه تماماً باستخدام MCP Inspector. فهو يشغّل الخادم بمعزل عن العميل، ما يتيح لك التمييز بين خطأ في الخادم ومشكلة في إعداد العميل.