بناء MCP Server من الصفر بالعربي: الدليل العملي الشامل لإنشاء خادم Model Context Protocol مخصص في 2026

⏱️ مدة القراءة: 7 دقيقة

ستجد في هذا المقال شرحًا مباشرًا وخطوات عملية مختصرة تساعدك على التطبيق بسرعة.

رسم توضيحي يشرح بنية بناء MCP Server بالعربية: ربط نموذج الذكاء الاصطناعي Claude بالأدوات الخارجية عبر بروتوكول Model Context Protocol

منذ أن أطلقت Anthropic بروتوكول Model Context Protocol (MCP) في أواخر 2024، تحوّل من تجربة هندسية إلى المعيار الفعلي لربط نماذج الذكاء الاصطناعي بالعالم الخارجي. في 2026 لم يعد المشهد كما كان: OpenAI دعمته رسمياً في ChatGPT و Codex، Google أضافته إلى Gemini، Microsoft بَنَت عليه Copilot Studio، وأصبح كل IDE حديث (Cursor، Windsurf، Antigravity، Zed) يقرأ خوادم MCP افتراضياً.

المشكلة؟ ٩٩٪ من المحتوى التعليمي عن بناء خادم MCP حصري بالإنجليزية. هذا الدليل يسد الفجوة: ستتعلم بناء خادم MCP حقيقي من الصفر بالعربية، بأمثلة عملية تشتغل فعلاً، وبأسلوب يجعلك تفهم ما يحدث في كل سطر — لا مجرد نسخ ولصق.

هذا الدليل موجّه للمطورين العرب الذين سبق وقرأوا دليلنا التعريفي لبروتوكول MCP ويريدون الآن الانتقال من الاستهلاك إلى البناء. ستخرج من هذا المقال وأنت قادر على تشغيل خادمك المخصص في Claude Desktop أو Cursor خلال ساعة واحدة.

ماذا ستتعلم في هذا الدليل؟

  • الفرق العملي بين استهلاك خوادم MCP جاهزة وبناء واحد مخصص.
  • البنية الداخلية لأي MCP Server: Tools، Resources، Prompts، وTransports.
  • كتابة خادم “Hello World” بالـPython في أقل من 30 سطر.
  • بناء خادم واقعي يستدعي API خارجي (الطقس) مع معالجة الأخطاء.
  • بناء مدير ملاحظات كامل (Tools + Resources + Prompts) — مشروع تخرّجك من هذا الدليل.
  • ربط الخادم بـClaude Desktop، Claude Code، Cursor، و Windsurf.
  • التصحيح باستخدام MCP Inspector، والاختبار، والنشر بـDocker.
  • الثغرات الأمنية الشائعة في خوادم MCP وكيفية تجنبها.

لماذا تبني خادم MCP خاص بك بدلاً من استخدام الجاهز؟

السؤال مشروع. هناك آلاف خوادم MCP الجاهزة في المستودع الرسمي ومخازن المجتمع. لكن في الممارسة الفعلية، ستجد نفسك تبني خادمك المخصص في الحالات التالية:

  • أدوات داخلية في شركتك: ربط Claude بـCRM داخلي، قاعدة بيانات، أو ERP لا يوجد له خادم جاهز.
  • منطق أعمال خاص: تريد أن يستدعي الذكاء الاصطناعي دالة حساب_العمولة وفق قواعد شركتك بدلاً من إعطائه صلاحية تنفيذ SQL مفتوح.
  • تكامل عبر بروتوكولات غير قياسية: ربط أجهزة IoT، أو خدمات SOAP قديمة، أو APIs غير REST.
  • تقليل التعرّض الأمني: بدلاً من إعطاء Claude صلاحية دخول على نظامك كاملاً، تكشف فقط الدوال التي تريدها.
  • تجميع عدة خدمات في واجهة واحدة: خادم MCP واحد يخدم Slack + Notion + قاعدة بياناتك بدلاً من تشغيل ثلاثة خوادم منفصلة.

