[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-binaa-awwal-khadim-mcp-dalil-amali-lilmutawwirin":3},{"article":4,"author":50},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":30,"related_articles":31},"d0000000-0000-0000-0000-000000000522","a0000000-0000-0000-0000-000000000096","بناء أول خادم MCP: دليل عملي للمطورين","binaa-awwal-khadim-mcp-dalil-amali-lilmutawwirin","دليل تعليمي عملي خطوة بخطوة لبناء خادم Model Context Protocol (MCP) بلغتي TypeScript و Python، وربطه بـ Claude Desktop أو Cursor، ونشره في بيئة الإنتاج.","## ما هو Model Context Protocol (MCP)؟\n\n**Model Context Protocol (MCP)** هو معيار مفتوح أنشأته Anthropic يحدد كيفية تواصل تطبيقات AI مع مصادر البيانات والأدوات الخارجية. فكر في MCP كـ **USB-C لدمج AI**: تمامًا كما يوفر USB-C موصلًا عالميًا واحدًا للشحن ونقل البيانات وإخراج الشاشة، يوفر MCP بروتوكولًا عالميًا واحدًا لربط نماذج AI بقواعد البيانات وواجهات API وأنظمة الملفات وأي خدمة أخرى. يلغي MCP الحاجة إلى عمليات دمج مخصصة بين كل تطبيق AI وكل أداة.\n\nفي عام 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 واحد.\n\n## بنية MCP: Host و Client و Server و Transport\n\nفهم بنية MCP ضروري قبل كتابة أي كود. يحدد البروتوكول أربعة أدوار رئيسية:\n\n| المكون | الدور | مثال |\n|--------|-------|------|\n| **Host** | تطبيق AI الذي يتفاعل معه المستخدم النهائي | Claude Desktop، Cursor، VS Code Copilot |\n| **Client** | معالج بروتوكول MCP داخل الـ Host | مدمج في تطبيق الـ Host |\n| **Server** | يكشف tools و resources و prompts عبر MCP | خادمك المخصص (ما سنبنيه) |\n| **Transport** | طبقة الاتصال بين Client و Server | stdio، HTTP+SSE، Streamable HTTP |\n\nيعمل تدفق الاتصال كالتالي:\n\n1. يبدأ **Host** ويهيئ MCP **Client** لكل خادم مُعد.\n2. يتصل **Client** بـ **Server** عبر **Transport** (stdio للمحلي، HTTP للبعيد).\n3. يرسل **Client** طلب `initialize`، يتفاوض على إصدار البروتوكول والقدرات.\n4. يستجيب **Server** بـ **tools** و **resources** و **prompts** المتاحة.\n5. عندما يحتاج نموذج AI إلى بيانات أو إجراءات خارجية، يستدعي **Client** طريقة الخادم المناسبة.\n6. ينفذ **Server** العملية ويعيد النتائج عبر رسائل JSON-RPC 2.0.\n\n### Tools مقابل Resources مقابل Prompts\n\nيمكن لخوادم MCP كشف ثلاثة أنواع من القدرات:\n\n- **Tools** هي دوال يمكن لنموذج AI استدعاؤها. تقبل مدخلات منظمة وتعيد مخرجات منظمة. مثال: `query_database(sql: string)` أو `send_email(to: string, subject: string, body: string)`.\n- **Resources** هي بيانات يمكن لنموذج AI قراءتها. يتم تحديدها بواسطة URIs وتعيد محتوى. مثال: `file:\u002F\u002F\u002Fpath\u002Fto\u002Fdocument.md` أو `postgres:\u002F\u002Flocalhost\u002Fmydb\u002Fusers`.\n- **Prompts** هي قوالب prompts قابلة لإعادة الاستخدام يوفرها الخادم. تساعد في توحيد طريقة تفاعل AI مع مجال الخادم. مثال: قالب `summarize_ticket` لخادم Jira MCP.\n\n## خطوة بخطوة: بناء خادم MCP في TypeScript\n\nلنبنِ خادم MCP عملي يوفر أداة للاستعلام من قاعدة بيانات SQLite. هذا حالة استخدام شائعة: منح نموذج AI وصولًا آمنًا للقراءة فقط إلى بيانات تطبيقك.\n\n### الخطوة 1: تهيئة المشروع\n\n```bash\nmkdir mcp-sqlite-server && cd mcp-sqlite-server\nnpm init -y\nnpm install @modelcontextprotocol\u002Fsdk better-sqlite3\nnpm install -D typescript @types\u002Fnode @types\u002Fbetter-sqlite3\nnpx tsc --init\n```\n\nتكوين `tsconfig.json`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"outDir\": \".\u002Fdist\",\n    \"rootDir\": \".\u002Fsrc\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"declaration\": true\n  },\n  \"include\": [\"src\u002F**\u002F*\"]\n}\n```\n\n### الخطوة 2: تنفيذ الخادم\n\nإنشاء `src\u002Findex.ts`:\n\n```typescript\nimport { McpServer } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\";\nimport Database from \"better-sqlite3\";\nimport { z } from \"zod\";\n\nconst db = new Database(process.env.DB_PATH || \".\u002Fdata.db\", {\n  readonly: true,\n});\n\nconst server = new McpServer({\n  name: \"sqlite-query\",\n  version: \"1.0.0\",\n});\n\nserver.tool(\n  \"query\",\n  \"تنفيذ استعلام SQL للقراءة فقط على قاعدة بيانات SQLite\",\n  {\n    sql: z.string().describe(\"استعلام SQL SELECT المراد تنفيذه\"),\n  },\n  async ({ sql }) => {\n    const normalized = sql.trim().toUpperCase();\n    if (!normalized.startsWith(\"SELECT\")) {\n      return {\n        content: [{ type: \"text\", text: \"خطأ: يُسمح فقط باستعلامات SELECT.\" }],\n        isError: true,\n      };\n    }\n    try {\n      const rows = db.prepare(sql).all();\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(rows, null, 2) }],\n      };\n    } catch (error) {\n      return {\n        content: [{ type: \"text\", text: `خطأ في الاستعلام: ${(error as Error).message}` }],\n        isError: true,\n      };\n    }\n  }\n);\n\nserver.tool(\n  \"list_tables\",\n  \"عرض جميع الجداول في قاعدة البيانات مع مخططاتها\",\n  {},\n  async () => {\n    const tables = db\n      .prepare(\n        `SELECT name, sql FROM sqlite_master\n         WHERE type='table' AND name NOT LIKE 'sqlite_%'\n         ORDER BY name`\n      )\n      .all();\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(tables, null, 2) }],\n    };\n  }\n);\n```\n\n### الخطوة 3: البناء والاختبار المحلي\n\n```bash\nnpx tsc\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-03-26\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' | node dist\u002Findex.js\n```\n\nيجب أن ترى استجابة JSON-RPC تحتوي على قدرات الخادم.\n\n### الخطوة 4: بناء نفس الخادم بلغة Python\n\nلمطوري Python، إليك التنفيذ المكافئ باستخدام SDK Python الرسمي لـ MCP:\n\n```python\nimport sqlite3\nimport json\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"sqlite-query\")\nDB_PATH = \"data.db\"\n\n@mcp.tool()\ndef query(sql: str) -> str:\n    \"\"\"تنفيذ استعلام SQL للقراءة فقط على قاعدة بيانات SQLite.\"\"\"\n    normalized = sql.strip().upper()\n    if not normalized.startswith(\"SELECT\"):\n        raise ValueError(\"يُسمح فقط باستعلامات SELECT.\")\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(sql)\n        rows = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(rows, indent=2, default=str)\n    finally:\n        conn.close()\n\n@mcp.tool()\ndef list_tables() -> str:\n    \"\"\"عرض جميع الجداول في قاعدة البيانات مع مخططاتها.\"\"\"\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(\n            \"SELECT name, sql FROM sqlite_master \"\n            \"WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n        )\n        tables = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(tables, indent=2)\n    finally:\n        conn.close()\n\nif __name__ == \"__main__\":\n    mcp.run(transport=\"stdio\")\n```\n\n## الاتصال بـ Claude Desktop\n\nيدعم Claude Desktop خوادم MCP بشكل أصلي. لربط خادمك، عدّل ملف تكوين Claude Desktop:\n\n**macOS:** `~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.json`\n**Windows:** `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \"\u002Fabsolute\u002Fpath\u002Fto\u002Fyour\u002Fdata.db\"\n      }\n    }\n  }\n}\n```\n\nأعد تشغيل Claude Desktop. سترى أيقونة مطرقة في واجهة المحادثة تشير إلى أدوات MCP المتاحة. الآن يمكنك سؤال Claude مثل \"ما الجداول الموجودة في قاعدة البيانات؟\" أو \"أظهر لي أعلى 10 مستخدمين حسب تاريخ التسجيل\" وسيستخدم Claude خادم MCP الخاص بك للاستعلام من قاعدة البيانات مباشرة.\n\n## الاتصال بـ Cursor\n\nيدعم Cursor أيضًا خوادم MCP. أضف التكوين إلى `.cursor\u002Fmcp.json` في جذر مشروعك:\n\n```json\n{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\".\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \".\u002Fdata.db\"\n      }\n    }\n  }\n}\n```\n\nبعد الحفظ، أعد تشغيل Cursor. ستظهر أدوات MCP في لوحة مساعد AI ويمكن استدعاؤها أثناء جلسات إنشاء الكود وتصحيح الأخطاء.\n\n## اختبار وتصحيح أخطاء خادم MCP\n\n### استخدام MCP Inspector\n\nMCP Inspector هو أداة التصحيح الرسمية. يوفر واجهة ويب للتفاعل مع خادمك:\n\n```bash\nnpx @modelcontextprotocol\u002Finspector node dist\u002Findex.js\n```\n\nيفتح هذا واجهة متصفح على `http:\u002F\u002Flocalhost:5173` حيث يمكنك:\n\n- عرض جميع tools و resources و prompts المسجلة\n- استدعاء tools بمدخلات مخصصة وفحص الاستجابات\n- مراقبة تدفق رسائل JSON-RPC في الوقت الفعلي\n- اختبار معالجة الأخطاء بإرسال طلبات مشوهة\n\n### مشاكل التصحيح الشائعة\n\n| المشكلة | السبب | الحل |\n|---------|-------|------|\n| الخادم لا يظهر في Claude Desktop | مسار التكوين أو خطأ في صيغة JSON | تحقق من JSON، تحقق من المسارات المطلقة |\n| خطأ \"Tool not found\" | الأدوات غير مسجلة قبل الاتصال | سجل الأدوات قبل استدعاء `server.connect()` |\n| انتهاء المهلة عند استدعاء الأدوات | عملية طويلة بدون تقدم | أضف إشعارات التقدم عبر `server.sendProgress()` |\n| مخرجات stderr تفسد البروتوكول | console.log يكتب إلى stdout (نقل stdio) | استخدم `console.error()` للتسجيل مع stdio |\n| انقطاع الاتصال بعد الخمول | انتهاء مهلة النقل | نفذ heartbeat أو استخدم نقل HTTP |\n\n## أفضل الممارسات للإنتاج\n\n1. **التحقق من المدخلات**: تحقق دائمًا من مدخلات الأدوات ونظفها. استخدم مخططات Zod (TypeScript) أو نماذج Pydantic (Python) للتحقق الصارم من الأنواع.\n\n2. **القراءة فقط افتراضيًا**: ابدأ بالوصول للقراءة فقط. أضف قدرات الكتابة فقط عند الحاجة الفعلية، واطلب دائمًا التأكيد للعمليات التدميرية.\n\n3. **معالجة الأخطاء**: أعد رسائل خطأ منظمة مع `isError: true`. لا تكشف أبدًا عن تتبعات المكدس الداخلية أو سلاسل اتصال قاعدة البيانات.\n\n4. **التسجيل**: سجل جميع استدعاءات الأدوات مع الطابع الزمني والمدخلات ومدة التنفيذ. استخدم stderr للتسجيل (وليس stdout) مع نقل stdio.\n\n5. **تحديد المعدل**: نفذ حدود معدل لكل أداة لمنع حلقات AI غير المتحكم فيها من إغراق خدمات الواجهة الخلفية.\n\n6. **المهلة الزمنية**: عيّن مهلات تنفيذ على جميع معالجات الأدوات. قد تستدعي نماذج AI أدوات تطلق استعلامات مكلفة — احمِ بنيتك التحتية.\n\n7. **فصل البيئات**: استخدم متغيرات البيئة لجميع التكوينات. لا تشفر أبدًا عناوين URL لقواعد البيانات أو مفاتيح API أو مسارات الملفات.\n\n8. **التنسيق**: استخدم التنسيق الدلالي لخادم MCP الخاص بك. يتضمن مصافحة `initialize` تفاوض الإصدار — التغييرات غير المتوافقة تتطلب زيادة في الإصدار الرئيسي.\n\n## الأسئلة الشائعة\n\n**س: ما الفرق بين MCP و function calling؟**\nج: يحدد function calling (المستخدم من OpenAI و Anthropic وغيرهم) الأدوات بشكل مضمن في كل طلب API. يُخرج MCP تعريفات الأدوات إلى خوادم مستقلة يمكن لمضيفات MCP المتوافقة اكتشافها واستخدامها. Function calling يعمل لكل طلب؛ MCP هو بروتوكول دائم مع جلسات ذات حالة.\n\n**س: هل يمكنني استخدام MCP مع نماذج غير Claude؟**\nج: نعم. MCP هو بروتوكول مفتوح. اعتمدت OpenAI و Google DeepMind و Microsoft دعم MCP في منصاتهم منذ أوائل 2026. أي تطبيق AI ينفذ MCP client يمكنه الاتصال بأي MCP server.\n\n**س: هل MCP للأدوات المحلية فقط؟**\nج: لا. بينما صُمم نقل stdio للخوادم المحلية، يدعم نقل HTTP+SSE و Streamable HTTP خوادم MCP البعيدة. يمكنك نشر خادم MCP كخدمة سحابية يمكن الوصول إليها عبر الشبكة.\n\n**س: كيف يتعامل MCP مع المصادقة؟**\nج: يدعم البروتوكول OAuth 2.0 للخوادم البعيدة. ترث خوادم stdio المحلية سياق أمان عملية المضيف. لعمليات النشر المؤسسية، يمكن لبوابة MCP مركزة المصادقة والتفويض.\n\n**س: ما اللغات التي يمكن استخدامها لبناء خادم MCP؟**\nج: تتوفر SDKs الرسمية لـ TypeScript و Python و Java و Kotlin و C# و Swift. تشمل SDKs المجتمع Rust و Go و Ruby و PHP. البروتوكول لا يعتمد على لغة معينة — أي لغة يمكنها قراءة\u002Fكتابة JSON-RPC عبر stdio أو HTTP يمكنها تنفيذ خادم MCP.\n\n**س: كيف تحدث خادم MCP دون إعادة تشغيل المضيف؟**\nج: يدعم MCP إشعارات تغيير القدرات. عندما تتغير أدوات خادمك، يمكن للخادم إرسال رسالة `notifications\u002Ftools\u002Flist_changed`، مما يدفع client لإعادة جلب قائمة الأدوات. لخوادم stdio، عادة ما يحتاج المضيف لإعادة التشغيل. يمكن تحديث خوادم HTTP دون إعادة تشغيل المضيف.","\u003Ch2 id=\"model-context-protocol-mcp\">ما هو Model Context Protocol (MCP)؟\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>Model Context Protocol (MCP)\u003C\u002Fstrong> هو معيار مفتوح أنشأته Anthropic يحدد كيفية تواصل تطبيقات AI مع مصادر البيانات والأدوات الخارجية. فكر في MCP كـ \u003Cstrong>USB-C لدمج AI\u003C\u002Fstrong>: تمامًا كما يوفر USB-C موصلًا عالميًا واحدًا للشحن ونقل البيانات وإخراج الشاشة، يوفر MCP بروتوكولًا عالميًا واحدًا لربط نماذج AI بقواعد البيانات وواجهات API وأنظمة الملفات وأي خدمة أخرى. يلغي MCP الحاجة إلى عمليات دمج مخصصة بين كل تطبيق AI وكل أداة.\u003C\u002Fp>\n\u003Cp>في عام 2026، أصبح MCP المعيار المهيمن لاتصالات AI-الأدوات. تتوقع Gartner أن \u003Cstrong>40% من تطبيقات المؤسسات ستتضمن وكلاء AI بحلول نهاية 2026\u003C\u002Fstrong>، و MCP هو البروتوكول الذي يجعل هذا عمليًا على نطاق واسع. قبل MCP، كان ربط نموذج AI بـ N أداة يتطلب N عملية دمج مخصصة. مع M تطبيق AI و N أداة، كنت بحاجة إلى M x N محول دمج. يختزل MCP هذا إلى M + N: كل تطبيق AI ينفذ MCP client واحد، وكل أداة تنفذ MCP server واحد.\u003C\u002Fp>\n\u003Ch2 id=\"mcp-host-client-server-transport\">بنية MCP: Host و Client و Server و Transport\u003C\u002Fh2>\n\u003Cp>فهم بنية MCP ضروري قبل كتابة أي كود. يحدد البروتوكول أربعة أدوار رئيسية:\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>المكون\u003C\u002Fth>\u003Cth>الدور\u003C\u002Fth>\u003Cth>مثال\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>\u003Cstrong>Host\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>تطبيق AI الذي يتفاعل معه المستخدم النهائي\u003C\u002Ftd>\u003Ctd>Claude Desktop، Cursor، VS Code Copilot\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Client\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>معالج بروتوكول MCP داخل الـ Host\u003C\u002Ftd>\u003Ctd>مدمج في تطبيق الـ Host\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Server\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>يكشف tools و resources و prompts عبر MCP\u003C\u002Ftd>\u003Ctd>خادمك المخصص (ما سنبنيه)\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>Transport\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>طبقة الاتصال بين Client و Server\u003C\u002Ftd>\u003Ctd>stdio، HTTP+SSE، Streamable HTTP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>يعمل تدفق الاتصال كالتالي:\u003C\u002Fp>\n\u003Col>\n\u003Cli>يبدأ \u003Cstrong>Host\u003C\u002Fstrong> ويهيئ MCP \u003Cstrong>Client\u003C\u002Fstrong> لكل خادم مُعد.\u003C\u002Fli>\n\u003Cli>يتصل \u003Cstrong>Client\u003C\u002Fstrong> بـ \u003Cstrong>Server\u003C\u002Fstrong> عبر \u003Cstrong>Transport\u003C\u002Fstrong> (stdio للمحلي، HTTP للبعيد).\u003C\u002Fli>\n\u003Cli>يرسل \u003Cstrong>Client\u003C\u002Fstrong> طلب \u003Ccode>initialize\u003C\u002Fcode>، يتفاوض على إصدار البروتوكول والقدرات.\u003C\u002Fli>\n\u003Cli>يستجيب \u003Cstrong>Server\u003C\u002Fstrong> بـ \u003Cstrong>tools\u003C\u002Fstrong> و \u003Cstrong>resources\u003C\u002Fstrong> و \u003Cstrong>prompts\u003C\u002Fstrong> المتاحة.\u003C\u002Fli>\n\u003Cli>عندما يحتاج نموذج AI إلى بيانات أو إجراءات خارجية، يستدعي \u003Cstrong>Client\u003C\u002Fstrong> طريقة الخادم المناسبة.\u003C\u002Fli>\n\u003Cli>ينفذ \u003Cstrong>Server\u003C\u002Fstrong> العملية ويعيد النتائج عبر رسائل JSON-RPC 2.0.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch3>Tools مقابل Resources مقابل Prompts\u003C\u002Fh3>\n\u003Cp>يمكن لخوادم MCP كشف ثلاثة أنواع من القدرات:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>Tools\u003C\u002Fstrong> هي دوال يمكن لنموذج AI استدعاؤها. تقبل مدخلات منظمة وتعيد مخرجات منظمة. مثال: \u003Ccode>query_database(sql: string)\u003C\u002Fcode> أو \u003Ccode>send_email(to: string, subject: string, body: string)\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Resources\u003C\u002Fstrong> هي بيانات يمكن لنموذج AI قراءتها. يتم تحديدها بواسطة URIs وتعيد محتوى. مثال: \u003Ccode>file:\u002F\u002F\u002Fpath\u002Fto\u002Fdocument.md\u003C\u002Fcode> أو \u003Ccode>postgres:\u002F\u002Flocalhost\u002Fmydb\u002Fusers\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Prompts\u003C\u002Fstrong> هي قوالب prompts قابلة لإعادة الاستخدام يوفرها الخادم. تساعد في توحيد طريقة تفاعل AI مع مجال الخادم. مثال: قالب \u003Ccode>summarize_ticket\u003C\u002Fcode> لخادم Jira MCP.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"mcp-typescript\">خطوة بخطوة: بناء خادم MCP في TypeScript\u003C\u002Fh2>\n\u003Cp>لنبنِ خادم MCP عملي يوفر أداة للاستعلام من قاعدة بيانات SQLite. هذا حالة استخدام شائعة: منح نموذج AI وصولًا آمنًا للقراءة فقط إلى بيانات تطبيقك.\u003C\u002Fp>\n\u003Ch3>الخطوة 1: تهيئة المشروع\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-bash\">mkdir mcp-sqlite-server &amp;&amp; cd mcp-sqlite-server\nnpm init -y\nnpm install @modelcontextprotocol\u002Fsdk better-sqlite3\nnpm install -D typescript @types\u002Fnode @types\u002Fbetter-sqlite3\nnpx tsc --init\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>تكوين \u003Ccode>tsconfig.json\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"outDir\": \".\u002Fdist\",\n    \"rootDir\": \".\u002Fsrc\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"declaration\": true\n  },\n  \"include\": [\"src\u002F**\u002F*\"]\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>الخطوة 2: تنفيذ الخادم\u003C\u002Fh3>\n\u003Cp>إنشاء \u003Ccode>src\u002Findex.ts\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-typescript\">import { McpServer } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fmcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol\u002Fsdk\u002Fserver\u002Fstdio.js\";\nimport Database from \"better-sqlite3\";\nimport { z } from \"zod\";\n\nconst db = new Database(process.env.DB_PATH || \".\u002Fdata.db\", {\n  readonly: true,\n});\n\nconst server = new McpServer({\n  name: \"sqlite-query\",\n  version: \"1.0.0\",\n});\n\nserver.tool(\n  \"query\",\n  \"تنفيذ استعلام SQL للقراءة فقط على قاعدة بيانات SQLite\",\n  {\n    sql: z.string().describe(\"استعلام SQL SELECT المراد تنفيذه\"),\n  },\n  async ({ sql }) =&gt; {\n    const normalized = sql.trim().toUpperCase();\n    if (!normalized.startsWith(\"SELECT\")) {\n      return {\n        content: [{ type: \"text\", text: \"خطأ: يُسمح فقط باستعلامات SELECT.\" }],\n        isError: true,\n      };\n    }\n    try {\n      const rows = db.prepare(sql).all();\n      return {\n        content: [{ type: \"text\", text: JSON.stringify(rows, null, 2) }],\n      };\n    } catch (error) {\n      return {\n        content: [{ type: \"text\", text: `خطأ في الاستعلام: ${(error as Error).message}` }],\n        isError: true,\n      };\n    }\n  }\n);\n\nserver.tool(\n  \"list_tables\",\n  \"عرض جميع الجداول في قاعدة البيانات مع مخططاتها\",\n  {},\n  async () =&gt; {\n    const tables = db\n      .prepare(\n        `SELECT name, sql FROM sqlite_master\n         WHERE type='table' AND name NOT LIKE 'sqlite_%'\n         ORDER BY name`\n      )\n      .all();\n    return {\n      content: [{ type: \"text\", text: JSON.stringify(tables, null, 2) }],\n    };\n  }\n);\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>الخطوة 3: البناء والاختبار المحلي\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-bash\">npx tsc\necho '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{\"protocolVersion\":\"2025-03-26\",\"capabilities\":{},\"clientInfo\":{\"name\":\"test\",\"version\":\"1.0\"}}}' | node dist\u002Findex.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>يجب أن ترى استجابة JSON-RPC تحتوي على قدرات الخادم.\u003C\u002Fp>\n\u003Ch3>الخطوة 4: بناء نفس الخادم بلغة Python\u003C\u002Fh3>\n\u003Cp>لمطوري Python، إليك التنفيذ المكافئ باستخدام SDK Python الرسمي لـ MCP:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-python\">import sqlite3\nimport json\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP(\"sqlite-query\")\nDB_PATH = \"data.db\"\n\n@mcp.tool()\ndef query(sql: str) -&gt; str:\n    \"\"\"تنفيذ استعلام SQL للقراءة فقط على قاعدة بيانات SQLite.\"\"\"\n    normalized = sql.strip().upper()\n    if not normalized.startswith(\"SELECT\"):\n        raise ValueError(\"يُسمح فقط باستعلامات SELECT.\")\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(sql)\n        rows = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(rows, indent=2, default=str)\n    finally:\n        conn.close()\n\n@mcp.tool()\ndef list_tables() -&gt; str:\n    \"\"\"عرض جميع الجداول في قاعدة البيانات مع مخططاتها.\"\"\"\n    conn = sqlite3.connect(DB_PATH)\n    conn.row_factory = sqlite3.Row\n    try:\n        cursor = conn.execute(\n            \"SELECT name, sql FROM sqlite_master \"\n            \"WHERE type='table' AND name NOT LIKE 'sqlite_%'\"\n        )\n        tables = [dict(row) for row in cursor.fetchall()]\n        return json.dumps(tables, indent=2)\n    finally:\n        conn.close()\n\nif __name__ == \"__main__\":\n    mcp.run(transport=\"stdio\")\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"claude-desktop\">الاتصال بـ Claude Desktop\u003C\u002Fh2>\n\u003Cp>يدعم Claude Desktop خوادم MCP بشكل أصلي. لربط خادمك، عدّل ملف تكوين Claude Desktop:\u003C\u002Fp>\n\u003Cp>\u003Cstrong>macOS:\u003C\u002Fstrong> \u003Ccode>~\u002FLibrary\u002FApplication Support\u002FClaude\u002Fclaude_desktop_config.json\u003C\u002Fcode>\n\u003Cstrong>Windows:\u003C\u002Fstrong> \u003Ccode>%APPDATA%\\Claude\\claude_desktop_config.json\u003C\u002Fcode>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\"\u002Fabsolute\u002Fpath\u002Fto\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \"\u002Fabsolute\u002Fpath\u002Fto\u002Fyour\u002Fdata.db\"\n      }\n    }\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>أعد تشغيل Claude Desktop. سترى أيقونة مطرقة في واجهة المحادثة تشير إلى أدوات MCP المتاحة. الآن يمكنك سؤال Claude مثل “ما الجداول الموجودة في قاعدة البيانات؟” أو “أظهر لي أعلى 10 مستخدمين حسب تاريخ التسجيل” وسيستخدم Claude خادم MCP الخاص بك للاستعلام من قاعدة البيانات مباشرة.\u003C\u002Fp>\n\u003Ch2 id=\"cursor\">الاتصال بـ Cursor\u003C\u002Fh2>\n\u003Cp>يدعم Cursor أيضًا خوادم MCP. أضف التكوين إلى \u003Ccode>.cursor\u002Fmcp.json\u003C\u002Fcode> في جذر مشروعك:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  \"mcpServers\": {\n    \"sqlite-query\": {\n      \"command\": \"node\",\n      \"args\": [\".\u002Fdist\u002Findex.js\"],\n      \"env\": {\n        \"DB_PATH\": \".\u002Fdata.db\"\n      }\n    }\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>بعد الحفظ، أعد تشغيل Cursor. ستظهر أدوات MCP في لوحة مساعد AI ويمكن استدعاؤها أثناء جلسات إنشاء الكود وتصحيح الأخطاء.\u003C\u002Fp>\n\u003Ch2 id=\"mcp\">اختبار وتصحيح أخطاء خادم MCP\u003C\u002Fh2>\n\u003Ch3>استخدام MCP Inspector\u003C\u002Fh3>\n\u003Cp>MCP Inspector هو أداة التصحيح الرسمية. يوفر واجهة ويب للتفاعل مع خادمك:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">npx @modelcontextprotocol\u002Finspector node dist\u002Findex.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>يفتح هذا واجهة متصفح على \u003Ccode>http:\u002F\u002Flocalhost:5173\u003C\u002Fcode> حيث يمكنك:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>عرض جميع tools و resources و prompts المسجلة\u003C\u002Fli>\n\u003Cli>استدعاء tools بمدخلات مخصصة وفحص الاستجابات\u003C\u002Fli>\n\u003Cli>مراقبة تدفق رسائل JSON-RPC في الوقت الفعلي\u003C\u002Fli>\n\u003Cli>اختبار معالجة الأخطاء بإرسال طلبات مشوهة\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch3>مشاكل التصحيح الشائعة\u003C\u002Fh3>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>المشكلة\u003C\u002Fth>\u003Cth>السبب\u003C\u002Fth>\u003Cth>الحل\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>الخادم لا يظهر في Claude Desktop\u003C\u002Ftd>\u003Ctd>مسار التكوين أو خطأ في صيغة JSON\u003C\u002Ftd>\u003Ctd>تحقق من JSON، تحقق من المسارات المطلقة\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>خطأ “Tool not found”\u003C\u002Ftd>\u003Ctd>الأدوات غير مسجلة قبل الاتصال\u003C\u002Ftd>\u003Ctd>سجل الأدوات قبل استدعاء \u003Ccode>server.connect()\u003C\u002Fcode>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>انتهاء المهلة عند استدعاء الأدوات\u003C\u002Ftd>\u003Ctd>عملية طويلة بدون تقدم\u003C\u002Ftd>\u003Ctd>أضف إشعارات التقدم عبر \u003Ccode>server.sendProgress()\u003C\u002Fcode>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>مخرجات stderr تفسد البروتوكول\u003C\u002Ftd>\u003Ctd>console.log يكتب إلى stdout (نقل stdio)\u003C\u002Ftd>\u003Ctd>استخدم \u003Ccode>console.error()\u003C\u002Fcode> للتسجيل مع stdio\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>انقطاع الاتصال بعد الخمول\u003C\u002Ftd>\u003Ctd>انتهاء مهلة النقل\u003C\u002Ftd>\u003Ctd>نفذ heartbeat أو استخدم نقل HTTP\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch2 id=\"\">أفضل الممارسات للإنتاج\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\n\u003Cp>\u003Cstrong>التحقق من المدخلات\u003C\u002Fstrong>: تحقق دائمًا من مدخلات الأدوات ونظفها. استخدم مخططات Zod (TypeScript) أو نماذج Pydantic (Python) للتحقق الصارم من الأنواع.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>القراءة فقط افتراضيًا\u003C\u002Fstrong>: ابدأ بالوصول للقراءة فقط. أضف قدرات الكتابة فقط عند الحاجة الفعلية، واطلب دائمًا التأكيد للعمليات التدميرية.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>معالجة الأخطاء\u003C\u002Fstrong>: أعد رسائل خطأ منظمة مع \u003Ccode>isError: true\u003C\u002Fcode>. لا تكشف أبدًا عن تتبعات المكدس الداخلية أو سلاسل اتصال قاعدة البيانات.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>التسجيل\u003C\u002Fstrong>: سجل جميع استدعاءات الأدوات مع الطابع الزمني والمدخلات ومدة التنفيذ. استخدم stderr للتسجيل (وليس stdout) مع نقل stdio.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>تحديد المعدل\u003C\u002Fstrong>: نفذ حدود معدل لكل أداة لمنع حلقات AI غير المتحكم فيها من إغراق خدمات الواجهة الخلفية.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>المهلة الزمنية\u003C\u002Fstrong>: عيّن مهلات تنفيذ على جميع معالجات الأدوات. قد تستدعي نماذج AI أدوات تطلق استعلامات مكلفة — احمِ بنيتك التحتية.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>فصل البيئات\u003C\u002Fstrong>: استخدم متغيرات البيئة لجميع التكوينات. لا تشفر أبدًا عناوين URL لقواعد البيانات أو مفاتيح API أو مسارات الملفات.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>التنسيق\u003C\u002Fstrong>: استخدم التنسيق الدلالي لخادم MCP الخاص بك. يتضمن مصافحة \u003Ccode>initialize\u003C\u002Fcode> تفاوض الإصدار — التغييرات غير المتوافقة تتطلب زيادة في الإصدار الرئيسي.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch2 id=\"\">الأسئلة الشائعة\u003C\u002Fh2>\n\u003Cp>\u003Cstrong>س: ما الفرق بين MCP و function calling؟\u003C\u002Fstrong>\nج: يحدد function calling (المستخدم من OpenAI و Anthropic وغيرهم) الأدوات بشكل مضمن في كل طلب API. يُخرج MCP تعريفات الأدوات إلى خوادم مستقلة يمكن لمضيفات MCP المتوافقة اكتشافها واستخدامها. Function calling يعمل لكل طلب؛ MCP هو بروتوكول دائم مع جلسات ذات حالة.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>س: هل يمكنني استخدام MCP مع نماذج غير Claude؟\u003C\u002Fstrong>\nج: نعم. MCP هو بروتوكول مفتوح. اعتمدت OpenAI و Google DeepMind و Microsoft دعم MCP في منصاتهم منذ أوائل 2026. أي تطبيق AI ينفذ MCP client يمكنه الاتصال بأي MCP server.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>س: هل MCP للأدوات المحلية فقط؟\u003C\u002Fstrong>\nج: لا. بينما صُمم نقل stdio للخوادم المحلية، يدعم نقل HTTP+SSE و Streamable HTTP خوادم MCP البعيدة. يمكنك نشر خادم MCP كخدمة سحابية يمكن الوصول إليها عبر الشبكة.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>س: كيف يتعامل MCP مع المصادقة؟\u003C\u002Fstrong>\nج: يدعم البروتوكول OAuth 2.0 للخوادم البعيدة. ترث خوادم stdio المحلية سياق أمان عملية المضيف. لعمليات النشر المؤسسية، يمكن لبوابة MCP مركزة المصادقة والتفويض.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>س: ما اللغات التي يمكن استخدامها لبناء خادم MCP؟\u003C\u002Fstrong>\nج: تتوفر SDKs الرسمية لـ TypeScript و Python و Java و Kotlin و C# و Swift. تشمل SDKs المجتمع Rust و Go و Ruby و PHP. البروتوكول لا يعتمد على لغة معينة — أي لغة يمكنها قراءة\u002Fكتابة JSON-RPC عبر stdio أو HTTP يمكنها تنفيذ خادم MCP.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>س: كيف تحدث خادم MCP دون إعادة تشغيل المضيف؟\u003C\u002Fstrong>\nج: يدعم MCP إشعارات تغيير القدرات. عندما تتغير أدوات خادمك، يمكن للخادم إرسال رسالة \u003Ccode>notifications\u002Ftools\u002Flist_changed\u003C\u002Fcode>، مما يدفع client لإعادة جلب قائمة الأدوات. لخوادم stdio، عادة ما يحتاج المضيف لإعادة التشغيل. يمكن تحديث خوادم HTTP دون إعادة تشغيل المضيف.\u003C\u002Fp>\n","ar","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:39.721369Z","دليل تعليمي خطوة بخطوة لبناء خادم MCP بلغتي TypeScript و Python. اربطه بـ Claude Desktop أو Cursor، اختبره باستخدام MCP Inspector، وانشره في بيئة الإنتاج.","دليل خادم mcp",null,"index, follow",[21,26],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000008","AI","ai","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000002","TypeScript","typescript","الهندسة",[32,38,44],{"id":33,"title":34,"slug":35,"excerpt":36,"locale":12,"category_name":30,"published_at":37},"d0000000-0000-0000-0000-000000000686","لماذا Bali تتحول إلى مركز تكنولوجيا التأثير في جنوب شرق آسيا 2026","limadha-bali-tatahawwal-markaz-tiknulujia-attathir-janub-sharq-asia-2026","تحتل Bali المرتبة 16 بين أنظمة الشركات الناشئة في جنوب شرق آسيا. مع تركيز متزايد لبناة Web3 وشركات AI المستدامة الناشئة وشركات تكنولوجيا السفر البيئي، تنحت الجزيرة مكانتها كعاصمة تكنولوجيا التأثير في المنطقة.","2026-03-28T10:44:50.120618Z",{"id":39,"title":40,"slug":41,"excerpt":42,"locale":12,"category_name":30,"published_at":43},"d0000000-0000-0000-0000-000000000685","فسيفساء حماية البيانات في ASEAN: قائمة امتثال للمطورين","fusayfisa-himayat-albayanat-asean-qaimat-imtithal-lilmutawwirin","تمتلك سبع دول في ASEAN الآن قوانين شاملة لحماية البيانات، لكل منها نماذج موافقة ومتطلبات توطين وهياكل عقوبات مختلفة. إليك قائمة امتثال عملية للمطورين الذين يبنون تطبيقات متعددة البلدان.","2026-03-28T10:44:50.114369Z",{"id":45,"title":46,"slug":47,"excerpt":48,"locale":12,"category_name":30,"published_at":49},"d0000000-0000-0000-0000-000000000684","التحول الرقمي في Indonesia بقيمة 29 مليار دولار: فرص لشركات البرمجيات","attahawwul-arraqami-indonesia-29-milyar-dular-furas-sharikat-albarmajiyat","من المتوقع أن يصل سوق خدمات تكنولوجيا المعلومات في Indonesia إلى 29.03 مليار دولار في 2026، ارتفاعاً من 24.37 مليار دولار في 2025. البنية التحتية السحابية والذكاء الاصطناعي والتجارة الإلكترونية ومراكز البيانات تقود أسرع نمو في جنوب شرق آسيا.","2026-03-28T10:44:50.092728Z",{"id":13,"name":51,"slug":52,"bio":53,"photo_url":18,"linkedin":18,"role":54,"created_at":55,"updated_at":55},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]