> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wolffi.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# خوادم MCP

> اربط أيّ خادم يعمل ببروتوكول سياق النماذج — محليًا أو عن بُعد — فتصبح أدواته أدوات وولفيش

# أيّ خادم أدوات، بلصقة واحدة

[بروتوكول سياق النماذج MCP](https://modelcontextprotocol.io) هو المعيار المفتوح لخوادم الأدوات — منظومة متنامية من الخوادم تعرض قواعد البيانات ومنتجات SaaS وتطبيقات التصميم والمعارف المتخصصة كأدوات يستدعيها الوكيل. يدعم وولفيش هذا البروتوكول دعمًا أصيلًا: الصق أمرًا أو رابطًا في **الإعدادات ← بروتوكول سياق النماذج**، فتصبح كل أداة يعرضها ذلك الخادم متاحة لوولفيش من رسالتك التالية مباشرة — في المحادثة العادية ولوكلاء [سير العمل](/ar/configuration/workflow-mode) على حدّ سواء. بلا خطوة «اتصال» منفصلة، بلا إعادة تشغيل، بلا ملفات تهيئة.

والاتصالات تعتني بنفسها. الخادم المحلي المنهار أو الطرف البعيد المنقطع لا يُظهر نافذة خطأ أبدًا — تتنحى أدواته بهدوء بينما يعيد وولفيش الاتصال في الخلفية، وتعود من تلقاء نفسها حين يعود الخادم.

## ربط خادم

<Steps>
  <Step title="افتح الإعدادات ← بروتوكول سياق النماذج">
    تعرض الصفحة اتصالاتك، ونموذج إضافة، وشرحًا موجزًا.
  </Step>

  <Step title="الصق أمرًا أو رابطًا">
    يكتشف وولفيش وسيلة النقل تلقائيًا مما تلصقه:

    * **أمر** (مثل `uvx tafsir-mcp` أو `npx -y @scope/some-server`) يشغّل **خادمًا محليًا**: يولّده وولفيش عمليةً فرعية ويخاطبه عبر stdin/stdout.
    * **رابط `http(s)://`** (مثل `https://mcp.notion.com/mcp`) يتصل بـ**خادم بعيد** عبر HTTP القابل للبث (مع تراجع تلقائي للخوادم القديمة التي لا تتحدث سوى SSE).

    الاسم اختياري — يشتقّه وولفيش من اسم الأمر أو من مضيف الرابط.
  </Step>

  <Step title="هذا كل شيء">
    يبدأ الاتصال فورًا. أدوات الخادم المحلي تظهر عادة خلال ثانية أو ثانيتين؛ وإذا تطلّب خادم بعيد تسجيل دخول، تعرض البطاقة زرّ **تسجيل الدخول** (انظر أدناه). وفي الحالتين تصبح الأدوات قابلة للاستدعاء من رسالتك التالية.
  </Step>
</Steps>

<Tip>
  الأوامر المحلية تعمل دون صدفة (shell) — علامات الاقتباس مدعومة (`--db "/path/with spaces/db.sqlite"`)، أما توسعة الصدفة (`~` و`$VAR` والأنابيب) فغير مدعومة. استخدم مسارات مطلقة.
</Tip>

### متغيرات البيئة للخوادم المحلية

الخوادم المحلية التي تحتاج بيانات اعتماد تأخذها كمتغيرات بيئة. حين يكتشف نموذج الإضافة أمرًا، يظهر حقل **متغيرات البيئة** الاختياري — سطر `KEY=value` لكل متغير. تُحقن هذه في العملية المولَّدة فقط، ولا تُرسل إلى النموذج اللغوي أبدًا.

```
API_KEY=sk-…
DATABASE_URL=postgres://…
```

## ما الذي تحصل عليه

كل خادم متصل يسجَّل كقدرة مستقلة بذاتها، منطَّقة بأسماء مسبوقة كي لا يتصادم خادمان أبدًا:

* تُسمى القدرة `mcp-<slug>` (مثل `mcp-tafsir-mcp`).
* كل أداة تُسبق بالاسم المختصر (slug) للخادم: `tafsir_mcp_fetch_ayah`، `notion_mcp_search`، ….
* **تعليمات** الخادم نفسه (إرشادات الاستخدام التي ينشرها كثير من الخوادم) ترافق وصف القدرة، فيستخدم النموذج الأدوات كما يقصد الخادم.

خوادم MCP **قابلة للاكتشاف**، شأن كل قدرة غير أساسية: الخادم المتصل لا يكلّف سوى سطر واحد في فهرس القدرات في موجّه النظام (الاسم ووصف موجز وعدد الأدوات) إلى أن يحتاجه النموذج فعلًا. استدعاء `tool_search` — أو استدعاء إحدى أدوات الخادم مباشرةً — يفعّل القدرة، وتصبح أدواتها قابلة للاستدعاء في الدور نفسه. هذا ما يجعل «أضف اتصالًا، استخدمه في الرسالة التالية» صحيحة دون أن يُضخّم كلُّ خادم متصل كلَّ طلب. ووكلاء سير العمل يحصلون على الأدوات ذاتها عبر المسار ذاته؛ لا شيء معامَل معاملة خاصة.

ويدافع وولفيش أيضًا عن موجّهه ضد ما قد يشحنه أي خادم: يُعقَّم وصف كل أداة (تُجرَّد عناوين markdown والوسوم الشبيهة بـ XML وتُسطَّح البنية إلى سطر واحد) ويُحدّ بسقف 400 محرف، فلا يستطيع أي خادم تزوير بنية الموجّه أو إعادة تضخيم الفهرس. أما *مخططات* الأدوات، في المقابل، فتمرّ كما هي حرفيًا.

حالة الاتصال تُفحص بـ `mcp_list`، ولا تُستنتج أبدًا من وجود الأدوات — فأدوات الخادم القابل للاكتشاف ليست في الطلب حتى يُفعَّل، والخادم قد ينقطع ويعاود الاتصال بين دور وآخر.

وإذا أضاف خادم أدوات أو أزالها أثناء التشغيل، يلتقط وولفيش التغيير تلقائيًا (عبر إشعار `list_changed` في البروتوكول، مع فحص دوري احتياطًا).

## بطاقة الاتصال

كل اتصال بطاقة واحدة: نقطة حالة + اسم، وأزرار إجراءات، وسطر حالة، والعنوان في كتلة شيفرة قابلة للنسخ.

| الحالة             | النقطة           | المعنى                                                                               |
| ------------------ | ---------------- | ------------------------------------------------------------------------------------ |
| متصل               | خضراء            | حيّ — تعرض عدد الأدوات                                                               |
| جارٍ الاتصال       | كهرمانية (نابضة) | المصافحة جارية — كتلة الشيفرة تعرض الخطوة الحية (`[2/3] MCP handshake (initialize)`) |
| يتطلب تسجيل الدخول | كهرمانية         | خادم بعيد يحتاج OAuth — تظهر بطاقة تنبيه بزرّ **تسجيل الدخول**                       |
| غير متصل           | محايدة           | الخادم غير قابل للوصول — وولفيش يعيد الاتصال بصمت؛ ويظهر الخطأ حرفيًا في كتلة شيفرة  |
| معطَّل             | محايدة           | أوقفتَه أنت — تُحفظ التهيئة وتسجيل الدخول                                            |

**إجراءات كل بطاقة:**

* **اختبار** (أيقونة التحديث) — يفحص خادمًا متصلًا ويبلّغ عدد الأدوات وزمن الاستجابة في إشعار؛ ويدفع خادمًا منقطعًا لإعادة الاتصال فورًا.
* **مفتاح تشغيل/إيقاف** — أوقف خادمًا دون حذفه. تسقط أدواته من الفهرس؛ وتبقى تهيئته وتسجيل دخوله.
* **حذف** (سلة المهملات) — يزيل الاتصال وكل ما ملكه: سجلّ التهيئة، ورموز تسجيل الدخول المخزنة، و(لخوادم OAuth) إبطال الرموز لدى المزود قدر المستطاع كي لا يبقى «تطبيق متصل» عالق هناك.

<Note>
  بطء الإطلاق الأول طبيعي لبعض الخوادم المحلية — مثلًا `uvx tafsir-mcp` ينزّل قاعدة بيانات بحجم \~214 م.ب في أول تشغيل. تعرض بطاقة الاتصال الخطوةَ الجارية بالضبط، وينتظر وولفيش المصافحة الأولى للخادم المحلي حتى 5 دقائق.
</Note>

## تسجيل الدخول (OAuth للخوادم البعيدة)

بعض الخوادم البعيدة (Notion وLinear وSentry…) تتطلب تسجيل دخول. ينفّذ وولفيش مصافحة OAuth المعيارية في البروتوكول — ولا تكتب كلمة مرور أو رمزًا في وولفيش أبدًا:

<Steps>
  <Step title="وولفيش يكتشفها">
    إضافة الرابط تُنزل البطاقة في حالة **يتطلب تسجيل الدخول**. وفي الخلفية يكون وولفيش قد اكتشف نقاط التفويض لدى الخادم وسجّل نفسه عميل OAuth (تسجيل عميل ديناميكي، باسم `Wolffish`).
  </Step>

  <Step title="نقرة واحدة">
    زرّ **تسجيل الدخول** يفتح متصفحك الافتراضي على صفحة موافقة المزود. تُصادِق لدى المزود مباشرة.
  </Step>

  <Step title="المتصفح يعود">
    بعد موافقتك، يعيد المزود توجيه متصفحك إلى مستمع مؤقت على `127.0.0.1` — النمط المعياري لتطبيقات سطح المكتب (RFC 8252، كما تفعل أدوات `gh` و`gcloud`). يستبدل وولفيش الرمز المؤقت برموز وصول (بتحقق PKCE) ويتصل. ويعرض التبويب «أنت متصل — عد إلى وولفيش».
  </Step>
</Steps>

ومن حينها يصير كل شيء صامتًا للأبد: تُخزَّن الرموز مع بقية بيانات اعتمادك في `config.json`، وتحملها الطلبات تلقائيًا، ويتجدد منتهي الصلاحية في الخلفية، وتعيد عمليات تشغيل التطبيق الاتصالَ دون متصفح. وحذف الاتصال يمسح الرموز محليًا **ويُبطلها** لدى المزود (دون انتظار — الحذف لا يتوقف عليه أبدًا).

<Warning>
  الاتصالات الصامتة لا تفتح متصفحًا أبدًا — الخادم الذي يحتاج تسجيل دخول ينتظر ببساطة في حالة **يتطلب تسجيل الدخول** حتى تنقر. تلك النقرة وحدها (أو أداة `mcp_authorize` بتوجيهٍ منك) هي ما يطلق تسليم المتصفح.
</Warning>

## الإدارة بالمحادثة

يدير وولفيش اتصالاته بخوادم MCP عبر قدرة [`mcp`](/ar/capabilities/built-in-capabilities) المدمجة (قابلة للاكتشاف كأي قدرة أخرى — يعثر عليها النموذج لحظة تسأل عن MCP). تنفّذ العمليات ذاتها التي في صفحة الإعدادات، فكل ما يفعله يظهر هناك حيًا، وكل ما تفعله أنت هناك يراه هو.

| الأداة                       | ما تفعله                                              |
| ---------------------------- | ----------------------------------------------------- |
| `mcp_list`                   | كل الخوادم بحالتها الحية وعدد أدواتها                 |
| `mcp_add`                    | إضافة خادم وربطه (أمر أو رابط، مع اسم/بيئة اختياريين) |
| `mcp_test`                   | التحقق من خادم الآن؛ ودفع العالق لإعادة الاتصال       |
| `mcp_enable` / `mcp_disable` | الإيقاف أو الاستئناف دون حذف                          |
| `mcp_remove`                 | إزالة خادم وكل ما ملكه (يطلب تأكيدك)                  |
| `mcp_authorize`              | بدء تسجيل الدخول عبر المتصفح لخادم بعيد               |

عمليًا، تتحدث فحسب: «اربط خادم التفسير بالأمر `uvx tafsir-mcp`»، «ما خوادم MCP المتصلة؟»، «عطّل ذاك الآن»، «احذفه نهائيًا».

## المتانة

نموذج الفشل هو: **خادم متعثر لا يجوز أن يمسّ خادمًا آخر أو التطبيق أو دورك، أبدًا.**

* **إعادة اتصال صامتة.** الاتصال المنقطع يعيد المحاولة بتباعد أُسّي (ثانية تتضاعف حتى سقف دقيقتين، وإلى الأبد للخوادم البعيدة). لا إشعارات ولا لافتات حمراء — تصير النقطة محايدة، ويظهر الخطأ في البطاقة، وتعود الأدوات بعودة الخادم.
* **الانقطاعات في منتصف الدور قابلة للنجاة.** إن سقط خادم في منتصف مهمة، تبقى أدواته مسجلة وتُرجع الاستدعاءات خطأ شبكة قابلًا لإعادة المحاولة — فيحاول محرك التنفيذ مجددًا لوهلة، وينقذ التعافي السريع الاستدعاءَ بدل إسقاط الدور.
* **فحوص صحة سلبية.** الخوادم المحلية تُراقب بحياة العملية (يُكتشف الانهيار لحظة انغلاق الأنبوب). والبعيدة تنال فحص `tools/list` دوريًا رخيصًا، يعمل أيضًا كتحديث لقائمة الأدوات.
* **الأوامر المكسورة تُركَن.** الأمر المحلي الذي يفشل فشلًا حتميًا (خطأ إملائي، بيئة تشغيل مفقودة) يتوقف عن التولّد بعد 5 محاولات — لا حلقة تنزيل لانهائية لـ`npx`/`uvx`. وتعرض البطاقة مخرجات خطأ الخادم نفسها؛ ونقرة اختبار أو إعادة تشغيل تعيد تسليحه.
* **العزل.** كل اتصال آلة حالة مستقلة. الخادم المتذبذب يتخبط وحده؛ والعملية الفرعية المنهارة تُحصد ويعاد توليدها دون مساس بغيرها.

## مرجع التهيئة

تُحفظ الاتصالات في `config.json` تحت `mcp.servers`. صفحة الإعدادات وأدوات المحادثة تديرها عنك — وتُوثَّق هنا للاكتمال:

```json theme={null}
{
  "mcp": {
    "servers": [
      {
        "id": "5f2c…",
        "name": "tafsir-mcp",
        "slug": "tafsir-mcp",
        "transport": "stdio",
        "command": "uvx tafsir-mcp",
        "env": { "API_KEY": "…" },
        "enabled": true
      },
      {
        "id": "9a1b…",
        "name": "Notion",
        "slug": "notion",
        "transport": "http",
        "url": "https://mcp.notion.com/mcp",
        "enabled": true,
        "oauth": {
          "clientInformation": { "client_id": "…" },
          "tokens": { "access_token": "…", "refresh_token": "…" },
          "redirectPort": 58340
        }
      }
    ]
  }
}
```

| الحقل             | الوصف                                                                                                                                  |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `name`            | الاسم المعروض في الإعدادات                                                                                                             |
| `slug`            | معرّف ثابت يُختار عند الإضافة — يقود اسم القدرة (`mcp-<slug>`) وبادئة الأدوات؛ لا يتغير أبدًا                                          |
| `transport`       | `stdio` (أمر محلي) أو `http` (رابط بعيد)                                                                                               |
| `command` / `env` | للمحلي فقط: سطر الأمر (مُقسَّم دون صدفة) ومتغيرات بيئة إضافية                                                                          |
| `url`             | للبعيد فقط: نقطة النهاية                                                                                                               |
| `enabled`         | مفتاح التشغيل/الإيقاف                                                                                                                  |
| `oauth`           | للخوادم البعيدة الموقَّع دخولها: العميل المسجَّل والرموز ومنفذ الاسترجاع المحلي (يبقى ثابتًا كي لا ينحرف عنوان إعادة التوجيه المسجَّل) |

## تحت الغطاء

للمساهمين — يقيم التنفيذ في `src/main/runtime/mcp/` في مستودع التطبيق:

| الوحدة          | الدور                                                                                                                                                                           |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `manager.ts`    | `McpManager` — اتصال واحد لكل خادم مهيأ؛ السطح الذي تستدعيه معالجات IPC ومسار الإقلاع وجسر قدرة `mcp`                                                                           |
| `connection.ts` | `McpConnection` — آلة حالة دورة حياة الخادم الواحد كاملة: اتصال، اكتشاف، تسجيل، إعادة اتصال بتباعد، فحوص صحة، ركن، تنسيق OAuth                                                  |
| `auth.ts`       | تنفيذ `OAuthClientProvider` من SDK، وخادم الاسترجاع المحلي، وإبطال الرموز قدر المستطاع                                                                                          |
| `capability.ts` | يحوّل قائمة أدوات MCP إلى قدرة مُخيخ: التنطيق، تمرير JSON-Schema كما هو، تعقيم وصف كل أداة (تجريد العناوين والوسوم، سقف 400 محرف)، تطبيع النتائج (نص/صورة/صوت/موارد/محتوى منظم) |
| `naming.ts`     | مساعدات نقية: الأسماء المختصرة، تنطيق أسماء الأدوات (سقف 64 محرفًا مع إزالة التكرار)، تقسيم الأوامر بوعي الاقتباس                                                               |
| `types.ts`      | أنواع التهيئة واللقطات (مصدر الحقيقة؛ وتعكسها طبقة preload)                                                                                                                     |

نقطة الدمج مملّة عمدًا: كل خادم متصل يسجّل **قدرة مُخيخ داخل العملية** عبر `registerInProcessCapability` — الآلية ذاتها التي تستخدمها [أدوات القنوات](/ar/channels/overview). هذا التسجيل الواحد يغذي فهرس القدرات في موجّه النظام، واكتشاف الأدوات وتفعيلها، واختيار أدوات الوكلاء، وتوجيه التنفيذ — ولهذا تصل أدوات MCP إلى كل أوضاع وولفيش دون أي معاملة خاصة. والتسجيل يرفع عدّاد جيل المُخيخ (فيُعاد تثبيت قائمة الأدوات إن تغيّرت في منتصف دور)، وينجو من إعادة تحميل القدرات، ويمرّر مخطط JSON لكل أداة **حرفيًا** — فتصل الاتحادات والقيم الافتراضية والبنى المتداخلة إلى النموذج كما هي. الأوصاف هي الشيء الوحيد الذي لا يمرّ خامًا: تُعقَّم ويُحدّ طولها قبل أن تبلغ أي طلب.

قاعدتان مكتسبتان بمشقة لمن يلمس هذه الشيفرة: الانقطاعات العابرة تُبقي القدرة مسجلة (وهذا ما يجعل انقطاعات منتصف الدور قابلة لإعادة المحاولة ويحفظ ذاكرة تخزين الموجّه لدى المزود)، ومعالج إغلاق النقل يُربط بعد نجاح الاتصال **فقط** (الاتصال الفاشل يغلق نقله بنفسه، والمعالج المبكر كان سيصنّف أخطاء التفويض انقطاعات عامة).

كل ما سبق مغطى بحِزم اختبار مستقلة في `src/main/runtime/__tests__/` — ملف `mcp.test.ts` (دورة الحياة والتسمية والمخططات والمتانة أمام خادم MCP حقيقي في الذاكرة) وملف `mcp-oauth.test.ts` (رحلة OAuth كاملة أمام خادم تفويض محلي مطابق للمواصفة، بما فيها التجديد والإبطال).

## استكشاف الأخطاء

<AccordionGroup>
  <Accordion title="أمر uvx / npx لا يتصل">
    يجب أن يوجد المشغِّل على جهازك: `uvx` يحتاج [uv](https://docs.astral.sh/uv/) (بالأمر `brew install uv`)، و`npx` يحتاج Node. الثنائي المفقود يركن البطاقة «غير متصل» مع خطأ توليد (`ENOENT`) في كتلة الشيفرة. ثبّت المشغِّل ثم اضغط اختبار.
  </Accordion>

  <Accordion title="خادم محلي يفشل باستمرار ثم يتوقف عن المحاولة">
    بعد 5 إطلاقات فاشلة متتالية يركن وولفيش الأمر بدل توليده للأبد. تعرض البطاقة مخرجات stderr للخادم نفسه — غالبًا بيانات اعتماد أو تبعية مفقودة. عالج السبب (أضف متغير البيئة مثلًا) ثم اضغط اختبار لإعادة التسليح.
  </Accordion>

  <Accordion title="خادم بعيد يتذبذب برسالة &#x22;Session not found&#x22;">
    هذه استضافة الخادم لا اتصالك: موزّع الحمل لديه يفرّق الطلبات على أجهزة لا تتشارك جلسات MCP. يعامله وولفيش عابرًا ويواصل المحاولة — ويتصل متى ساعف التوجيه — لكن الإصلاح بيد مشغّل الخادم وحده (التصاق الجلسات). إن كان للخادم نسخة أمر محلي، ففضّلها.
  </Accordion>

  <Accordion title="تسجيل الدخول يفشل قبل أن يفتح المتصفح">
    يسجّل وولفيش نفسه لدى المزود تلقائيًا (تسجيل عميل ديناميكي). قلة من المزودين لا يدعمونه ويشترطون معرّف عميل مسجلًا مسبقًا — هؤلاء لا يكتمل تدفقهم مع أي عميل MCP عام. أما Notion وLinear وSentry فتدعمه جميعًا.
  </Accordion>

  <Accordion title="خادم بعيد يريد مفتاح API صِرفًا لا OAuth">
    ترويسات التفويض المخصصة للخوادم البعيدة غير مدعومة بعد. إن كان للخادم نسخة محلية (stdio)، فشغّلها ومرّر المفتاح متغيرَ بيئة.
  </Accordion>

  <Accordion title="خادم يتصل لكنه يعرض 0 أداة">
    دمج MCP في وولفيش يقدّم الأدوات أولًا. الخادم الذي ينشر *موارد* أو *قوالب موجهات* فقط يتصل جيدًا لكنه لا يسهم بشيء قابل للاستدعاء بعد.
  </Accordion>
</AccordionGroup>