القاعدة الذهبية: إذا كان الحل الجاهز يحقق ٨٠٪ مما تريد، استخدمه ثم وسّعه. أما إذا أحتاج إلى تطبيق منطق خاص بمؤسستك، ابنِ خادماً مخصصاً.

البنية الداخلية لـMCP Server

قبل أن نكتب سطراً واحداً من الكود، يجب أن نفهم القطع الثلاث التي يتكوّن منها أي خادم MCP. التشبيه الأقرب: تخيّل أنك تبني API لطفل ذكي جداً — تحتاج أن تخبره ثلاثة أشياء:

1. Tools (الأدوات) — ماذا تستطيع أن تفعل؟

الـTools هي الدوال القابلة للتنفيذ. كل أداة لها اسم، وصف، ومخطط مدخلات (JSON Schema). عندما يقرر النموذج استدعاء أداة، يرسل الخادم المدخلات المنظمة فينفّذ الكود ويعيد النتيجة.

مثال: أداة get_weather(city: str) تستدعي خدمة طقس وترجع درجة الحرارة. الأداة هي “الفعل” الذي يقرر النموذج تنفيذه.

2. Resources (الموارد) — ماذا تستطيع أن تقرأ؟

الـResources هي بيانات للقراءة فقط، يمكن للنموذج (أو المستخدم) قراءتها كمصدر مرجعي. كل مورد له uri فريد مثل notes://daily/2026-05-15 أو file:///etc/config.json.

الفرق الجوهري بين Tool و Resource: الأداة تنفّذ شيئاً، والمورد يكشف بيانات. الأداة قد يكون لها تأثير جانبي (تكتب في DB، ترسل بريداً)، أما المورد فآمن للقراءة المتكررة.

3. Prompts (القوالب) — ماذا تستطيع أن تقترح؟

الـPrompts قوالب جاهزة يستطيع المستخدم استدعاؤها بسرعة. مثلاً: قالب review_pr يأخذ رقم PR ويبني تعليمات مراجعة كاملة. الـPrompts تظهر في واجهة Claude Desktop كقائمة منسدلة (Slash commands).

4. Transports (وسائل النقل)

هذه قناة الاتصال بين العميل (Claude) والخادم. لديك ثلاثة خيارات:

  • stdio: الأبسط والأشيع للتطوير المحلي. الخادم يقرأ من stdin ويكتب على stdout.
  • Streamable HTTP: للنشر السحابي. الموصى به في 2026 (حلّ محل SSE القديم).
  • SSE القديم: ما زال مدعوماً لكنه طريق للنفاد — لا تستخدمه لمشاريع جديدة.

المتطلبات قبل البدء

  • Python 3.10+ (سنستخدمه في الأمثلة). البديل: Node.js 18+ مع @modelcontextprotocol/sdk.
  • مدير الحزم uv (موصى به من Anthropic) أو pip التقليدي.
  • محرر مع دعم MCP: Claude Desktop للاختبار الأولي، أو Cursor / Claude Code.
  • معرفة أساسية بـasync/await في Python.

أنصح بـuv لأنه يدير البيئات والاعتماديات في خطوة واحدة. تثبيته على أي نظام:

# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

# تحقق من التثبيت
uv --version

المثال الأول: Hello World — أبسط MCP Server في 25 سطر

سنبدأ بأبسط ما يمكن: خادم يقدّم أداة واحدة فقط، echo، تعيد النص الذي أرسله المستخدم. الهدف هو فهم البنية لا أكثر.

أنشئ مجلداً جديداً وهيّئ المشروع:

uv init mcp-hello
cd mcp-hello
uv add "mcp[cli]"

الآن أنشئ ملف server.py:

from mcp.server.fastmcp import FastMCP

# تعريف الخادم باسم وإصدار
mcp = FastMCP("hello-server")

