انتقل إلى المحتوى الرئيسي
الهندسةMar 28, 2026

بناء أول خادم MCP: دليل عملي للمطورين

OS
Open Soft Team

Engineering Team

ما هو Model Context Protocol (MCP)؟

Model Context Protocol (MCP) هو معيار مفتوح أنشأته Anthropic يحدد كيفية تواصل تطبيقات AI مع مصادر البيانات والأدوات الخارجية. فكر في MCP كـ USB-C لدمج AI: تمامًا كما يوفر USB-C موصلًا عالميًا واحدًا للشحن ونقل البيانات وإخراج الشاشة، يوفر MCP بروتوكولًا عالميًا واحدًا لربط نماذج AI بقواعد البيانات وواجهات API وأنظمة الملفات وأي خدمة أخرى. يلغي MCP الحاجة إلى عمليات دمج مخصصة بين كل تطبيق AI وكل أداة.

في عام 2026، أصبح MCP المعيار المهيمن لاتصالات AI-الأدوات. تتوقع Gartner أن 40% من تطبيقات المؤسسات ستتضمن وكلاء AI بحلول نهاية 2026، و MCP هو البروتوكول الذي يجعل هذا عمليًا على نطاق واسع. قبل MCP، كان ربط نموذج AI بـ N أداة يتطلب N عملية دمج مخصصة. مع M تطبيق AI و N أداة، كنت بحاجة إلى M x N محول دمج. يختزل MCP هذا إلى M + N: كل تطبيق AI ينفذ MCP client واحد، وكل أداة تنفذ MCP server واحد.

بنية MCP: Host و Client و Server و Transport

فهم بنية MCP ضروري قبل كتابة أي كود. يحدد البروتوكول أربعة أدوار رئيسية:

المكونالدورمثال
Hostتطبيق AI الذي يتفاعل معه المستخدم النهائيClaude Desktop، Cursor، VS Code Copilot
Clientمعالج بروتوكول MCP داخل الـ Hostمدمج في تطبيق الـ Host
Serverيكشف tools و resources و prompts عبر MCPخادمك المخصص (ما سنبنيه)
Transportطبقة الاتصال بين Client و Serverstdio، HTTP+SSE، Streamable HTTP

يعمل تدفق الاتصال كالتالي:

  1. يبدأ Host ويهيئ MCP Client لكل خادم مُعد.
  2. يتصل Client بـ Server عبر Transport (stdio للمحلي، HTTP للبعيد).
  3. يرسل Client طلب initialize، يتفاوض على إصدار البروتوكول والقدرات.
  4. يستجيب Server بـ tools و resources و prompts المتاحة.
  5. عندما يحتاج نموذج AI إلى بيانات أو إجراءات خارجية، يستدعي Client طريقة الخادم المناسبة.
  6. ينفذ Server العملية ويعيد النتائج عبر رسائل JSON-RPC 2.0.

Tools مقابل Resources مقابل Prompts

يمكن لخوادم MCP كشف ثلاثة أنواع من القدرات:

  • Tools هي دوال يمكن لنموذج AI استدعاؤها. تقبل مدخلات منظمة وتعيد مخرجات منظمة. مثال: query_database(sql: string) أو send_email(to: string, subject: string, body: string).
  • Resources هي بيانات يمكن لنموذج AI قراءتها. يتم تحديدها بواسطة URIs وتعيد محتوى. مثال: file:///path/to/document.md أو postgres://localhost/mydb/users.
  • Prompts هي قوالب prompts قابلة لإعادة الاستخدام يوفرها الخادم. تساعد في توحيد طريقة تفاعل AI مع مجال الخادم. مثال: قالب summarize_ticket لخادم Jira MCP.

خطوة بخطوة: بناء خادم MCP في TypeScript

لنبنِ خادم MCP عملي يوفر أداة للاستعلام من قاعدة بيانات SQLite. هذا حالة استخدام شائعة: منح نموذج AI وصولًا آمنًا للقراءة فقط إلى بيانات تطبيقك.

الخطوة 1: تهيئة المشروع

mkdir mcp-sqlite-server && cd mcp-sqlite-server
npm init -y
npm install @modelcontextprotocol/sdk better-sqlite3
npm install -D typescript @types/node @types/better-sqlite3
npx tsc --init

تكوين tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "declaration": true
  },
  "include": ["src/**/*"]
}

الخطوة 2: تنفيذ الخادم

إنشاء src/index.ts:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import Database from "better-sqlite3";
import { z } from "zod";

const db = new Database(process.env.DB_PATH || "./data.db", {
  readonly: true,
});

const server = new McpServer({
  name: "sqlite-query",
  version: "1.0.0",
});

