كيفية بناء خادم MCP بلغة Python خطوة بخطوة
كيفية بناء خادم MCP؟ نكتب أدواتنا بلغة Python باستخدام SDK 2.0، ونختبرها في MCP Inspector، ثم نربطها بـ Claude Code وClaude Desktop خطوة بخطوة.
هذا المقال بلغات أخرى:DeutschEnglishEspañolFrançaisItaliano日本語Polski简体中文
في هذا المقال
- ما الذي سنحتاج إليه؟
- الخطوة 1: كيف نجهّز المشروع؟
- الخطوة 2: كيفية بناء خادم MCP مع أول أداة
- الخطوة 3: لماذا لا يجوز استخدام print()؟
- الخطوة 4: كيف نختبر الخادم في MCP Inspector؟
- الخطوة 5: كيف نربط الخادم بـ Claude Code؟
- الخطوة 6: كيف نضيف الخادم إلى Claude Desktop؟
- الخطوة 7: كيف نشغّل خادم MCP عبر HTTP؟
- ما الذي يجب الانتباه إليه؟
- FAQ
كيفية بناء خادم MCP؟ في Python يكفي ملف واحد مع MCP Python SDK الرسمية: نكتب دالة عادية بأنواع بيانات و docstring، نضيف المزخرف @mcp.tool()، فتحوّلها SDK إلى أداة يستطيع Claude أو ChatGPT أو Cursor استدعاءها. والخادم الكامل في مثال التوثيق لا يتجاوز بضعة عشر سطرًا.
في هذا الشرح نكتب خادمًا من الصفر، ونختبره في MCP Inspector، ثم نربطه بـ Claude Code وClaude Desktop. الأوامر والشيفرة مأخوذة من الشرح الرسمي “Build an MCP server” ومن README الخاص بـ SDK ومن توثيق Claude Code.
ما الذي سنحتاج إليه؟
أفترض أننا نعرف ما هو MCP، أي المضيف والعميل والخادم والأدوات (وإن لم نكن نعرف، فلنبدأ من شرح ما هو MCP). وللعمل نحتاج إلى:
- Python 3.11 أو أحدث (هذا ما يشترطه README في SDK الحالية)،
- مدير الحزم uv الذي يعتمده الشرح الرسمي،
- Node.js 22.19.0 أو أحدث إذا أردنا اختبار الخادم في MCP Inspector،
- مضيف MCP لتجربة كل شيء، مثل Claude Code أو Claude Desktop.
ملاحظة مهمة قبل البدء: في الإصدار 2.0 من SDK تغيّر اسم الصنف الرئيسي. بحسب وصف تغييرات v2، ما كان يُكتب from mcp.server.fastmcp import FastMCP صار الآن from mcp.server import MCPServer. كثير من الشروحات على الإنترنت ما زال يعرض النسخة القديمة، والشرح الرسمي يشترط SDK 2.0.0 أو أحدث.
الخطوة 1: كيف نجهّز المشروع؟
نثبّت uv أولًا (macOS وLinux):
curl -LsSf https://astral.sh/uv/install.sh | sh
وعلى Windows في PowerShell:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
بعد التثبيت نعيد تشغيل الطرفية حتى يصبح الأمر uv متاحًا. ثم ننشئ المشروع ونثبّت SDK:
uv init my-server
cd my-server
uv venv
source .venv/bin/activate
uv add "mcp[cli]"
touch server.py
الإضافة [cli] تثبّت الأمر mcp (ومعه mcp dev وmcp run وmcp install)، وسنحتاج إليه في الاختبار (على Windows نفعّل البيئة عبر .venv\Scripts\activate).
الخطوة 2: كيفية بناء خادم MCP مع أول أداة
نكتب في الملف server.py المثال الوارد في README الخاص بـ SDK، ونضيف في آخره تشغيل الخادم كما في الشرح الرسمي:
from mcp.server import MCPServer
mcp = MCPServer("Demo")
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers."""
return a + b
@mcp.resource("greeting://{name}")
def greeting(name: str) -> str:
"""Greet someone by name."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run(transport="stdio")
هذا خادم MCP كامل: أداة واحدة (add) ومورد واحد بقالب عنوان (greeting://{name}). واللافت أننا لا نكتب أي JSON Schema: بحسب README، التوقيع a: int, b: int هو المخطط نفسه، و docstring تصبح وصف الأداة الذي يقرؤه النموذج. أما تحليل الطلبات والتحقق منها والبروتوكول فتتولاها SDK.
لذلك تستحق الـ docstring عناية. النموذج يختار الأداة بناءً على اسمها ووصفها، فعبارة “Add two numbers.” هي الحد الأدنى، وفي الأدوات الحقيقية نصف الوسائط أيضًا، كما في مثال الطقس الرسمي:
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get weather forecast for a location.
Args:
latitude: Latitude of the location
longitude: Longitude of the location
"""
(هذا المثال يعتمد على API هيئة الأرصاد الأمريكية NWS، لذا يعمل فقط مع مواقع داخل الولايات المتحدة)
الخطوة 3: لماذا لا يجوز استخدام print()؟
هذا أكثر الأخطاء شيوعًا في أول خادم. الخادم المحلي يتواصل مع المضيف عبر الإدخال والإخراج القياسيين (stdio)، والرسائل بصيغة JSON-RPC. والتوثيق يحذّر صراحة: الكتابة إلى stdout تفسد رسائل JSON-RPC وتعطّل الخادم، وprint() تكتب افتراضيًا إلى stdout بالذات.
نستخدم بدلًا منها الوحدة logging التي تكتب إلى stderr:
import logging
logger = logging.getLogger(__name__)
logger.info("Processing request") # يذهب إلى stderr
مع خوادم HTTP لا تظهر هذه المشكلة، لأن السجلات المكتوبة إلى stdout لا تختلط باستجابات HTTP.
الخطوة 4: كيف نختبر الخادم في MCP Inspector؟
MCP Inspector هي الأداة الرسمية لاختبار الخوادم. ومن SDK نشغّلها بأمر واحد:
uv run mcp dev server.py
يفتح المتصفح على Inspector. وبحسب README، استدعاء add بالوسيطين a=1 وb=2 يعيد 3. وفي المكان نفسه نرى قائمة الأدوات والموارد ورسائل JSON-RPC الخام، وهذا يساعد كثيرًا حين يتعطل شيء.
لدى Inspector أيضًا نسخة تعمل في الطرفية (--tui) ووضع للسكربتات (--cli). الوضع الثاني يطبع مثلًا قائمة الأدوات ثم ينهي عمله، فيصلح للاستخدام في CI:
npx @modelcontextprotocol/inspector --cli uv run server.py --method tools/list
(تحقق من إصدار Node.js بالأمر node --version، فـ Inspector يتطلب 22.19.0 أو أحدث)
الخطوة 5: كيف نربط الخادم بـ Claude Code؟
نضيف الخادم المحلي كخادم من نوع stdio. وكل ما يأتي بعد -- هو الأمر الذي سيشغّله Claude Code:
claude mcp add --transport stdio demo -- uv --directory /FULL/PATH/my-server run server.py
يجب أن يكون المسار مطلقًا (نعرفه بالأمر pwd داخل مجلد المشروع). حالة الاتصال يعرضها claude mcp get demo، وداخل جلسة Claude Code الأمر /mcp. والآن يمكننا أن نطلب مثلًا: “اجمع 1234 و5678 بالأداة add” ثم نوافق على الاستدعاء.
وفي توثيق Claude Code أمران يفيداننا من البداية:
- مهلة إقلاع الخادم نغيّرها بالمتغير
MCP_TIMEOUT، فمثلًاMCP_TIMEOUT=10000 claudeيمنح الخادم 10 ثوانٍ، - Claude Code يحذّر حين تتجاوز نتيجة الأداة 10 000 توكن، ويقتطعها افتراضيًا عند 25 000 توكن (يغيّر هذا الحدَّ المتغير
MAX_MCP_OUTPUT_TOKENS)، لذا لا ينبغي للأدوات أن تعيد قواعد بيانات كاملة.
الخطوة 6: كيف نضيف الخادم إلى Claude Desktop؟
في Claude Desktop نضيف الخوادم المحلية إلى ملف الإعدادات claude_desktop_config.json. يوجد الملف في ~/Library/Application Support/Claude/ على macOS، وفي ~/.config/Claude/ على Linux، وفي %AppData%\Claude\ على Windows (وإن لم يكن موجودًا ننشئه). والمدخل يبدو هكذا:
{
"mcpServers": {
"demo": {
"command": "uv",
"args": [
"--directory",
"/FULL/PATH/my-server",
"run",
"server.py"
]
}
}
}
بعدها نغلق التطبيق إغلاقًا تامًا (على macOS عبر Cmd+Q، فإغلاق النافذة وحده لا يكفي) ثم نشغّله من جديد. يُفترض أن يظهر الخادم في قائمة “Connectors” تحت أيقونة علامة الزائد. وإن لم يظهر، ينصح التوثيق بالتحقق من صياغة JSON ومن أن المسار مطلق، وبكتابة المسار الكامل إلى uv في الحقل command (يعرضه الأمر which uv). أما السجلات فنجدها في ~/Library/Logs/Claude (macOS) أو ~/.config/Claude/logs/ (Linux)، في الملفين mcp.log وmcp-server-NAME.log.
الخطوة 7: كيف نشغّل خادم MCP عبر HTTP؟
خادم stdio يعمل على جهازنا فقط. ولكي نتيحه كخادم بعيد نشغّله عبر Streamable HTTP، وهو بحسب README الخاص بـ SDK النقل المستخدم في بيئات الإنتاج:
uv run mcp run server.py --transport streamable-http
عندها يستمع الخادم على العنوان http://localhost:8000/mcp، ونضيفه في Claude Code كأي خادم بعيد:
claude mcp add --transport http demo-http http://localhost:8000/mcp
ولكي يعمل خادم كهذا في تطبيق Claude على المتصفح كـ“custom connector”، يجب أن يكون متاحًا من الإنترنت، لأن Claude يتصل به من سحابة Anthropic. وهنا يلزم تسجيل الدخول أيضًا: توثيق MCP يشرح تفويض الخوادم عبر OAuth 2.1.
ما الذي يجب الانتباه إليه؟
أولًا، ما تسمح به الأداة. خادم MCP يمنح النموذج قدرة حقيقية على التصرف في جهازنا، فلنكتب الأدوات بأضيق نطاق ممكن: “اقرأ ملفًا من هذا المجلد” أفضل من “شغّل أي أمر”.
ثانيًا، البيانات القادمة من الخارج. إذا كانت الأداة تجلب محتوى من الإنترنت أو من البريد الإلكتروني، فقد تحمل معها prompt injection، أي تعليمات مخفية موجّهة إلى النموذج. كتبت عن ذلك بتفصيل أكبر في شرح أمان وكلاء الذكاء الاصطناعي.
ثالثًا، الأسرار. لنمرّر مفاتيح API عبر متغيرات البيئة (--env في Claude Code) لا داخل الشيفرة. وبحسب التوثيق، يحفظ Inspector الرموز في سلسلة مفاتيح النظام، وإن لم تكن موجودة (داخل حاوية مثلًا) فيحفظها في ملف غير مشفّر هو ~/.mcp-inspector/secrets.json.
ويمكننا بعد ذلك ربط هذا الخادم بوكيل نبنيه بأنفسنا، وهذا ما أعرضه في شرح كيفية بناء وكيل ذكاء اصطناعي بلغة Python.
FAQ
ما أبسط طريقة لبناء خادم MCP؟
أبسط خادم في README الخاص بـ SDK لا يتجاوز بضعة عشر سطرًا: كائن MCPServer، ودالة واحدة بالمزخرف @mcp.tool()، ثم mcp.run(). والباقي، أي مخطط الوسائط ومعالجة البروتوكول، تتولاه SDK.
ما هو FastMCP؟
هو الاسم القديم لصنف الخادم الرئيسي في MCP Python SDK. في الإصدار 2.0 صار اسمه MCPServer، والاستيراد هو from mcp.server import MCPServer.
هل يمكن كتابة خادم MCP بلغة أخرى غير Python؟
نعم. للشرح الرسمي نسخ بلغات منها TypeScript وJava وKotlin وC# وRuby وRust وGo.
هل يعمل خادم MCP مع Claude فقط؟
لا. MCP معيار مفتوح، لذا يعمل الخادم نفسه في أي مضيف يدعم البروتوكول، مثل ChatGPT أو Visual Studio Code أو Cursor.