@mcp.tool()
def echo(message: str) -> str:
    """ترجع الرسالة كما هي — أداة بسيطة للاختبار.

    Args:
        message: النص المراد إرجاعه
    """
    return f"تم استقبال: {message}"

if __name__ == "__main__":
    # يشتغل عبر stdio افتراضياً
    mcp.run()

هذا كل شيء. FastMCP هي الطبقة الموصى بها من المكتبة الرسمية، تُخفي معظم التعقيد. الديكوريتر @mcp.tool() يحوّل أي دالة Python إلى أداة MCP. وصف الدالة (docstring) يصبح وصف الأداة الذي يقرأه النموذج، والـtype hints تتحول تلقائياً إلى JSON Schema للمدخلات.

اختبر الخادم بـMCP Inspector:

uv run mcp dev server.py

سيفتح المتصفح على http://localhost:6274 مع واجهة تفاعلية. اختر تبويب “Tools”، اضغط على echo، أدخل أي نص، واضغط “Run”. إذا رأيت الرد، فأنت رسمياً مطوّر MCP الآن.

المثال الثاني: خادم الطقس — التعامل مع APIs خارجية

الـHello World ممتاز للفهم، لكنه عديم النفع. الآن نبني شيئاً مفيداً فعلاً: خادم يستعلم عن طقس أي مدينة عبر Open-Meteo (مجاني بلا مفتاح API).

uv init mcp-weather
cd mcp-weather
uv add "mcp[cli]" httpx

محتوى server.py:

import httpx
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("weather-server")

# دالة مساعدة لتحويل اسم المدينة إلى إحداثيات
async def _geocode(city: str) -> tuple[float, float, str] | None:
    url = "https://geocoding-api.open-meteo.com/v1/search"
    async with httpx.AsyncClient(timeout=10.0) as client:
        r = await client.get(url, params={"name": city, "count": 1, "language": "ar"})
        r.raise_for_status()
        data = r.json()
    results = data.get("results") or []
    if not results:
        return None
    first = results[0]
    return first["latitude"], first["longitude"], first["name"]

@mcp.tool()
async def get_weather(city: str) -> str:
    """تجلب الطقس الحالي لمدينة معينة بالعربية.

    Args:
        city: اسم المدينة (عربي أو إنجليزي). مثل: دمشق، الرياض، Cairo
    """
    coords = await _geocode(city)
    if coords is None:
        return f"لم أتمكن من إيجاد المدينة '{city}'. تحقق من الإملاء."

    lat, lon, official_name = coords
    url = "https://api.open-meteo.com/v1/forecast"
    params = {
        "latitude": lat,
        "longitude": lon,
        "current": "temperature_2m,relative_humidity_2m,wind_speed_10m,weather_code",
        "timezone": "auto",
    }
    async with httpx.AsyncClient(timeout=10.0) as client:
        r = await client.get(url, params=params)
        r.raise_for_status()
        data = r.json()

    cur = data["current"]
    return (
        f"الطقس في {official_name}:\n"
        f"- درجة الحرارة: {cur['temperature_2m']}°C\n"
        f"- الرطوبة: {cur['relative_humidity_2m']}%\n"
        f"- سرعة الرياح: {cur['wind_speed_10m']} كم/س"
    )

if __name__ == "__main__":
    mcp.run()

نقاط مهمة في هذا المثال تستحق التوقف:

  • الدالة async: عندما تستدعي API خارجي، استخدم async/await دائماً. الخادم نفسه عبر event loop واحدة، وأي blocking call يجمّد كل الطلبات الأخرى.
  • timeout صريح: لا تترك httpx بلا timeout. تجمّد عميل MCP لـ60 ثانية ينتج تجربة مزعجة.
  • raise_for_status(): نريد رفع استثناء واضح عند خطأ HTTP، لا إخفاءه.
  • رسائل خطأ بشرية: عند فشل الـgeocoding، نعيد جملة عربية مفهومة بدلاً من استثناء غامض.
  • الناتج نصي منسّق: النموذج يقرأ النص ويعيد صياغته للمستخدم. لا حاجة لـJSON معقّد.