server.tool(
  "query",
  "تنفيذ استعلام SQL للقراءة فقط على قاعدة بيانات SQLite",
  {
    sql: z.string().describe("استعلام SQL SELECT المراد تنفيذه"),
  },
  async ({ sql }) => {
    const normalized = sql.trim().toUpperCase();
    if (!normalized.startsWith("SELECT")) {
      return {
        content: [{ type: "text", text: "خطأ: يُسمح فقط باستعلامات SELECT." }],
        isError: true,
      };
    }
    try {
      const rows = db.prepare(sql).all();
      return {
        content: [{ type: "text", text: JSON.stringify(rows, null, 2) }],
      };
    } catch (error) {
      return {
        content: [{ type: "text", text: `خطأ في الاستعلام: ${(error as Error).message}` }],
        isError: true,
      };
    }
  }
);

server.tool(
  "list_tables",
  "عرض جميع الجداول في قاعدة البيانات مع مخططاتها",
  {},
  async () => {
    const tables = db
      .prepare(
        `SELECT name, sql FROM sqlite_master
         WHERE type='table' AND name NOT LIKE 'sqlite_%'
         ORDER BY name`
      )
      .all();
    return {
      content: [{ type: "text", text: JSON.stringify(tables, null, 2) }],
    };
  }
);

الخطوة 3: البناء والاختبار المحلي

npx tsc
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node dist/index.js

يجب أن ترى استجابة JSON-RPC تحتوي على قدرات الخادم.

الخطوة 4: بناء نفس الخادم بلغة Python

لمطوري Python، إليك التنفيذ المكافئ باستخدام SDK Python الرسمي لـ MCP:

import sqlite3
import json
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("sqlite-query")
DB_PATH = "data.db"

@mcp.tool()
def query(sql: str) -> str:
    """تنفيذ استعلام SQL للقراءة فقط على قاعدة بيانات SQLite."""
    normalized = sql.strip().upper()
    if not normalized.startswith("SELECT"):
        raise ValueError("يُسمح فقط باستعلامات SELECT.")
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    try:
        cursor = conn.execute(sql)
        rows = [dict(row) for row in cursor.fetchall()]
        return json.dumps(rows, indent=2, default=str)
    finally:
        conn.close()

@mcp.tool()
def list_tables() -> str:
    """عرض جميع الجداول في قاعدة البيانات مع مخططاتها."""
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    try:
        cursor = conn.execute(
            "SELECT name, sql FROM sqlite_master "
            "WHERE type='table' AND name NOT LIKE 'sqlite_%'"
        )
        tables = [dict(row) for row in cursor.fetchall()]
        return json.dumps(tables, indent=2)
    finally:
        conn.close()

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

الاتصال بـ Claude Desktop

يدعم Claude Desktop خوادم MCP بشكل أصلي. لربط خادمك، عدّل ملف تكوين Claude Desktop:

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

{
  "mcpServers": {
    "sqlite-query": {
      "command": "node",
      "args": ["/absolute/path/to/dist/index.js"],
      "env": {
        "DB_PATH": "/absolute/path/to/your/data.db"
      }
    }
  }
}

أعد تشغيل Claude Desktop. سترى أيقونة مطرقة في واجهة المحادثة تشير إلى أدوات MCP المتاحة. الآن يمكنك سؤال Claude مثل “ما الجداول الموجودة في قاعدة البيانات؟” أو “أظهر لي أعلى 10 مستخدمين حسب تاريخ التسجيل” وسيستخدم Claude خادم MCP الخاص بك للاستعلام من قاعدة البيانات مباشرة.

الاتصال بـ Cursor

يدعم Cursor أيضًا خوادم MCP. أضف التكوين إلى .cursor/mcp.json في جذر مشروعك:

{
  "mcpServers": {
    "sqlite-query": {
      "command": "node",
      "args": ["./dist/index.js"],
      "env": {
        "DB_PATH": "./data.db"
      }
    }
  }
}

بعد الحفظ، أعد تشغيل Cursor. ستظهر أدوات MCP في لوحة مساعد AI ويمكن استدعاؤها أثناء جلسات إنشاء الكود وتصحيح الأخطاء.

اختبار وتصحيح أخطاء خادم MCP

استخدام MCP Inspector

MCP Inspector هو أداة التصحيح الرسمية. يوفر واجهة ويب للتفاعل مع خادمك:

npx @modelcontextprotocol/inspector node dist/index.js

يفتح هذا واجهة متصفح على http://localhost:5173 حيث يمكنك:

  • عرض جميع tools و resources و prompts المسجلة
  • استدعاء tools بمدخلات مخصصة وفحص الاستجابات
  • مراقبة تدفق رسائل JSON-RPC في الوقت الفعلي
  • اختبار معالجة الأخطاء بإرسال طلبات مشوهة

مشاكل التصحيح الشائعة

