كل الملاحظات

WebMCP

لم يعد الذكاء الاصطناعي بحاجة للتخمين أو المعالجة المطوله لفهم ما يحدث داخل صفحة الويب، بل أصبحت لديه واجهة موحدة عبر WebMCP تقرأ السياق بدقة.

ما هو WebMCP ولماذا ؟

عندما تطلب من AI AGENT أو CLAUDE EXTENSION تنفيذ مهمة معينة في صفحة ما — كـ ملء نموذج بيانات form أو الحصول على بيانات... إلخ — فيتم الاعتماد على التقاط صور الشاشة أو كشط بيانات DOM وتحليل ومعالجة بياناتها، وقد تخسر كل ذلك مع أي تحديث للصفحة! وهو ما يتسبب في ضياع كثير من الوقت وزيادة استهلاك الـ TOKENS نظراً لأن هذه الأدوات تعمل على قراءة الصفحة بأكملها.

مع توافر الـ WebMCP أصبح هناك قناة اتصال مباشرة وصريحة بين نموذج AI والصفحة، حيث يضيف المطور الأدوات (tools) الخاصة بصفحته في document.modelContext ليقرأها الـ Agent مباشرةً بدلاً من التخمين.

مقارنة بين Server MCP و WebMCP

على عكس الـ MCP التقليدي الذي يعمل أساساً داخل الـ Server (Backend) لتنفيذ مهام (Function Calls) عند طلب الـ Agent، تظل حدود عمله محصورة في بيئة الserver. فهو لا يملك وصولاً مباشراً لصفحة الويب الحالية التي يتصفحها المستخدم.

المقارنة لا تعني إطلاقًا أن أحدهما أفضل من الآخر أو أن أحدهما سيغني عن الثاني، بل هي مقارنة لتوضيح فصل المسؤوليات (Separation of Concerns).

دور الـ Server MCP

الخيار المثالي والوحيد للمهام المعقدة التي تتطلب قوة معالجة عالية، أو الوصول لقواعد البيانات الضخمة (Databases)، أو التعامل مع ملفات النظام (File Systems)، أو تنفيذ عمليات خلفية شاقة لا ينبغي للعميل (Client) الاطلاع عليها أو تحمل عبء معالجتها محلياً.

دور الـ WebMCP

صُمم ليكون متخصص في سياق المتصفح يبرع في المهام المباشرة التي تتفاعل مع الواجهة الحالية، مثل قراءة الـ DOM، والتفاعل مع المدخلات (Forms)، والوصول للـ LocalStorage، واستغلال الجلسة النشطة (Active Session).

مميزات WebMCP

  • معيار JavaScript موحد: يعمل مباشرة داخل المتصفح.
  • Auth تلقائي: الأدوات تعمل داخل جلسة المستخدم، فلا حاجة لـ API Keys أو Auth Headers.
  • التحكم في المشاركة بين المواقع: تحدد عند التسجيل المواقع المسموح لها باستدعاء أدواتك.

ليه لسه محتاجين الأزرار؟

قد يتبادر إلى ذهنك كنظرة مستقبلية: إذا يمكننا الآن التحكم في الصفحة بالكامل عن طريق بروتوكول مثل الـ WebMCP وتنفيذ أي كود JS عن طريق الـ Agent بسهولة، فلماذا لا نعمل على تغيير شكل الـ UI ليكون أبسط عن طريق إخفاء كل التفاصيل من الصفحة وعرض محتوى واحد فقط، شاشة واحدة / عنصر واحد... ويكون المتحكم فقط هو أمر نصي أو صوتي للـ Agent: اعرض كذا، ابحث عن كذا... إلخ.

ولكن يختلف الكثير مع هذا التصور للأسباب التالية:

  • 1. إذا غاب الـ Agent لأي سبب، سنفقد أو سيصعب التحكم بالصفحة.
  • 2. وجود العناصر وترتيبها يساعد قارئات الشاشة (Screen Reader) وخدمة ذوي الهمم.
  • 3. الإنسان بيتعلم وبيستكشف عن طريق رؤيته للصفحة وتفاصيلها، فعند تعرضه لاستخدام شاشة صمّاء سيصعب اكتشاف ما تقدمه الصفحة من مزايا.
  • 4. أحياناً التفاعل اللحظي باستخدام الماوس أو لوحة المفاتيح كيبورد بين قوسين بيبقى أسرع بكتير من كتابة نص كامل في بعض الأمور.
  • 5. سيواجه الـ WebMCP تحدياً كبيراً من المنظمات وشركات المتصفحات إذا تم اعتماده بديلاً للـ UI التقليدي، لأن أساس استخدام المتصفح هو تجربة الـ Open Web وحرية الحركة.