المثال الثالث (مشروع التخرج): مدير ملاحظات كامل

الآن نبني شيئاً يجمع الأنواع الثلاثة: Tools (إضافة/حذف/بحث)، Resources (قراءة قائمة الملاحظات)، وPrompts (قالب جاهز لتلخيص الملاحظات).

uv init mcp-notes
cd mcp-notes
uv add "mcp[cli]"

ملف server.py كاملاً:

import json
from datetime import datetime
from pathlib import Path
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("notes-server")

# نخزّن الملاحظات في ملف JSON بسيط بجانب الخادم
DATA_FILE = Path.home() / ".mcp_notes.json"

def _load() -> dict:
    if not DATA_FILE.exists():
        return {}
    return json.loads(DATA_FILE.read_text(encoding="utf-8"))

def _save(notes: dict) -> None:
    DATA_FILE.write_text(
        json.dumps(notes, ensure_ascii=False, indent=2),
        encoding="utf-8"
    )

# ============== Tools ==============

@mcp.tool()
def add_note(title: str, body: str) -> str:
    """يضيف ملاحظة جديدة برمز فريد.

    Args:
        title: عنوان الملاحظة
        body: نص الملاحظة
    """
    notes = _load()
    note_id = datetime.now().strftime("%Y%m%d%H%M%S")
    notes[note_id] = {
        "title": title,
        "body": body,
        "created_at": datetime.now().isoformat(),
    }
    _save(notes)
    return f"تمت إضافة الملاحظة برمز: {note_id}"

@mcp.tool()
def delete_note(note_id: str) -> str:
    """يحذف ملاحظة بمعرّفها.

    Args:
        note_id: رمز الملاحظة (مثل 20260515103000)
    """
    notes = _load()
    if note_id not in notes:
        return f"الملاحظة {note_id} غير موجودة."
    deleted = notes.pop(note_id)
    _save(notes)
    return f"تم حذف: {deleted['title']}"

@mcp.tool()
def search_notes(query: str) -> str:
    """يبحث في الملاحظات بالعنوان أو المتن.

    Args:
        query: نص البحث
    """
    notes = _load()
    q = query.strip().lower()
    matches = [
        f"[{nid}] {n['title']}\n{n['body'][:100]}..."
        for nid, n in notes.items()
        if q in n["title"].lower() or q in n["body"].lower()
    ]
    if not matches:
        return f"لا توجد ملاحظات تطابق '{query}'."
    return "\n\n".join(matches)

# ============== Resources ==============

@mcp.resource("notes://list")
def list_notes() -> str:
    """يعرض كل الملاحظات كمصدر للقراءة."""
    notes = _load()
    if not notes:
        return "لا توجد ملاحظات بعد."
    lines = [
        f"- [{nid}] {n['title']}  ({n['created_at'][:10]})"
        for nid, n in sorted(notes.items(), reverse=True)
    ]
    return "\n".join(lines)

@mcp.resource("notes://{note_id}")
def get_note(note_id: str) -> str:
    """يقرأ ملاحظة محددة."""
    notes = _load()
    if note_id not in notes:
        return f"الملاحظة {note_id} غير موجودة."
    n = notes[note_id]
    return f"# {n['title']}\n\nأنشئت: {n['created_at']}\n\n{n['body']}"

# ============== Prompts ==============

@mcp.prompt()
def summarize_recent(days: int = 7) -> str:
    """قالب جاهز لتلخيص ملاحظات آخر فترة."""
    return (
        f"اقرأ كل ملاحظاتي من آخر {days} أيام عبر المورد notes://list، "
        f"ثم استخرج منها 3-5 موضوعات رئيسية مع توصيات عملية لكل موضوع."
    )