المشكلةالسببالحل
الخادم لا يظهر في Claude Desktopمسار التكوين أو خطأ في صيغة JSONتحقق من JSON، تحقق من المسارات المطلقة
خطأ “Tool not found”الأدوات غير مسجلة قبل الاتصالسجل الأدوات قبل استدعاء server.connect()
انتهاء المهلة عند استدعاء الأدواتعملية طويلة بدون تقدمأضف إشعارات التقدم عبر server.sendProgress()
مخرجات stderr تفسد البروتوكولconsole.log يكتب إلى stdout (نقل stdio)استخدم console.error() للتسجيل مع stdio
انقطاع الاتصال بعد الخمولانتهاء مهلة النقلنفذ heartbeat أو استخدم نقل HTTP

أفضل الممارسات للإنتاج

  1. التحقق من المدخلات: تحقق دائمًا من مدخلات الأدوات ونظفها. استخدم مخططات Zod (TypeScript) أو نماذج Pydantic (Python) للتحقق الصارم من الأنواع.

  2. القراءة فقط افتراضيًا: ابدأ بالوصول للقراءة فقط. أضف قدرات الكتابة فقط عند الحاجة الفعلية، واطلب دائمًا التأكيد للعمليات التدميرية.

  3. معالجة الأخطاء: أعد رسائل خطأ منظمة مع isError: true. لا تكشف أبدًا عن تتبعات المكدس الداخلية أو سلاسل اتصال قاعدة البيانات.

  4. التسجيل: سجل جميع استدعاءات الأدوات مع الطابع الزمني والمدخلات ومدة التنفيذ. استخدم stderr للتسجيل (وليس stdout) مع نقل stdio.

  5. تحديد المعدل: نفذ حدود معدل لكل أداة لمنع حلقات AI غير المتحكم فيها من إغراق خدمات الواجهة الخلفية.

  6. المهلة الزمنية: عيّن مهلات تنفيذ على جميع معالجات الأدوات. قد تستدعي نماذج AI أدوات تطلق استعلامات مكلفة — احمِ بنيتك التحتية.

  7. فصل البيئات: استخدم متغيرات البيئة لجميع التكوينات. لا تشفر أبدًا عناوين URL لقواعد البيانات أو مفاتيح API أو مسارات الملفات.

  8. التنسيق: استخدم التنسيق الدلالي لخادم MCP الخاص بك. يتضمن مصافحة initialize تفاوض الإصدار — التغييرات غير المتوافقة تتطلب زيادة في الإصدار الرئيسي.

الأسئلة الشائعة

س: ما الفرق بين MCP و function calling؟ ج: يحدد function calling (المستخدم من OpenAI و Anthropic وغيرهم) الأدوات بشكل مضمن في كل طلب API. يُخرج MCP تعريفات الأدوات إلى خوادم مستقلة يمكن لمضيفات MCP المتوافقة اكتشافها واستخدامها. Function calling يعمل لكل طلب؛ MCP هو بروتوكول دائم مع جلسات ذات حالة.

س: هل يمكنني استخدام MCP مع نماذج غير Claude؟ ج: نعم. MCP هو بروتوكول مفتوح. اعتمدت OpenAI و Google DeepMind و Microsoft دعم MCP في منصاتهم منذ أوائل 2026. أي تطبيق AI ينفذ MCP client يمكنه الاتصال بأي MCP server.

س: هل MCP للأدوات المحلية فقط؟ ج: لا. بينما صُمم نقل stdio للخوادم المحلية، يدعم نقل HTTP+SSE و Streamable HTTP خوادم MCP البعيدة. يمكنك نشر خادم MCP كخدمة سحابية يمكن الوصول إليها عبر الشبكة.

س: كيف يتعامل MCP مع المصادقة؟ ج: يدعم البروتوكول OAuth 2.0 للخوادم البعيدة. ترث خوادم stdio المحلية سياق أمان عملية المضيف. لعمليات النشر المؤسسية، يمكن لبوابة MCP مركزة المصادقة والتفويض.

س: ما اللغات التي يمكن استخدامها لبناء خادم MCP؟ ج: تتوفر SDKs الرسمية لـ TypeScript و Python و Java و Kotlin و C# و Swift. تشمل SDKs المجتمع Rust و Go و Ruby و PHP. البروتوكول لا يعتمد على لغة معينة — أي لغة يمكنها قراءة/كتابة JSON-RPC عبر stdio أو HTTP يمكنها تنفيذ خادم MCP.

س: كيف تحدث خادم MCP دون إعادة تشغيل المضيف؟ ج: يدعم MCP إشعارات تغيير القدرات. عندما تتغير أدوات خادمك، يمكن للخادم إرسال رسالة notifications/tools/list_changed، مما يدفع client لإعادة جلب قائمة الأدوات. لخوادم stdio، عادة ما يحتاج المضيف لإعادة التشغيل. يمكن تحديث خوادم HTTP دون إعادة تشغيل المضيف.

الوسوم