Accessibility و WebMCP

هناك نقد Issue #91 يتساءل بشكل جوهري: "لماذا ننشئ نظامًا جديدًا ومستقلاً للـ AI طالما أن الـ Accessibility Tree توفر بالفعل خرائط برمجية للصفحة، ولماذا لا نطور شجرة الـ Accessibility بدلاً من اختراع WebMCP؟"

ملخص النقد

  • أولاً: لدينا بالفعل شجرة يبنيها الـ Browser تلقائياً، متكاملة ومتسقة مع الـ DOM، فيمكن استغلال هذه الميزة وربط الـ Agent بها بدلاً من بناء WebMCP بطرق وأدوات وأكواد مختلفة، والتي ستصبح مشكلة إذا تم تحديث الصفحة دون تحديث هذه الأدوات، على عكس الـ Accessibility Tree التي تتزامن تلقائياً.
  • ثانياً: إذا تم الاعتماد على تطوير الـ Agent للتفاعل مع الـ Accessibility Tree، فسيتم الاهتمام بكتابة أوسام ARIA، وسيخدم هذا طرفين في وقت واحد: أولاً ذوي الهمم، وثانياً استخدام الـ AI Agent. على العكس، الآن لدينا طريقة أخرى لوصف الصفحة وهي الـ WebMCP، اللي بتعمل بشكل متوازٍ، مع احتمال تراجع استخدام أحدهما في المستقبل.
  • ثالثاً: وصف عناصر الصفحة وتحويلها إلى بيانات منظمة بهذا الشكل (JSON Schema)، وكتابة مدخلاتها وتحديد أنواعها، ده عمل سيرفر بحت، مش شغل أو مسؤولية الـ UI.

الرد على النقد

للإجابة عن السؤال المباشر في النقد: نعم، هناك حالات استخدام لا تستطيع شجرة الـ Accessibility ولا الـ Backend APIs التعامل معها بفاعلية:

  • أولاً: سبب عدم الاعتماد على الـ Accessibility Tree
    • حدود الرؤية: لأنها بتعبّر عن الـ UI فقط (button, div) ومختصرة ع الـ values بتاعت العنصر نفسه (input value مثلاً)، مش بتتعامل مع حاجة زي canvas أو browser storage أو state جوه الكود نفسه (Redux/React).
    • طريقة التنفيذ: اه، ممكن من خلال الـ Accessibility Tree الـ Agent ينفذ عملية معينة، مثال إنه هيتعرف ويضغط ع الـ button الخاص بالـ payment. بس التنفيذ هيكون على شكل خطوات: يدوس، يستنى الصفحة ترجع، يدوّر على الـ button اللي بعده — وأي تغيير في الصفحة بيصعّب التسلسل أكتر. على عكس WebMCP اللي بينده function جاهزة زي checkoutCart() بتتنفّذ بشكل مباشر.
    • التكلفة مع الداتا الكبيرة: في تطبيق زي Google Sheets أو Figma، عشان الـ Agent يوصل لـ 500 خلية في الجدول هيقرا 500 عنصر DOM واحد واحد — بطء واستهلاك عالي للموارد. على عكس WebMCP اللي بيدي أداة زي queryGridData(filter) بترجّع الداتا مهيكلة من ذاكرة الجداول على طول، من غير ما تلمس الـ DOM.
  • ثانياً: أسباب عدم الاعتماد على الـ Backend
    • الداتا مش عند السيرفر أصلاً: الداتا في الصفحة عايشة في الـ current session وماتبعتتش للسيرفر، فأي API call هيشتغل على نسخة السيرفر المتسجّلة اللي مفيهاش التعديلات المحلية.
    • وحتى لو عايز توصّلها: هتحتاج sync مستمر مع كل قيمة جديدة بتتضاف في الفرونت: تقرا القيم اللحظية، تـ serialize، تبعت، والـ Agent يستنى الرد — كل ده عشان function الصفحة نفسها بتنفّذها بـ call واحد.

أفضل الممارسات