if __name__ == "__main__":
    mcp.run()

ما الذي يجعل هذا المثال “حقيقياً”؟

  • تخزين دائم: استخدمنا ملف JSON. في الإنتاج تستبدله بـSQLite أو Postgres، لكن المبدأ ذاته.
  • URIs ديناميكية للموارد: notes://{note_id} تستخدم متغيراً يمرر تلقائياً من العميل. هذا يسمح للنموذج بقراءة أي ملاحظة بالاسم.
  • Prompt كقالب قابل للتعديل: المستخدم في Claude Desktop سيرى /summarize_recent ويستطيع تمرير days مخصصة.
  • ترميز UTF-8 صريح: ضروري للعربية. إذا نسيت encoding="utf-8" ستظهر ملاحظاتك مشوّهة على Windows.

ربط خادمك بـ Claude Desktop

الآن وصلنا إلى الجزء الممتع: تشغيل خادمك داخل تطبيق Claude الرسمي. افتح ملف الإعدادات حسب نظامك:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json

أضف خادمك:

{
  "mcpServers": {
    "notes": {
      "command": "uv",
      "args": [
        "--directory",
        "/path/to/mcp-notes",
        "run",
        "server.py"
      ]
    }
  }
}

استبدل المسار بمسار مجلد مشروعك الحقيقي. ثم أغلق Claude Desktop تماماً وأعد فتحه (الإغلاق من Menu Bar لا من النافذة فقط). ستظهر أيقونة مطرقة 🔨 في أسفل صندوق الدردشة تشير إلى عدد الأدوات المتاحة. اضغطها لرؤية أدواتك الثلاث.

الآن جرّب: “أضف ملاحظة بعنوان ‘فكرة مشروع’ ومتنها ‘بناء خادم MCP للبريد الإلكتروني’، ثم اعرض قائمة ملاحظاتي”. Claude سيستدعي add_note ثم يقرأ المورد notes://list ويعرض النتيجة.

ربط الخادم بـ Cursor و Claude Code

إذا كنت تستخدم Cursor، الإعداد عبر Settings → MCP → Add new MCP server. تستطيع لصق نفس بنية JSON أعلاه.

لـClaude Code، استخدم الأمر:

claude mcp add notes -- uv --directory /path/to/mcp-notes run server.py

ثم تحقق:

claude mcp list

يمكنك أيضاً مشاركة الإعداد عبر .mcp.json في جذر المشروع، فيستخدمه فريقك كاملاً.

التصحيح: عندما يتوقّف كل شيء عن العمل

سترى هذا السيناريو كثيراً: تعدّل الكود، تعيد تشغيل Claude، لا شيء يظهر. أدوات التصحيح الأساسية:

  • MCP Inspector: شغّل uv run mcp dev server.py أولاً. إذا اشتغل هنا، فالمشكلة في الإعداد لا في الكود.
  • لوغات Claude Desktop: على macOS تجدها في ~/Library/Logs/Claude/mcp*.log. على Windows في %APPDATA%\Claude\Logs\. هذه أول مكان أنظر إليه عند أي مشكلة.
  • اطبع على stderr لا stdout: في خادم stdio، stdout مخصص للبروتوكول. أي print() يفسد الاتصال. استخدم import sys; print("debug", file=sys.stderr).
  • أخطاء المسارات: استخدم مسارات مطلقة دائماً في claude_desktop_config.json. ~ لا يُحلّ تلقائياً.

إذا اشتغل في Inspector لكن فشل في Claude، السبب الأشيع: مسار uv ليس في PATH عند تشغيل Claude. استخدم المسار المطلق:

which uv
# مثال: /Users/you/.local/bin/uv

# استبدل في الإعدادات
"command": "/Users/you/.local/bin/uv"

النشر في الإنتاج: من stdio إلى HTTP

