دليل عملي لبناء خوادم MCP إنتاجية للوكلاء الذكية في 2026: من تعريف الأدوات والموارد، إلى اختيار وسيلة النقل، والمصادقة بـ OAuth 2.1، مع كود Python حقيقي وأخطاء يجب تجنبها.
بروتوكول سياق النموذج (MCP) هو معيار مفتوح يسمح للوكلاء الذكية بالاتصال بالأدوات ومصادر البيانات الخارجية عبر واجهة موحدة، بدلاً من بناء تكامل مخصص لكل نموذج وكل أداة. أطلقت Anthropic البروتوكول في نهاية 2024، وبحلول 2026 صار المعيار الفعلي لدى Claude وChatGPT وعدد من العملاء المستقلين. في هذا الدليل سأشرح كيف تبني خادم MCP إنتاجي من الصفر: تعريف الأدوات والموارد، اختيار وسيلة النقل المناسبة، والتعامل مع المصادقة والأمان والمراقبة، مع نقاط تعلمتها بالطريقة الصعبة وأنا أشحن خوادم لفرق حقيقية.
MCP يحل مشكلة "M×N"، حيث يحتاج كل نموذج إلى تكامل مخصص مع كل أداة، عبر فصل العملاء عن الخوادم بطبقة بروتوكول واحدة قائمة على JSON-RPC 2.0.
خادم MCP يقدم ثلاثة أنواع من القدرات: الأدوات (Tools) لتنفيذ الإجراءات، الموارد (Resources) لاسترجاع البيانات، والمطالبات (Prompts) لقوالب جاهزة للاستخدام.
هناك ثلاث وسائل نقل رئيسية في مواصفة 2025-06-18: stdio للأدوات المحلية، وStreamable HTTP للنشر السحابي، وSSE الذي تم استبداله رسمياً.
المصادقة في الخوادم البعيدة تتم عبر OAuth 2.1 مع PKCE وفقاً لمواصفة يونيو 2025، وليس عبر مفاتيح API مضمنة.
اختبار الخادم باستخدام MCP Inspector ضروري قبل الإنتاج، لأن الأخطاء الصامتة في وصف الأداة تؤدي إلى استدعاءات خاطئة من النموذج.
تقييم استخدام الأدوات (Tool-Use Evaluation) أهم من تحسين المطالبة. وكيل بأدوات سيئة الوصف سيفشل مهما كان النموذج قوياً.
ما هو بروتوكول MCP ولماذا يهم في 2026؟
بروتوكول سياق النموذج (Model Context Protocol) هو معيار مفتوح طورته Anthropic لتوحيد الطريقة التي تتصل بها تطبيقات الذكاء الاصطناعي بمصادر البيانات والأدوات الخارجية. فكر فيه كـ "USB-C للتطبيقات الذكية": بدلاً من كتابة تكامل مخصص لكل أداة (Slack, GitHub, Postgres, نظام ملفات داخلي…) لكل نموذج (Claude, GPT-5, Gemini)، تكتب خادم MCP واحد، ويستطيع أي عميل متوافق مع البروتوكول استخدامه فوراً.
المشكلة التي يحلها البروتوكول معروفة باسم مشكلة M×N: إذا كان لديك M من النماذج وN من الأدوات، فأنت تحتاج M×N من التكاملات. مع MCP، يصبح العدد M+N فقط. كل نموذج يحتاج إلى تطبيق العميل مرة واحدة، وكل أداة تحتاج إلى خادم مرة واحدة. هذا ليس تحسيناً تجميلياً؛ إنه التحول من بنية تكاملات هشة إلى نظام بيئي قابل للتركيب.
بصراحة، أول مرة جربت ربط Cursor مع ثلاث أدوات داخلية لفريقي، فهمت لماذا انتشر البروتوكول بهذه السرعة. في 2026، اعتمدت OpenAI رسمياً MCP في Agents SDK، وصار Claude Desktop وCursor وZed وWindsurf كلها عملاء MCP. مواصفة يونيو 2025 أضافت Streamable HTTP وOAuth 2.1 ووضوحاً في معالجة الأخطاء، مما جعل البروتوكول جاهزاً للإنتاج. وهذا أنهى عملياً عصر "كل وكيل يبني تكاملاته الخاصة".
البنية المعمارية لـ MCP: العملاء والخوادم والمضيفون
يستخدم البروتوكول ثلاثة مفاهيم أساسية تحتاج إلى التمييز بينها بوضوح قبل كتابة أي كود:
المضيف (Host): التطبيق الذي يستخدمه المستخدم نهائياً، مثل Claude Desktop أو Cursor. المضيف يدير دورة حياة العملاء.
العميل (Client): مكون داخل المضيف يحافظ على اتصال 1:1 مع خادم MCP محدد. تطبيق المضيف الواحد قد يحتوي على عشرات العملاء، كل واحد يتصل بخادم مختلف.
الخادم (Server): العملية التي تقدم الأدوات والموارد. هذا ما ستكتبه أنت غالباً.
يتم الاتصال عبر JSON-RPC 2.0، وهو بروتوكول استدعاء إجراءات بعيدة بسيط ومثبت. كل رسالة لها method وparams وid، والاستجابة تحتوي على result أو error. لا حاجة لاختراع شيء جديد، لأن JSON-RPC اختير تحديداً ليكون قابلاً للتنفيذ في أي لغة دون مكتبات ثقيلة.
عند بدء الاتصال، يقوم العميل بإجراء "مصافحة التهيئة" (Initialize Handshake) حيث يتفاوض الطرفان على الإصدار والقدرات المدعومة. الخادم يعلن أياً من Tools/Resources/Prompts يدعم، والعميل يعلن قدراته (هل يدعم العميل إشعارات التغيير؟ التحكم في النموذج؟). هذا التفاوض يتيح للبروتوكول التطور دون كسر العملاء الأقدم.
الفرق بين Tools وResources وPrompts
هذا هو المفهوم الأكثر سوء فهماً لدى المبتدئين. ما الفرق بين الثلاثة، ومتى تستخدم كلاً منها؟
المعيار
Tools (الأدوات)
Resources (الموارد)
Prompts (المطالبات)
من يتحكم؟
النموذج
التطبيق
المستخدم
الغرض
تنفيذ إجراء
قراءة بيانات
قالب جاهز
أمثلة
إرسال بريد، تشغيل استعلام SQL
محتوى ملف، نتيجة استعلام
"لخص هذا المستند"
الآثار الجانبية
نعم عادة
لا (قراءة فقط)
لا
كيفية الاستدعاء
tools/call
resources/read
prompts/get
الشبيه
POST endpoint
GET endpoint
ماكرو أو قالب
القاعدة العملية: إذا كان للعملية أثر جانبي (إنشاء، تحديث، حذف، إرسال)، استخدم Tool. إذا كانت قراءة خالصة بدون آثار جانبية ويمكن تخزينها مؤقتاً، استخدم Resource. إذا كانت قالباً يستدعيه المستخدم من قائمة منسدلة في تطبيقه، استخدم Prompt.
الخطأ الأكثر شيوعاً هو تحويل كل شيء إلى Tool. هذا يضخم نافذة السياق بأوصاف لا داعي لها ويربك النموذج. الموارد لا تُعرض للنموذج تلقائياً؛ التطبيق المضيف يقرر ما يضعه في السياق، وهذا منفصل تماماً عن النموذج. لمعالجة هذا التمييز بعمق، راجع دليل هندسة السياق للوكلاء الذكية الذي يشرح متى يكون كل تمثيل مناسباً.
بناء أول خادم MCP بالـ Python خطوة بخطوة
سأبني الآن خادم MCP بسيطاً يقدم أداتين: واحدة لقراءة قاعدة بيانات SQLite، وأخرى لإنشاء تذاكر دعم. سأستخدم المكتبة الرسمية mcp الإصدار 1.10 (2026).
الآن الخادم نفسه. لاحظ أنني أستخدم FastMCP، وهي واجهة عالية المستوى تعتمد على الأنواع التوضيحية لتوليد مخططات JSON Schema تلقائياً، وهذا يقلل الأخطاء بشكل كبير:
from mcp.server.fastmcp import FastMCP
from pydantic import BaseModel, Field
import aiosqlite
mcp = FastMCP("support-desk")
class TicketInput(BaseModel):
title: str = Field(..., description="ملخص قصير للمشكلة")
priority: str = Field("medium", description="منخفض، متوسط، عالٍ، حرج")
customer_email: str = Field(..., description="بريد العميل الإلكتروني")
@mcp.tool()
async def create_ticket(payload: TicketInput) -> dict:
"""ينشئ تذكرة دعم جديدة في النظام الداخلي.
استخدم هذا فقط عندما يطلب المستخدم صراحة فتح تذكرة.
يعيد رقم التذكرة ورابط المتابعة.
"""
async with aiosqlite.connect("support.db") as db:
cursor = await db.execute(
"INSERT INTO tickets(title, priority, email) VALUES (?, ?, ?)",
(payload.title, payload.priority, payload.customer_email)
)
await db.commit()
ticket_id = cursor.lastrowid
return {
"ticket_id": ticket_id,
"url": f"https://support.example.com/t/{ticket_id}",
"status": "open"
}
@mcp.tool()
async def search_tickets(query: str, limit: int = 10) -> list[dict]:
"""يبحث في تذاكر الدعم بنص حر. يعيد قائمة بأحدث المطابقات."""
async with aiosqlite.connect("support.db") as db:
db.row_factory = aiosqlite.Row
rows = await db.execute_fetchall(
"SELECT id, title, priority, status FROM tickets "
"WHERE title LIKE ? ORDER BY id DESC LIMIT ?",
(f"%{query}%", limit)
)
return [dict(r) for r in rows]
if __name__ == "__main__":
mcp.run(transport="stdio")
ثلاث نقاط حاسمة في هذا الكود تستحق التوقف عندها:
وصف الأداة (docstring) هو واجهة برمجة التطبيقات الفعلية للنموذج. ما تكتبه هنا هو ما يقرأه النموذج ليقرر متى يستدعي الأداة. اكتبه بعناية، واذكر القيود ("استخدم هذا فقط عندما...").
أنواع Pydantic تتحول إلى JSON Schema تلقائياً. هذا يمنع النموذج من إرسال بيانات مشوهة، ويوفر عليك كتابة التحقق يدوياً.
القيمة المُعادة يجب أن تكون قابلة للتسلسل JSON. النموذج يرى ما تعيده كنص. كائنات datetime أو bytes أو objects مخصصة ستفشل بصمت. (وقعت في هذا في أول مشروع لي وضيّعت ساعتين قبل أن أنتبه.)
اختيار وسيلة النقل: stdio أم Streamable HTTP؟
تدعم مواصفة 2025-06-18 وسيلتين رئيسيتين للنقل، وأخرى مهجورة لا تزال موجودة للتوافق العكسي:
stdio: العملية الأم (المضيف) تشغل خادم MCP كعملية ابن، وتتواصل عبر stdin/stdout. سريع، آمن افتراضياً (لا شبكة)، ومثالي للأدوات المحلية. هذا ما يستخدمه Claude Desktop لأغلب خوادمه.
Streamable HTTP: الطريقة الجديدة المعتمدة منذ يونيو 2025 للخوادم البعيدة. نقطة نهاية HTTP واحدة تدعم كلاً من الطلبات الفردية وتدفقات Server-Sent Events. الخادم يقرر متى يفتح تدفقاً.
SSE (مهجورة): الطريقة الأقدم التي كانت تتطلب نقطتي نهاية منفصلتين. لا تبنِ عليها مشاريع جديدة.
للأدوات الداخلية على أجهزة المطورين: stdio. للخدمات السحابية متعددة المستأجرين: Streamable HTTP. لا تخلط بين الاثنين في نفس الخادم، واجعل القرار صريحاً في الإعداد.
لتحويل المثال السابق إلى Streamable HTTP، غيّر السطر الأخير فقط:
if __name__ == "__main__":
mcp.run(transport="streamable-http", host="0.0.0.0", port=8080)
المصادقة والأمان: OAuth 2.1 وعزل الأدوات
الخوادم المحلية عبر stdio آمنة افتراضياً لأنها ترث صلاحيات المستخدم وتعمل في عمليته. المشكلة الحقيقية تظهر مع الخوادم البعيدة. هنا تنص مواصفة يونيو 2025 على استخدام OAuth 2.1 مع PKCE كآلية مصادقة قياسية.
الفكرة الأساسية: لا تضع مفاتيح API في إعداد العميل. بدلاً من ذلك، يطلب الخادم من العميل بدء تدفق OAuth، يفتح العميل المتصفح، المستخدم يصادق، الخادم يحصل على رمز وصول، ويخزنه بأمان. هذا يحل ثلاث مشاكل دفعة واحدة:
التفويض الدقيق: كل مستخدم يصادق بصلاحياته الخاصة، فلا يستطيع وكيل المستخدم A الوصول إلى بيانات المستخدم B عن طريق الخطأ.
الإبطال: يستطيع المستخدم سحب الوصول من لوحة تحكم مزود الهوية دون لمس إعداد الخادم.
المراجعة (Audit): كل استدعاء أداة مرتبط بهوية حقيقية، مما يجعل سجلات الأمان قابلة للقراءة.
للتعمق في كيفية بناء وكيل يستخدم أدوات بأمان مع التحقق من المخرجات في كل خطوة، راجع دليل بناء أنظمة RAG الإنتاجية الذي يغطي طبقات التحقق نفسها في سياق الاسترجاع.
النشر الإنتاجي والمراقبة
نشر خادم MCP في الإنتاج يتضمن خمسة قرارات لا يمكنك تأجيلها:
1. حدود المعدل (Rate Limiting)
الوكلاء يستدعون الأدوات بمعدلات لا يمكن التنبؤ بها. وكيل في حلقة فاشلة قد يستدعي أداة 200 مرة في الدقيقة. ضع حدوداً على مستوى الرمز (token) وليس على مستوى عنوان IP، لأن عميلاً واحداً قد يخدم عدة مستخدمين.
2. المهلات (Timeouts)
كل أداة يجب أن يكون لها مهلة صريحة. النموذج سينتظر طوال مدة المهلة، مما يستهلك ميزانية وقت المستخدم. القاعدة العملية: 30 ثانية حد أقصى لأي أداة تفاعلية. الأدوات الأطول يجب أن تعيد رمز عمل، وأن تنتج أداة استعلام منفصلة للحالة.
3. التتبع (Tracing)
كل استدعاء أداة يجب أن يحمل معرّف ربط (correlation ID) من العميل عبر الخادم إلى أي خدمة خلفية. هذا يجعل تصحيح "لماذا قام الوكيل بإرسال البريد إلى الشخص الخطأ؟" ممكناً. استخدم OpenTelemetry، فهو معيار صناعي ومدعوم بشكل أصيل في mcp 1.10.
4. التقييم (Evaluation)
اختبر استخدام الأدوات نفسه، وليس فقط جودة الإجابة. اجمع مجموعة من سيناريوهات حقيقية، شغّل وكيلك عليها، وسجّل: هل اختار الأداة الصحيحة؟ هل مرّر المعاملات الصحيحة؟ هل توقف عند الحصول على النتيجة بدلاً من الاستدعاء مرة أخرى؟ هذا الجزء يتجاهله أغلب الفرق، وهو السبب الأول لفشل الوكلاء في الإنتاج. (شخصياً، لم أرَ مشروعاً وكيلياً ناجحاً في الإنتاج لا يملك خط أنابيب تقييم لائق.)
5. تخزين الحالة (State Storage)
اجعل الخادم بلا حالة (stateless) قدر الإمكان. أي حالة يجب أن تكون في قاعدة بيانات خارجية، وليست في الذاكرة. هذا يبسط النشر الأفقي ويتعامل مع إعادة تشغيل الخادم بشكل أنيق.
هذه الأخطاء رأيتها مراراً في 2025-2026 لدى فرق تنتقل من تكاملات مخصصة إلى MCP:
وصف أداة مبهم. "أداة بريد إلكتروني" لا تخبر النموذج متى يستخدمها. اكتب بدلاً من ذلك: "ترسل بريداً إلى عنوان واحد. استخدمها فقط بعد تأكيد المستخدم الصريح. لا تستخدمها للتسويق الجماعي."
عدد أدوات هائل. 50 أداة في خادم واحد تجعل النموذج يضيع. القاعدة العملية: لا تتجاوز 15-20 أداة لكل خادم. إذا احتجت أكثر، قسّم إلى خوادم منطقية.
إرجاع HTML أو JSON خام بدلاً من بنى مفيدة. النموذج يحتاج إلى نص أو JSON منسق بمفاتيح ذات معنى، لا 200KB من HTML خام.
تجاهل الأخطاء. أرجع رسائل خطأ واضحة قابلة للقراءة من النموذج: "لم يتم العثور على المستخدم بهذا البريد. تأكد من التهجئة." لا تكتفِ بإرجاع رمز خطأ HTTP.
دمج التحقق من الإذن مع منطق الأداة. افصل بين "هل يستطيع هذا المستخدم استدعاء هذه الأداة؟" و"ماذا تفعل الأداة؟"، لأن هذا يبسط الاختبار ويمنع تسرب الصلاحيات.
عدم وجود إصدار للأدوات (Versioning). عندما تغيّر مخطط أداة، الوكلاء الذين يستخدمون النسخة القديمة سينكسرون. أبقِ النسخ القديمة مع deprecated: true لمدة معقولة.
النظام البيئي لـ MCP في 2026
بحلول منتصف 2026، هناك أكثر من 2,000 خادم MCP عام في المستودع الرسمي، يغطي معظم الأدوات الشائعة:
الاتصالات: Slack, Discord, Microsoft Teams, Gmail.
تطوير البرمجيات: GitHub, GitLab, Linear, Jira, Sentry.
قواعد البيانات: Postgres, MySQL, Snowflake, BigQuery, MongoDB.
التخزين السحابي: S3, Google Drive, Dropbox.
الإنتاجية: Notion, Linear, Asana, Google Workspace.
المراقبة: Datadog, Grafana, PagerDuty.
قبل بناء خادم خاص، ابحث في مستودع الخوادم الرسمي. الكثير مما تظنه فريداً لعملك مغطى بالفعل بطريقة قابلة للتمديد. أكبر القيم التي يقدمها MCP لفريقك ستأتي من ربط أدواتك الداخلية، وليس من إعادة بناء خادم Slack.
أخيراً، نصيحة عملية بناءً على ما رأيته: لا تتعامل مع MCP كحل سحري. هو بروتوكول، ليس وكيلاً. الوكلاء الجيدون يحتاجون أيضاً إلى هندسة سياق محكمة، وتقييم منهجي، وأدوات مصممة بعناية. البروتوكول يخفض تكلفة التكامل، لكنه لا يعالج المشكلة الجوهرية: استخدامُ أداةٍ سيئٌ تماماً كما هو دون MCP.
الأسئلة الشائعة
هل MCP بديل لـ Function Calling أم مكمل له؟
مكمل. النموذج لا يزال يستخدم آلية Function Calling الأصلية لاستدعاء الأدوات. MCP يحدد كيف يكتشف الوكيل تلك الأدوات ويتصل بمصادرها عبر العملية أو الشبكة. تستطيع استخدام MCP مع أي نموذج يدعم استدعاء الأدوات، بما في ذلك Claude وGPT-5 وGemini.
ما الفرق بين خادم MCP وملحق ChatGPT (Plugin)؟
ملحقات ChatGPT كانت محدودة بـ OpenAI وتعتمد على OpenAPI. أما MCP فهو معيار مفتوح متعدد البائعين، يستخدم JSON-RPC، ويدعم Tools وResources وPrompts بدلاً من الأدوات فقط. بحلول 2026 تخلت OpenAI عن نظام الملحقات القديم لصالح MCP.
هل يمكن بناء خادم MCP بلغة غير Python؟
نعم. المواصفة تعتمد على JSON-RPC 2.0 فقط، لذا أي لغة تستطيع إرسال واستقبال JSON عبر stdio أو HTTP تستطيع تنفيذ خادم. توجد SDK رسمية لـ TypeScript وPython وKotlin وC# وSwift وJava في 2026، إضافة إلى تطبيقات مجتمعية لـ Go وRust وRuby.
كيف أختبر خادم MCP قبل النشر؟
استخدم MCP Inspector الرسمي عبر npx @modelcontextprotocol/inspector. يفتح واجهة ويب تتيح لك استدعاء الأدوات يدوياً، فحص المخططات المولّدة، ومراقبة رسائل JSON-RPC الخام. بعد ذلك، اربط الخادم بـ Claude Desktop أو Cursor للاختبار الواقعي مع نموذج حقيقي.
هل MCP آمن للاستخدام مع البيانات الحساسة؟
البروتوكول نفسه آمن إذا استُخدم بشكل صحيح: stdio يبقى محلياً، وStreamable HTTP يدعم OAuth 2.1 وTLS. الخطر الأكبر هو حقن الأدوات (Tool Injection) من محتوى غير موثوق. عامل كل مدخل كمدخل خبيث، استخدم قوائم بيضاء صارمة، وراجع كل استدعاء أداة في السجلات. لا تعرض أبداً أداة "تنفيذ SQL خام" على بيانات إنتاج حساسة.
كم عدد الأدوات الذي يجب أن يقدمه خادم MCP واحد؟
القاعدة العملية: 15-20 أداة كحد أقصى لكل خادم. ما بعد ذلك يصبح النموذج مرتبكاً ويختار الأداة الخاطئة. إذا كان مجالك يحتاج إلى المزيد، قسّمه إلى خوادم منطقية (مثلاً خادم "قراءة" وخادم "كتابة"). الكثير من الأدوات يشير عادة إلى أن تجريداتك في المستوى الخطأ.
دليل عملي شامل لضبط النماذج اللغوية الكبيرة بتقنيتي LoRA وQLoRA في 2026، مع كود بايثون كامل باستخدام Unsloth. اضبط نموذج 8B بذاكرة 8 جيجابايت وبتكلفة أقل من 10 دولارات.
دليل عملي شامل لبناء أنظمة RAG الإنتاجية في 2026: من التقسيم الذكي وقواعد البيانات المتجهية إلى GraphRAG وRAG الوكيلي، مع أمثلة بالكود ومنهجيات التقييم.