أ. الأمان والخصوصية
  • Self-XSS

    من خلال إسكربت بسيط في الـ console، يمكن تشغيل الـ function المسؤولة عن الأداة (tool) عدة مرات متتالية، مما يتسبب في تكلفة عالية، أو من ناحية أخرى ضغط كبير على السيرفر في وقت قصير (تجاوز الـ Rate Limit).

    من الحلول الموجودة لهذا النوع استخدام throttle أو debounce للتحكم في عدد مرات تنفيذ الأداة في الثانية الواحدة... إلخ.

    ولكن يظل الـ Backend هو خط الدفاع الأهم ضد هذا السلوك، بحظر أي طلبات تتجاوز الحد المسموح بها وإرسال 429 Too Many Requests.

  • Session Cleanup

    في تطبيقات الـ (SPA) لا يُعاد تحميل الصفحة عند تسجيل الخروج، لذلك تبقى الأدوات المسجلة نشطة ما لم تُلغَ.

    سيناريو محتمل: عند تسجيل خروج شخص ما من موقعك دون إلغاء تسجيل أدواته، قد تظل هذه الأدوات متاحة لحد هيستخدم المتصفح بعده، مما قد يتسبب بتسريب معلومات أو ظهور أدوات غير مناسبة له.

    لذلك اهتم بالـ clean up بعد كل جلسة، وألغِ تسجيل الأدوات باستخدام controller.abort().

ب. عدد الأدوات

تجنب إنشاء أدوات كثيرة دون حاجة؛ نعم لا يوجد حد معين لعدد الأدوات الممكن استخدامها، لكن كل أداة تُسجل (باسمها، وصفها، والـ Schema الخاصة بها) تستهلك من الـ Tokens الخاصة بالنموذج مما يزيد من زمن الاستجابة (Latency) والتكلفة.

ج. سيب الترتيب للـ Agent
متقولش للـ Agent يستخدم إيه الأول (مثل: "أولاً اطلب الاسم، ثم استدعِ الأداة الفلانية، وإذا نجحت استدعِ الأداة التانية")، لأن تقييد النموذج بخطوات متسلسلة يقلل مرونته، ويستنزف Tokens، ويتسبب في ارتباك وتوقف عن العمل عند تغير طريقة طلب المستخدم.
الأفضل: صياغة الوصف حول الوظيفة والمدخلات فقط، وترك ترتيب الأفعال للـ Agent (مثال: "تستعلم عن قائمة المنتجات المتاحة وتفلترها بناءً على السعر والمقاس المُدخلين").
د. نص بدل أرقام

استخدام قيم نصية ذات معنى واضحة بدل الأكواد أو الأرقام المبهمة:

❌ غير موصى به: shippingId: 1
✔️ موصى به: shippingMethod: "express"
هـ. سيب الحسابات للـ JavaScript

لا تجبر الـ Agent على إجراء الحسابات أو تحويل نطاقات التوقيت (Time Zones).

مثلاً: لو الـ function تحتاج تاريخ بصيغة (format) معينة، لا تطلب من الـ Agent تحويل الصيغة. اقبل التاريخ بالشكل المرسل كما هو، ثم حوّله انت بكود JavaScript بسيط قبل استخدامه. وإذا لم تُفهم الصيغة، أرجع رسالة واضحة تشرح الصيغ المقبولة.

و. خلّي الـ Agent يصلح نفسه

عند فشل الأداة (tool) أو تجاوز حدود الاستخدام (Rate Limit)، لا تُرجع خطأً مبهماً مثل Error فقط، بل أرجع رسالة تشرح المشكلة، حتى يتمكن الـ Agent من تصحيح مدخلاته أو عرضها على المستخدم.

async execute({ date }) {
  const res = await fetch("/api/flights?date=" + date);

  if (res.status === 429) {
    // ❌ return "Error 429";
    return "Too many searches. Wait a minute, or use the search form on the page.";
  }

  return JSON.stringify(await res.json());
}

الكود والاستخدام

1. التحقق من التوافر

if (document.modelContext) {
  console.log('WebMCP is supported');
} else {
  console.log('WebMCP is not supported in this browser');
}
تعمل على HTTPS أو localhost فقط.

2. استخدام الـ registerTool

await document.modelContext.registerTool({
  name: "add-todo",
  description: "Add a new item to the todo list",
  inputSchema: {
    type: "object",
    properties: { text: { type: "string" } }
  },
  execute({ text }) {
    addTodo(text); // استدعاء function موجودة مسبقاً
    return "Added: " + text; // يُرسل إلى الـ Agent
  }
});

3. الـ Annotations

التعليقات التوضيحية (Annotations) تُضاف عند تسجيل الأداة داخل registerTool، وهي تلميحات (hints) تساعد الـ Agent على التعامل مع الأدوات بشكل أدق.

