خادم MCP
خادم MCP
استخدم FourA من أي عميل لـ Model Context Protocol (مثل Claude Desktop وClaude Code وCursor وWindsurf وVS Code) كـثلاث أدوات أصلية وخمسة workflow prompts. لا حاجة لـ integration code، ولا لـ HTTP client مخصص.
بدء سريع: stdio محلي (موصى به لـ Claude Desktop)
احصل على مفتاح من foura.ai/dashboard#api-keys (بنقرة واحدة، يظهر مرة واحدة عند الإنشاء، بالصيغة pk_live_...). ضع هذا المفتاح في ملف تكوين عميل MCP الخاص بك:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "@fouradata/mcp"],
"env": { "FOURA_API_KEY": "pk_live_..." }
}
}
}
ملاحظة هامة لـ Claude Desktop: أغلق Claude Desktop تماماً (
Cmd+Qعلى نظام macOS) قبل تعديل ملف التكوين. إذا كان التطبيق لا يزال قيد التشغيل، فسيقوم بالكتابة فوق تعديلاتك باستخدام التكوين المخزن في الذاكرة عند الخروج.
يقوم الأمر npx بتنزيل @fouradata/mcp عند التشغيل الأول (~10 ثوانٍ) وتشغيله كعملية فرعية (subprocess) لعميل MCP الخاص بك. لا يلزم التثبيت العام (global install).
| العميل | موقع ملف التكوين |
|---|---|
| Claude Desktop (macOS) | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Claude Desktop (Windows) | %APPDATA%\Claude\claude_desktop_config.json |
| Claude Code | claude mcp add foura -- npx -y @fouradata/mcp (قم بتعيين FOURA_API_KEY في البيئة أولاً) |
| Cursor | ~/.cursor/mcp.json |
| Windsurf | ~/.codeium/windsurf/mcp_config.json |
| VS Code (امتداد MCP) | .vscode/mcp.json |
أعد تشغيل العميل. ستظهر الأدوات (foura_single وfoura_proxy وfoura_browser) والخمسة prompts في قائمة الأدوات الخاصة بك.
بدء سريع: مستضاف (Streamable HTTP)
بالنسبة للعملاء الذين يدعمون نقل Streamable HTTP (مثل Cursor وWindsurf وVS Code وClaude Code مع --transport http)، قم بتوجيههم إلى الـ endpoint المستضاف بدلاً من تشغيل عملية فرعية محلية:
{
"mcpServers": {
"foura": {
"url": "https://mcp.foura.ai/mcp",
"headers": {
"Authorization": "Bearer pk_live_..."
}
}
}
}
ترفض إصدارات Claude Desktop الحالية صيغة url المجردة. استخدم تكوين stdio الموضح أعلاه لـ Claude Desktop، أو قم بالجسر عبر mcp-remote:
{
"mcpServers": {
"foura": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.foura.ai/mcp", "--header", "Authorization: Bearer pk_live_..."]
}
}
}
مرجع الـ endpoint المستضاف
| الخاصية | القيمة |
|---|---|
| URL | https://mcp.foura.ai/mcp |
| Transport | Streamable HTTP (POST /mcp، وresponses من نوع SSE) |
| Authentication | Authorization: Bearer pk_live_... لكل request |
| MCP-Protocol-Version | حسب @modelcontextprotocol/sdk (حالياً 2025-11-25، 2025-06-18، 2025-03-26، 2024-11-05، 2024-10-07) |
| 401 challenge | WWW-Authenticate: Bearer realm="foura-mcp", resource_metadata="https://foura.ai/docs/mcp/server#auth" |
الخادم المستضاف عديم الحالة (stateless). يحمل كل request مفتاحه الخاص، والذي يمرره الخادم إلى FourA API كـ X-API-Key. مفتاح واحد يتيح الوصول إلى الأدوات الثلاث كلها.
للحماية من هجمات DNS-rebinding (CVE-2025-66414)، يتحقق الخادم من صحة الـ Host header (يجب أن يكون mcp.foura.ai أو localhost) والـ Origin header عند وجوده (المسموح بها في القائمة البيضاء: mcp.foura.ai وclaude.ai وapp.cursor.sh وapp.cursor.com). المتصلون من خادم إلى خادم (curl وعملاء MCP في وضع جسر stdio) لا يرسلون Origin ويمرون مباشرة.
الأدوات
جميع الأدوات الثلاث مصحوبة بالتعليقين التوضيحيين readOnlyHint: true وopenWorldHint: true وفقاً لـ مواصفات MCP 2025-06-18. العملاء الذين يوافقون تلقائياً على الأدوات الموثوقة المخصصة للقراءة فقط يستدعونها دون نافذة تأكيد منبثقة لكل request.
foura_single
طلب HTTP واحد، مع إرجاع الـ response. يستغرق من 200 ملي ثانية إلى ثانيتين. يطابق POST /api/single/ بنسبة واحد لواحد.
يُستخدم للصفحات الثابتة، وواجهات برمجة تطبيقات JSON APIs، وصفحات HTML التي يتم رندرتها على الخادم (server-rendered).
foura_proxy
طلب HTTP يتم توجيهه عبر مجموعة proxy دوارة مع إعادة محاولة تلقائية. يستغرق من 1 إلى 5 ثوانٍ. يطابق POST /api/proxy/.
يُستخدم عندما تُرجع أداة foura_single الخطأ 403، أو CAPTCHA، أو محتوى محظوراً جغرافياً. يتضمن الـ response معرف الـ proxy الذي نجح (proxy) والوقت الإجمالي الفعلي بالثواني (total كعدد عشري float).
foura_browser
جلسة متصفح كاملة. يتم تشغيل JavaScript، ورندرة الـ DOM، وإرجاع الـ cookies. يستغرق من 2 إلى 10 ثوانٍ. يطابق POST /api/browser/.
يُستخدم لتطبيقات الصفحة الواحدة (single-page apps)، أو المحتوى المحمل كسلان (lazy-loaded)، أو الصفحات المحمية بتحديات مكافحة البوتات التي تتطلب متصفحاً حقيقياً لتجاوزها.
بالنسبة لهياكل المدخلات، والقيم الافتراضية، وقواعد التحقق من الصحة لكل أداة، يرجى الرجوع إلى مرجع REST endpoint. تطابق مخططات الأدوات (schemas) واجهة REST API حقلاً بحقل، بالإضافة إلى ميزة الاختيار الاختياري offload_large الحصرية لـ MCP (انظر أدناه).
الاستجابات المحددة النوع (Typed responses)
يتضمن كل response للأداة كلاً من content (ملخص نصي مقروء للبشر) وstructuredContent (ملف JSON محدد النوع تم التحقق من صحته مقابل الـ outputSchema الخاص بالأداة). لكل أداة هيكلها الفريد الخاص بها:
foura_single:{ status, headers, data, total_time, ... }(الـ headers عبارة عن مصفوفة، إدخال واحد لكل قفزة إعادة توجيه redirect hop)foura_proxy: نفس أداة single بالإضافة إلى{ proxy, total }(حيثtotalهو الثواني كعدد عشري float، وهو التوقيت الخارجي شاملاً محاولات الإعادة)foura_browser: هيكل متميز{ status, headers: object, body, cookies, userAgent }(ملاحظة: قد يكونbodyسلسلة نصية string أو كائناً object اعتماداً على content-type)
العملاء الذين يدعمون structuredContent (مثل Claude Desktop وCursor وWindsurf بدءاً من عام 2026) يمررون الكائن المحدد النوع مباشرة إلى نموذج اللغة الكبير LLM، متجاوزين عملية إعادة ترميز الـ JSON كسلسلة نصية (re-tokenization). توقع توفيراً بنسبة 30-40% في الـ tokens على الاستجابات النموذجية.
الـ response headers متعددة القيم
الـ headers التي تظهر عدة مرات (مثل Set-Cookie وLink وWWW-Authenticate) تعود كمصفوفات:
{
"headers": [
{
"result": { "version": "HTTP/2", "code": 200, "reason": "" },
"content-type": "text/html",
"set-cookie": ["a=1; Path=/", "b=2; Path=/"]
}
]
}
هذا الأمر مهم للمواقع التي تقوم بتعيين cookies الجلسة + التتبع + الموافقة في response واحد (معظم مواقع التجارة الإلكترونية).
الاستجابات الكبيرة: offload_large (الافتراضي: inline)
بشكل افتراضي (منذ الإصدار v0.2.0)، يتم إرجاع هياكل الـ response الكاملة inline في structuredContent بغض النظر عن الحجم. يعمل هذا في كل عميل MCP مباشرة دون تكوين إضافي.
إذا كان عميلك يدعم MCP resources/read وتريد توفير الـ tokens في الصفحات الكبيرة، فمرر offload_large: true مع كل استدعاء للأداة. سيتم حينها كتابة الاستجابات التي تساوي أو تزيد عن 50 كيلوبايت على القرص، وإرجاعها كـ resource_link، وسيقوم عميلك بجلب الـ body فقط عندما يحتاج إليه فعلياً. تنتهي صلاحية البيانات المخزنة مؤقتاً بعد ساعة واحدة.
{
"method": "GET",
"url": "https://en.wikipedia.org/wiki/Web_scraping",
"offload_large": true
}
| العميل | offload_large: true |
|---|---|
| Claude Desktop | ليس بعد، اترك القيمة الافتراضية false |
| Claude Code, Cursor, Windsurf | مدعوم |
| امتداد VS Code MCP | مدعوم |
معزول على مستوى المستأجر (Tenant-isolated): يحصل كل مفتاح API على مساحة الاسم الخاصة به (sha256(apiKey)[:16]). المفتاح الذي قام بتخزين البيانات فقط هو من يمكنه قراءتها مجدداً. تُرجع عمليات القراءة عبر المستأجرين الخطأ Payload not found دون تسريب معلومات حول وجود البيانات.
التوجيهات المدمجة (Built-in Prompts)
تظهر خمسة قوالب لسير العمل تحت المسار /prompts في أي عميل MCP. يأخذ كل منها وسيطات مسمية (named arguments) ويُرجع رسالة مستخدم مجهزة بقالب تقوم بتنسيق أداة واحدة أو أكثر.
| Prompt | الوسيطات (Arguments) | ماذا يفعل |
|---|---|---|
scrape_product_page |
url |
جلب عبر المتصفح، ثم استخراج عنوان المنتج، السعر، الصورة، المخزون، وSKU كـ JSON |
extract_article |
url |
جلب عبر Single مع تراجع تلقائي إلى proxy، ثم إزالة عناصر التنقل/الإعلانات وإرجاع مقال JSON نظيف |
monitor_pricing |
url، وtarget_price اختياري |
جلب عبر proxy، واستخراج السعر الحالي، ومقارنته بالسعر المستهدف |
check_endpoint_health |
url، وexpected_text اختياري |
جلب عبر Single مع تحقق صارم من الصحة، وإرجاع حالة الوصول والتوقيت |
bulk_fetch_urls |
urls (مفصولة بفاصلة) |
جلب متوازٍ عبر Single، وتراجع تلقائي إلى proxy لكل URL، وإرجاع البيانات التعريفية (metadata) فقط |
لا تستهلك التوجيهات (prompts) أي tokens في حالة الخمول. التوجيهات التي يتم استدعاؤها فقط هي التي تدخل في سياق الـ LLM.
النص الكامل بالإضافة إلى توجيهات التراجع اليدوي: وصفات MCP.
غلاف الخطأ (Error envelope)
يحمل كل خطأ (isError: true) غلاف structuredContent. الحد الأدنى من الحقول في كل خطأ:
{
"service": "single | proxy | browser",
"code": "rate_limited",
"error": "Rate limit exceeded"
}
في الأخطاء الصادرة من المصدر (upstream) والتي تحمل حالة HTTP، يكون الحقل status حاضراً أيضاً. في أخطاء الـ rate limit والسعة، يضيف غلاف المصدر الحقول retryAfter وcurrent.{concurrency, rpm} وlimits.{maxConcurrency, maxRpm}. انظر أخطاء واجهة برمجة التطبيقات (API Errors) لمعرفة هيكل REST الأساسي.
قيم code المستقرة:
| الرمز (Code) | HTTP | المعنى | هل إعادة المحاولة آمنة؟ |
|---|---|---|---|
ssrf_blocked |
غير متاح | عنوان IP المستهدف يقع في نطاق خاص أو محجوز (RFC 5735, 6598, IPv6 reserved) | لا، قم بتغيير URL |
upstream_non_json |
يختلف | أرجع المصدر (upstream) هيكلاً غير صالح (malformed body) | ربما، تحقق من الأمر |
output_validation_failed |
غير متاح | رفض الـ outputSchema الخاص بخادم MCP الـ response الخاص بالمصدر (خطأ في الخادم أو هيكل غير متوقع من المصدر) |
ربما، أبلغ عن المشكلة |
bad_request |
400 | تم رفض هيكل المدخلات | لا، قم بإصلاح الوسيطات |
auth_failed |
401 | المفتاح مفقود، غير صالح، أو تم إلغاء تنشيطه | لا، قم بإصلاح المفتاح |
forbidden |
403 | تمت المصادقة ولكن غير مسموح بالوصول | لا، أو انتقل إلى foura_proxy |
not_found |
404 | الهدف أو الـ endpoint مفقود | لا |
rate_limited |
429 | تم الوصول إلى الحد الأقصى لـ RPM | نعم، انتظر retryAfter |
at_capacity |
503 | تم الوصول إلى الحد الأقصى للتزامن (Concurrency) | نعم، انتظر retryAfter |
service_disabled |
503 | فترة صيانة أو أن خطتك لا تشمل هذه الأداة | اتصل بالدعم |
service_unavailable |
503 | خطأ 503 عام | نعم، تراجع لفترة قصيرة (short backoff) |
upstream_error |
500+ | خطأ 5xx من المصدر | نعم، تراجع أسي (exponential backoff) |
upstream_client_error |
4xx | أخطاء 4xx أخرى | لا في الغالب |
upstream_unknown |
أخرى | إجراء دفاعي، لا ينبغي أن يحدث عملياً | تحقق من الأمر |
يمكن لوكلاء الـ LLM قراءة الـ code مباشرة لتنفيذ منطق إعادة المحاولة دون الحاجة لتحليل النصوص. دليل المصادقة: المصادقة.
الحدود
- الـ body يكون inline بشكل افتراضي. عند تفعيل
offload_large: true، تذهب الـ responses التي تساوي أو تزيد عن 50 كيلوبايت إلى القرص مع إرجاعresource_link(لكل مستأجر، مع مدة صلاحية TTL تبلغ ساعة واحدة). - يتم رفض الأهداف الخاصة (RFC 5735 وRFC 6598 ونطاقات IPv6 المحجوزة) على طبقة MCP. يتم تمرير المضيفين العامين فقط.
- الحد الأقصى لحجم request body هو 256 كيلوبايت لطلبات
/mcpالواردة (حمولات MCP الحقيقية تكون أقل من 4 كيلوبايت). - يتم فرض الـ rate limits بواسطة FourA API لكل خدمة. انظر حدود المعدل (Rate Limits).
الاستضافة الذاتية (Self-Hosting)
يعمل كل مثيل (instance) في حاوية واحدة (container) دون حالة (statelessly). ستتوفر نسخة مطابقة عامة على GitHub مع الإصدار v1.0. وحتى ذلك الحين، يتوفر الكود المصدري في مستودع خاص وصورة الحاوية متاحة عند الطلب. اتصل بـ support@foura.ai للحصول على وصول مبكر.
البيئة القابلة للتكوين:
| المتغير | الافتراضي | الغرض |
|---|---|
| PORT | 3076 | منفذ استماع HTTP |
| FOURA_API_BASE | https://api.foura.ai/api | عنوان URL الأساسي لـ REST الخاص بـ FourA المصدر |
| FOURA_MCP_PAYLOADS_DIR | /data/payloads | مكان تخزين الـ responses التي تساوي أو تزيد عن 50 كيلوبايت مؤقتاً على القرص (عند تفعيل offload_large: true) |
| FOURA_MCP_ALLOWED_HOSTS | mcp.foura.ai,localhost,127.0.0.1,[::1] | القائمة البيضاء لأسماء المضيفين لـ Host header (للحماية من هجمات DNS-rebinding) |
| FOURA_MCP_ALLOWED_ORIGINS | https://mcp.foura.ai,https://claude.ai,https://app.cursor.sh,https://app.cursor.com | القائمة البيضاء لـ Origin للمتصلين عبر المتصفح |
| FOURA_MCP_RESOURCE_METADATA_URL | https://foura.ai/docs/mcp/server#auth | عنوان URL المُرجع في WWW-Authenticate عند حدوث خطأ 401 |
يتم التشغيل كـ uid 1001 (غير جذر non-root) في الحاوية الرسمية. يجب أن يكون ربط المضيف /data/payloads (host bind mount) قابلاً للكتابة بواسطة هذا الـ uid.
يمكن التوسيع أفقياً خلف أي موازن تحميل (load balancer). يقدم العملاء مفتاحهم مع كل request، لذا لا توجد sticky session.