بناء خادم MCP الأول لكم
استخدموا Python MCP SDK لإنشاء خادم يوفّر الموارد والأدوات والمطالبات، ثم صلوه بـ Claude Desktop لرؤية عمله من البداية إلى النهاية.
بناء خادم MCP الأول لكم درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
إعداد مشروع خادم MCP
يتطلب بناء خادم MCP باستخدام Python حزمة SDK المسماة mcp وبيئة Python. ستنشئون خادمًا يمكن لـ Claude Desktop أو لأي عميل MCP الاتصال به عبر stdio. ابدؤوا بتثبيت الحزمة وإنشاء ملف الخادم.
# Create a project directory
# mkdir my_mcp_server && cd my_mcp_server
# Create a virtual environment
# python -m venv venv && source venv/bin/activate
# Install the MCP SDK
# pip install mcp httpx
# Project structure:
# my_mcp_server/
# server.py <- Your MCP server
# requirements.txt
# README.mdإنشاء كائن الخادم
استوردوا من الحزمة mcp وأنشئوا مثيلًا من Server باستخدام اسم الخادم. يظهر الاسم للعملاء في قائمة خوادم MCP الخاصة بهم، لذا اختاروا اسمًا وصفيًا. ويُعدّ كائن الخادم نقطة الدخول لتسجيل جميع الأدوات والموارد والموجهات الخاصة بكم.
# server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import asyncio
import httpx
# Create the server — name is shown in Claude Desktop
app = Server('weather-server')
# --- Tool registrations go here ---
# Entry point
if __name__ == '__main__':
asyncio.run(stdio_server(app))تسجيل الأدوات باستخدام @app.list_tools()
يسجّل decorator @app.list_tools() معالجًا يعيد قائمة الأدوات المتاحة عندما يطلبها العميل. وتُعرَّف كل أداة باسم ووصف وinputSchema، وهو JSON Schema الذي يصف معاملاتها. ويرسل العميل هذه القائمة إلى LLM كي يعرف الأدوات التي يمكنه استدعاؤها.
@app.list_tools()
async def list_tools() -> list[types.Tool]:
return [
types.Tool(
name='get_weather',
description='Get current weather for a city. Use when the user asks about weather in a specific location.',
inputSchema={
'type': 'object',
'properties': {
'city': {
'type': 'string',
'description': 'City name, e.g. London or New York'
},
'units': {
'type': 'string',
'enum': ['metric', 'imperial'],
'description': 'Temperature units. Default is metric.'
}
},
'required': ['city']
}
),
types.Tool(
name='list_cities',
description='Return a list of major cities the user can query weather for.',
inputSchema={'type': 'object', 'properties': {}, 'required': []}
)
]تنفيذ الأدوات
يتولى المُزيِّن @app.call_tool() تنفيذ الأدوات. عندما يستدعي العميل أداةً، يتلقى هذا المعالج اسم الأداة ومعاملاتها. نفِّذ المنطق المناسب وأعِد قائمةً من كائنات TextContent التي تحتوي على سلسلة النتيجة.
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[types.TextContent]:
if name == 'list_cities':
cities = ['London', 'New York', 'Tokyo', 'Paris', 'Sydney']
return [types.TextContent(type='text', text=', '.join(cities))]
if name == 'get_weather':
city = arguments['city']
units = arguments.get('units', 'metric')
unit_symbol = 'C' if units == 'metric' else 'F'
# Call real weather API (stub here)
async with httpx.AsyncClient() as client:
# Replace with actual API call
result = f'{city}: 18{chr(176)}{unit_symbol}, partly cloudy, humidity 65%'
return [types.TextContent(type='text', text=result)]
raise ValueError(f'Unknown tool: {name}')إتاحة الموارد
الموارد هي بيانات ثابتة أو ديناميكية يمكن للنموذج قراءتها؛ فكِّر فيها على أنها ملفات. حدِّد عناوين URI للموارد ونفِّذ قارئًا للموارد. تظهر الموارد في العميل كعناصر يمكن للذكاء الاصطناعي الرجوع إليها، وهي مفيدة للإعدادات والوثائق أو لقطات البيانات التي يُكثر الوصول إليها.
@app.list_resources()
async def list_resources() -> list[types.Resource]:
return [
types.Resource(
uri='weather://supported-cities',
name='Supported Cities List',
description='Complete list of cities available in this weather server.',
mimeType='text/plain'
)
]
@app.read_resource()
async def read_resource(uri: str) -> str:
if uri == 'weather://supported-cities':
cities = ['London', 'New York', 'Tokyo', 'Paris', 'Sydney', 'Dubai', 'Singapore']
return '\n'.join(cities)
raise ValueError(f'Unknown resource URI: {uri}')تسجيل قوالب المطالبات
المطالبات هي قوالب رسائل قابلة لإعادة الاستخدام يعرضها العملاء على المستخدمين كأوامر تبدأ بشرطة مائلة أو كإجراءات سريعة. وهي تقبل معاملات وتعيد قائمةً من الرسائل التي تصبح السياق الأولي للمحادثة. وتُعد المطالبات مناسبةً لترميز التعليمات المعقدة التي يفعّلها المستخدمون بأمر واحد.
@app.list_prompts()
async def list_prompts() -> list[types.Prompt]:
return [
types.Prompt(
name='weather-report',
description='Generate a formatted weather report for a city.',
arguments=[
types.PromptArgument(name='city', description='City name', required=True)
]
)
]
@app.get_prompt()
async def get_prompt(name: str, arguments: dict) -> types.GetPromptResult:
if name == 'weather-report':
city = arguments.get('city', 'London')
return types.GetPromptResult(
description=f'Weather report for {city}',
messages=[
types.PromptMessage(
role='user',
content=types.TextContent(
type='text',
text=f'Use the get_weather tool to look up {city} and give me a detailed weather report including what clothing I should wear.'
)
)
]
)
raise ValueError(f'Unknown prompt: {name}')الاتصال بـ Claude Desktop
لاستخدام خادم MCP الخاص بكم مع Claude Desktop، أضيفوه إلى ملف إعداد Claude Desktop. في macOS، يوجد هذا الملف في ~/Library/Application Support/Claude/claude_desktop_config.json. حدِّدوا الأمر الذي يبدأ تشغيل الخادم وأي متغيرات بيئية يحتاج إليها.
# ~/Library/Application Support/Claude/claude_desktop_config.json
# Add this JSON configuration:
# {
# "mcpServers": {
# "weather-server": {
# "command": "/path/to/venv/bin/python",
# "args": ["/path/to/my_mcp_server/server.py"],
# "env": {
# "WEATHER_API_KEY": "your_api_key_here"
# }
# }
# }
# }
# After saving, restart Claude Desktop.
# Your server's tools will appear in Claude's tool list.اختبار خادمكم باستخدام MCP CLI
قبل الاتصال بـ Claude Desktop، اختبروا خادمكم باستخدام أدوات فحص MCP أو أدوات CLI. يبدأ الأمر mcp dev تشغيل خادمكم ويفتح أداة فحص في المتصفح، حيث يمكنكم استدعاء الأدوات يدويًا ومشاهدة رسائل البروتوكول الأولية، مما يسهّل تصحيح المشكلات.
# Install the MCP development tools
# pip install 'mcp[cli]'
# Start the inspector with your server
# mcp dev server.py
# The inspector opens at http://localhost:5173
# You can:
# - See all registered tools and their schemas
# - Call tools with custom arguments
# - Browse available resources
# - Test prompt templates
# - View the full JSON-RPC message exchangeمعالجة الأخطاء في خوادم MCP
يجب ألا تتعطل خوادم MCP أبدًا بسبب إدخال غير صالح. ضعوا كل عمليات تنفيذ الأدوات داخل try/except وأعيدوا رسائل الخطأ ككائنات TextContent بدلًا من رفع الاستثناءات. بالنسبة إلى الأخطاء الفادحة، مثل مشكلات الإعداد أو مفاتيح API المفقودة، سجّلوها عند بدء التشغيل وارفعوها قبل دخول الخادم في حلقته الرئيسية.
@app.call_tool()
async def call_tool_safe(name: str, arguments: dict) -> list[types.TextContent]:
try:
if name == 'get_weather':
city = arguments.get('city')
if not city:
return [types.TextContent(type='text', text='Error: city argument is required.')]
result = await fetch_weather(city, arguments.get('units', 'metric'))
return [types.TextContent(type='text', text=result)]
raise ValueError(f'Unknown tool: {name}')
except httpx.TimeoutException:
return [types.TextContent(type='text', text='Error: Weather API timed out. Try again.')]
except Exception as e:
return [types.TextContent(type='text', text=f'Error: {str(e)}')]تسجيل الأحداث لخوادم MCP
بما أن خوادم MCP تتواصل مع العميل عبر stdio، فإن عبارات الطباعة ستُفسد البروتوكول. استخدموا دائمًا stderr لتسجيل الأحداث؛ فهو يرسلها إلى تدفق منفصل لا يتداخل مع تبادل رسائل MCP. اضبطوا وحدة logging في Python للكتابة إلى stderr.
import logging
import sys
# Configure logging to stderr (NOT stdout — that's the MCP channel)
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
stream=sys.stderr
)
logger = logging.getLogger('weather-server')
# In your tool handler:
# logger.info(f'Getting weather for {city}')
# logger.error(f'API call failed: {e}')
# Claude Desktop captures stderr to a log file:
# ~/Library/Logs/Claude/mcp-server-weather-server.logتعبئة خادم MCP الخاص بكم
شاركوا خادم MCP الخاص بكم عبر تعبئته باستخدام pyproject.toml ونشره على PyPI، أو وزّعوه كحاوية Docker للفرق. استخدموا المتغيرات البيئية لجميع الأسرار، مثل مفاتيح API وعناوين URL لقواعد البيانات، حتى يظل إعداد الخادم منفصلًا عن الشيفرة. وثّقوا متغيرات البيئة المطلوبة ومثال الإعداد في ملف README واضح.
تحقق سريع
اختبروا مدى فهمكم لبناء خادم MCP باستخدام Python.
مراجعة الدرس
تعلّمتم في هذا الدرس أن: خوادم MCP تتيح الأدوات عبر المُزيِّنين @app.list_tools() و@app.call_tool()، وأن الموارد والمطالبات توسّع الخادم ببيانات قابلة للقراءة وقوالب قابلة لإعادة الاستخدام، وأن تسجيل الأحداث يجب أن يستخدم stderr لتجنب إفساد قناة بروتوكول MCP عبر stdio. في الخطوة التالية، سنصل خادم MCP بقاعدة بيانات ونتيح موارد ديناميكية مع ترقيم الصفحات.
تعلم Python مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 30
- الدروس
- 120
الأسئلة الشائعة
هل درس «بناء خادم MCP الأول لكم» مجاني؟
نعم — نص درس «بناء خادم MCP الأول لكم» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
ماذا ستتعلم في «بناء خادم MCP الأول لكم»؟
استخدموا Python MCP SDK لإنشاء خادم يوفّر الموارد والأدوات والمطالبات، ثم صلوه بـ Claude Desktop لرؤية عمله من البداية إلى النهاية. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟
لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «بناء خادم MCP الأول لكم»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟
نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- ما هو MCP ولماذا يهم
- بناء خادم MCP الأول لكم
- إتاحة موارد قواعد البيانات عبر MCP
- أمان MCP والمصادقة