annotations: {
  readOnlyHint: true,          // only reads, changes nothing
  consequentialHint: false,    // real-world or irreversible, e.g. a payment
  untrustedContentHint: false  // output may contain untrusted content
}

4. مشاركة الأدوات مع مواقع أخرى

لإتاحة الأداة لـ origin آخر، أضف exposedTo بعد تعريف الأداة.

{ exposedTo: ["https://trusted-partner.example"] }

ولتفعيل WebMCP داخل iframe من origin آخر، استخدم allow="tools".

<iframe src="https://widget.example" allow="tools"></iframe>

5. إلغاء تسجيل الأداة

مرر signal عند التسجيل، ثم استخدم abort() لإلغاء تسجيل الأداة.

const controller = new AbortController();
await document.modelContext.registerTool(tool, { signal: controller.signal });

controller.abort();

6. الطريقة الـ Declarative: تحويل form إلى أداة (tool)

بدون JavaScript: تضيف attributes على <form> موجود.

<form toolname="sign-up" tooldescription="Create a new account">

  <input name="firstName" toolparamdescription="The user's first name">
  <input name="lastName" toolparamdescription="The user's last name">
  <input type="email" name="email" toolparamdescription="The user's email address">
  <button>Sign up</button>

</form>

7. الـ Events

يمكنك التمييز إذا كان الـ submit event قد تم عن طريق الـ Agent باستخدام event.agentInvoked، واستخدام respondWith() لإرجاع نتيجة أو الرد عليه.

form.addEventListener('submit', (e) => {
  if (!e.agentInvoked) return;   // a normal submit by the user
  e.respondWith(searchCars(new FormData(form)));
});

استخدم toolchange لمعرفة متى تسجل أداة أو تلغى.

document.modelContext.addEventListener("toolchange", async () => {
  const currentTools = await document.modelContext.getTools();
  updateAgentToolRegistry(currentTools);
});

استخدم toolactivated لمعرفة متى يملأ الـ Agent الفورم وقبل إرسالها.

document.modelContext.addEventListener("toolactivated", () => {
  form.scrollIntoView();
});

استخدم toolcanceled لمعرفة متى يلغي الـ Agent الاستدعاء.

document.modelContext.addEventListener("toolcanceled", () => {
  form.reset();
});

التنسيق بـ CSS

وللتنسيق أثناء عمل الـ Agent: :tool-form-active للفورم، و :tool-submit-active لزر الإرسال فيها.

form:tool-form-active { outline: 2px solid orange; }
button:tool-submit-active { opacity: 0.6; }

المصادر: WebMCP explainer · Declarative API

الاستعداد للـ (Production)

من ناحية الـ User

  • توافر متصفح: Chrome 149 و Edge 150 أو أحدث، و Brave، وكمان تطبيق ChatGPT Desktop.
    أما Firefox و Safari فلا يدعمانه حالياً.
  • تفعيل WebMCP flag: اكتب chrome://flags/#enable-webmcp-testing في الـ URL وفعّله.
    ملحوظة: لو الموقع مسجّل في الـ Origin Trial، الأدوات هتشتغل من غير أي flags.
  • Agent يستدعي الأدوات: WebMCP بيعرض الأدوات بس، ومحتاج Agent داخل المتصفح يستخدمها.
    أسهل طريقة للتجربة حالياً هي إضافة Model Context Tool Inspector، عبارة عن side panel بيتعرض فيها الـ tools و chat لكتابة برومبت معين.
    وفيه إضافات تانية زي WebMCP Inspector.
  • من أدوات الـ AI التانية: تقدر تستخدم Chrome DevTools for Agents مع Claude Code أو Gemini CLI أو Cursor أو Codex.
    ملحوظة: تطبيق ChatGPT Desktop بيدعم WebMCP مباشرةً.

من ناحية الـ Developer

الـ Origin Trial بيخلي زوار موقعك يستخدموا WebMCP من غير ما يفعّلوا أي flags.

  • 1. سجّل الـ origin بتاع موقعك (مثل https://example.com) في صفحة الـ Origin Trial لـ Chrome و Edge.
    كل تسجيل هيديك token.
  • 2. ضيف الـ token في الـ <head> لكل صفحة فيها tools:
<meta http-equiv="origin-trial" content="YOUR_TOKEN">

المراجع (References)

المستودع الرسمي لبروتوكول WebMCP على GitHub:

https://github.com/webmachinelearning/webmcp

توثيق WebMCP من Chrome for Developers:

https://developer.chrome.com/docs/ai/webmcp

بحث وتحليل وكتابة: Sayeh
سبتمبر 2026