الخادم عبر stdio رائع للتطوير المحلي، لكنه لا يصلح لخادم يخدم فريقاً كاملاً. للإنتاج تنتقل إلى Streamable HTTP. FastMCP يدعمه بسطر واحد:

if __name__ == "__main__":
    # بدلاً من mcp.run()
    mcp.run(transport="streamable-http", host="0.0.0.0", port=8080)

أبسط Dockerfile للنشر:

FROM python:3.12-slim

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN pip install uv && uv sync --frozen

COPY server.py .

EXPOSE 8080
CMD ["uv", "run", "server.py"]

الإعداد على Claude/Cursor يصبح:

{
  "mcpServers": {
    "notes": {
      "url": "https://mcp.example.com/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_TOKEN"
      }
    }
  }
}

لا تنشر خادم MCP حقيقي بدون مصادقة. أي خادم HTTP مكشوف بلا توكن = إعطاء العالم كله صلاحية تشغيل أدواتك.

الأمن: أخطاء كلّفت فرقاً حقيقية الكثير

خوادم MCP تعرّض دوال قابلة للتنفيذ لنموذج لغوي. هذا يعني أن أي ثغرة قد تستغل عبر prompt injection. القائمة التي يجب أن تطبّقها قبل النشر:

  • مبدأ الحد الأدنى من الصلاحيات: إذا الأداة تقرأ ملفات، حصرها في مجلد واحد بصراحة. لا تستخدم open(path) بلا تحقق.
  • تحقق صارم من المدخلات: استخدم Pydantic أو type hints صارمة. لا تثق بأن النموذج “لن يرسل مدخلات سيئة”.
  • لا تنفّذ shell commands من مدخل النموذج: subprocess.run(shell=True, args=user_input) = كارثة. إذا لزم، استخدم القائمة المحددة args=["program", arg1, arg2].
  • سجّل كل استدعاء: في الإنتاج، كل استدعاء لأداة يجب أن يُكتب في audit log مع المعرّف، المدخلات، النتيجة، والوقت.
  • حدّد معدّل الاستدعاءات: rate limiting بسيط يمنع نموذجاً مضلَّلاً من إفراغ رصيد API الخاص بك.
  • أوضح للنموذج ما لا يفعله: في وصف الأداة، اكتب صراحة “هذه الأداة لا تنفّذ ملفات تنفيذية مهما طُلِب”.

قرأنا في دليلنا عن أمن وكلاء الذكاء الاصطناعي أمثلة حقيقية لاختراقات عبر prompt injection — نفس المبادئ تنطبق على خوادم MCP.

أفضل ١٠ ممارسات لخوادم MCP في 2026

  1. اسم خادم وصفي: company-crm أفضل من my-server.
  2. وصف أداة من جملة واحدة + مثال استخدام: النموذج يقرّر متى يستدعي الأداة بناءً على هذا.
  3. أنواع مدخلات دقيقة: email: EmailStr أفضل من email: str.
  4. افصل الأدوات القابلة للقراءة (Resources) عن الأدوات المعدّلة (Tools).
  5. اجعل أدواتك إيدمبوتنت idempotent ما أمكن: استدعاؤها مرتين لا يُفسد شيئاً.
  6. أرجع رسائل خطأ بشرية للنموذج بدلاً من stack traces.
  7. اختبر باستخدام unit tests عادية: FastMCP دوالها قابلة للاستدعاء مباشرة.
  8. إصدارات معنوية: غيّر اسم/توقيع الأداة فقط مع version bump واضح.
  9. وثّق في README: متطلبات، متغيرات البيئة، أمثلة استدعاء.
  10. راقب الاستخدام: عدد الاستدعاءات، متوسط زمن الاستجابة، معدل الأخطاء.

الأسئلة الشائعة (FAQ)

هل MCP يعمل مع نماذج غير Claude؟

نعم، بدءاً من 2025 أعلنت OpenAI رسمياً دعم MCP في ChatGPT و Codex، وكذلك Gemini و Microsoft Copilot Studio و Cursor. خادمك المكتوب اليوم يعمل عبر كل هذه المنصات بلا تعديل.

ما الفرق بين MCP وFunction Calling التقليدي؟

Function Calling مرتبط بمزود نموذج معين (OpenAI، Anthropic) وتعيد كتابته في كل تطبيق. MCP بروتوكول مستقل: تكتب خادمك مرة، ويصبح قابلاً للاستخدام عبر أي عميل MCP-compatible. مقالنا عن Function Calling يشرح الفرق بتفصيل أعمق.

هل يمكنني كتابة خادم MCP بلغة غير Python أو Node.js؟

نعم. توجد SDKs رسمية لـ TypeScript، Python، Java، Kotlin، C#، Go، Swift، و Rust. البروتوكول نفسه قائم على JSON-RPC 2.0، فأي لغة قادرة على قراءة/كتابة JSON تستطيع تنفيذ خادم.

كم يستهلك خادم MCP من موارد؟

خادم stdio بسيط يستهلك أقل من 50MB RAM. الحمل الحقيقي يأتي من العمليات داخل أدواتك (استدعاء API، استعلام DB). للإنتاج عبر HTTP، خادم بـ512MB RAM و 1 vCPU يخدم عشرات المستخدمين المتزامنين بسهولة.

كيف أحمي بيانات حساسة في الأدوات؟

لا تمرّر مفاتيح API من النموذج. ضعها في متغيرات بيئة على جهازك أو خادمك، واقرأها داخل دوال الأداة عبر os.environ["API_KEY"]. النموذج يرى المخرجات فقط لا أسرار الاتصال.

هل أحتاج تعلم async/await لأكتب خادم MCP؟

للأمثلة البسيطة لا. FastMCP يقبل دوال عادية ودوال async. لكن أي خادم سيستدعي API خارجي أو DB يجب أن يستخدم async، وإلا ستجمّد كل الطلبات الأخرى. استثمر ساعة في فهم async — ستوفّر عليك أياماً من ديباغ لاحقاً.

هل يمكن لخادم MCP أن “يبدأ محادثة” مع المستخدم؟

لا في النموذج الحالي. الخادم سلبي: ينتظر العميل أن يستدعيه. لكن منذ MCP 2025-spec أُضيفت ميزة Sampling التي تسمح للخادم بطلب توليد من النموذج (مثل: “اطلب من Claude يلخّص هذا”). تستخدمها أدوات الوكيل المعقدة فقط.

الخطوات التالية

الآن وأنت تستطيع بناء خادم MCP من الصفر، إليك ثلاثة اتجاهات للتعمّق:

خلاصة

بناء خادم MCP في 2026 لم يعد مشروع نهاية أسبوع للمتحمسين فقط — أصبح مهارة أساسية لكل من يبني تطبيقات ذكاء اصطناعي عملية. الفرق بين فريق يكتب وكلاء أقوياء وفريق عالق في prompt engineering تقليدي غالباً يأتي من القدرة على بناء خوادم MCP مخصصة لمنطق أعمالهم.

الأمثلة الثلاثة في هذا الدليل (Hello World، Weather، Notes) جاهزة للنسخ والتشغيل. ابدأ بأبسطها، عدّلها لما يهمك فعلاً، ثم انتقل للتعقيد التدريجي. خادمك التالي قد يربط Claude بقاعدة بياناتك، أو بـSlack شركتك، أو بأجهزة IoT منزلك. الحد الأدنى أصبح في يديك.

وإذا أردت متابعة جديد بروتوكول MCP وأدوات الوكلاء، تابع قسم وكلاء الذكاء الاصطناعي في المدونة — ننشر تحديثات أسبوعية على هذا المحور.

Comments

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *