مثال على MCP Elicitation لدعم العملاء وإعداده في Claude Code

مثال عملي على MCP Elicitation لدعم العملاء: خادم TypeScript يوقف تصعيد التذكرة مؤقتًا، ويطلب من الوكيل الأولوية ومجال المنتج وحالة الانقطاع عبر نموذج، ثم يستأنف العمل. يتضمن إعداد Claude Code، ومعالجة الرفض والإلغاء، وقائمة فحص للاختبار.

مثال على MCP Elicitation لدعم العملاء وإعداده في Claude Code
Cristian Da Conceicao
مؤسس Picasso IA

يكتب وكيل الدعم "escalate SUP-1042" في Claude Code فتبدأ الأداة عملها. ثم تتوقف، لأن أحدًا لم يخبرها بالأولوية، ولا بمجال المنتج، ولا بما إذا كان العملاء محرومين من الوصول. الإعداد الضعيف يخمّن ويستدعي الفريق الخطأ. أما الإعداد الأفضل فيسأل. هذا السؤال، الذي يُرسَل من الخادم إلى الشخص أمام الطرفية، هو ما يفعله MCP Elicitation. يعرض هذا المثال على MCP Elicitation لمكتب دعم العملاء الحلقة كاملة: كود الخادم، ومخطط النموذج، وإعداد Claude Code، وما يجب فعله عندما يقول الوكيل "لا".

كل ما يلي موجّه إلى النسخة 2025-11-25 من Model Context Protocol وإلى TypeScript SDK. الخادم صغير بما يكفي لقراءته في جلسة واحدة، وكل جزء فيه يقابل قاعدة في المواصفات.

ما الذي يفعله MCP Elicitation فعليًا

عادةً يستدعي عميل MCP أداة، ويعمل الخادم، ثم تعود النتيجة. يضيف Elicitation خطوة واحدة في المنتصف. أثناء تشغيل الأداة، يرسل الخادم طلب elicitation/create إلى العميل. يعرض العميل على الشخص مربع حوار، ويجمع الإجابة ويعيدها. ثم تكمل الأداة عملها ببيانات حقيقية بدلًا من التخمين.

أيدٍ تمسك استمارة ورقية وقلمًا حبريًا فوق مكتب من خشب البلوط

هذا يجعل Elicitation أداة من نوع human in the loop. يبقى الخادم مسؤولًا عمّا يحتاجه. ويبقى العميل مسؤولًا عن كيف يظهر السؤال، وأي الخوادم يُسمح لها بالسؤال، وما إذا كان الشخص يملك حق الرفض.

وضع النموذج ووضع URL

تحدد المواصفات وضعين:

  • وضع النموذج يجمع بيانات منظمة داخل قناة الاتصال نفسها. يرسل الخادم رسالة قصيرة مع requestedSchema، ويعرض العميل نموذجًا مبنيًا عليه.
  • وضع URL يوجّه الشخص إلى عنوان خارجي لأي شيء حساس، مثل تسجيل الدخول أو الدفع. لا تمرّ البيانات عبر العميل أبدًا. وقد قدّمت نسخة 2025-11-25 هذا الوضع.

صُممت مخططات النماذج لتكون صغيرة عمدًا. فهي كائنات مسطّحة تحتوي على خصائص بدائية فقط:

نوع المخططالخيارات المفيدةالاستخدام المعتاد
string (نص)minLength وmaxLength وpattern وformat (email وuri وdate وdate-time)البريد الإلكتروني للتواصل، ملاحظة قصيرة
number أو integer (رقم أو عدد صحيح)minimum وmaximum وdefaultعدد العملاء المتأثرين
boolean (قيمة منطقية)default"هل هذا انقطاع في الخدمة؟"
enum أحادي الاختيارenum، أو oneOf مع العناوينالأولوية، مجال المنتج
enum متعدد الاختيارمصفوفة مع minItems وmaxItemsالمنصات المتأثرة

تُستبعد الكائنات المتداخلة ومصفوفات الكائنات عمدًا، حتى يتمكن أي عميل من رسم النموذج دون تخمين.

ثلاث إجابات ممكنة

يحمل كل رد action:

  1. accept: أرسل الشخص النموذج، وcontent يحتوي على القيم.
  2. decline: قال الشخص "لا" عن قصد.
  3. cancel: أغلق الشخص مربع الحوار دون أن يختار شيئًا.

يجب أن يتعامل خادمك مع الحالات الثلاث كنتائج طبيعية. أغلب أخطاء Elicitation تنشأ من معالجة الحالة الأولى وحدها.

سيناريو دعم العملاء

تخيّل فريق دعم لديه مكتب مساعدة مليء بالتذاكر، ومناوبة صغيرة للطوارئ. يعمل الوكلاء داخل Claude Code، ويمنح خادم MCP اسمه support-desk النموذجَ إجراء كتابة واحدًا: escalate_ticket. يأخذ معرّف التذكرة ويسلّم الحالة إلى المهندسين المختصين.

وكيل دعم عملاء يرتدي سماعة رأس أمام مكتب عليه شاشتان

لماذا يفشل التخمين هنا

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

يُسلّم Elicitation القرار إلى الشخص الذي يملكه. يوفّر النموذج معرّف التذكرة، ويوفّر الإنسان الحكم.

الحقول التي يطلبها الخادم

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

الحقلالنوعسبب وجوده
priorityتعداد أحادي الاختيار (enum)يوجّه الطلب إلى قائمة المناوبة الصحيحة
areaتعداد أحادي الاختيار (enum)يحدد الفريق المسؤول
affectedCustomersinteger، من 1 إلى 10000يفصل المستخدم الواحد عن حادثة واسعة النطاق
customerEmailstring، بصيغة emailيتيح للمهندس المتابعة
outagebooleanيفتح قناة الحادثة

منظر علوي لمكتب فيه حاسوب محمول وأسهم دفترية وملاحظات لاصقة مرتبة بالتسلسل

فقط priority وarea مطلوبان. الحقول الأخرى لها قيم افتراضية، فيستطيع وكيل في عجلة من أمره أن يقبل ويكمل.

💡 اجعل النموذج قصيرًا. كل حقل إضافي سبب يدفع الوكيل إلى الضغط على إلغاء.

بناء خادم الدعم

الخادم ملف TypeScript واحد، ونقل stdio، واعتماديتان صغيرتان.

مطور برمجيات يكتب على حاسوب محمول في مكتب هادئ بطابق علوي

ملفات المشروع والاعتماديات

mkdir support-desk-mcp && cd support-desk-mcp
npm init -y
npm pkg set type=module
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node
mkdir src

ضبط type على module يسمح للملف باستخدام await على المستوى الأعلى واستيرادات ES.

أداة التصعيد

احفظ هذا الملف باسم src/server.ts:

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

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

const EscalationForm = z.object({
  priority: z.enum(["p1", "p2", "p3"]),
  area: z.enum(["billing", "login", "api", "mobile-app"]),
  affectedCustomers: z.number().int().min(1).max(10000).default(1),
  customerEmail: z.string().email().optional(),
  outage: z.boolean().default(false),
});

// Stub: swap in your helpdesk API call.
async function createEscalation(ticketId: string, data: z.infer<typeof EscalationForm>) {
  return `ESC-${Date.now().toString(36).toUpperCase()}`;
}

const reply = (text: string, isError = false) => ({
  content: [{ type: "text" as const, text }],
  isError,
});

server.registerTool(
  "escalate_ticket",
  {
    description: "Escalate a support ticket to the on-call team. Asks the agent for missing details.",
    inputSchema: { ticketId: z.string().describe("Ticket ID, for example SUP-1042") },
  },
  async ({ ticketId }) => {
    if (!server.server.getClientCapabilities()?.elicitation) {
      return reply("This client cannot show forms. Ask the agent for priority and area, then retry.", true);
    }

    const answer = await server.server.elicitInput({
      message: `Ticket ${ticketId} needs a few details before it reaches the on-call team.`,
      requestedSchema: {
        type: "object",
        properties: {
          priority: {
            type: "string",
            title: "Priority",
            oneOf: [
              { const: "p1", title: "P1 Service down" },
              { const: "p2", title: "P2 Major feature broken" },
              { const: "p3", title: "P3 Minor issue" },
            ],
          },
          area: {
            type: "string",
            title: "Product area",
            enum: ["billing", "login", "api", "mobile-app"],
          },
          affectedCustomers: {
            type: "integer",
            title: "Customers affected",
            minimum: 1,
            maximum: 10000,
            default: 1,
          },
          customerEmail: { type: "string", format: "email", title: "Customer email" },
          outage: { type: "boolean", title: "Is this an outage?", default: false },
        },
        required: ["priority", "area"],
      },
    });

    if (answer.action === "decline") {
      return reply(`The agent declined to escalate ${ticketId}. The ticket is unchanged.`);
    }
    if (answer.action === "cancel") {
      return reply(`Escalation of ${ticketId} was cancelled. Nothing was changed.`);
    }

    const parsed = EscalationForm.safeParse(answer.content);
    if (!parsed.success) {
      return reply("The form answers were invalid. Ask again.", true);
    }

    const escalationId = await createEscalation(ticketId, parsed.data);
    return reply(`Escalated ${ticketId} as ${parsed.data.priority} in ${parsed.data.area}. Reference ${escalationId}.`);
  }
);

await server.connect(new StdioServerTransport());

لاحظ أن mode غير موجود في استدعاء elicitInput. وضع النموذج هو الافتراضي، وهذا يُبقي الطلب مقروءًا للعملاء الأقدم.

تحقق من قدرات العميل أولًا

الأسطر الأولى من المعالج أهم مما تبدو عليه. يعلن العميل الذي يدعم Elicitation عن قدرة elicitation أثناء التهيئة. الكائن elicitation الفارغ يعني وضع النموذج فقط، ولا يجوز للخادم أبدًا أن يرسل وضعًا لم يعلن العميل عنه.

إذا كانت القدرة غير موجودة، يعيد الخادم رسالة خطأ نصية بسيطة بدلًا من أن يتعلق. يقرأ النموذج تلك الرسالة ويسأل الوكيل في الدردشة. الأداة التي تفشل بلباقة أفضل من أداة تتجمد.

💡 في خادم stdio، لا تطبع أبدًا على الإخراج القياسي. أسطر console.log الضالة تُفسد تدفق البروتوكول. أرسل مخرجات التصحيح عبر console.error.

إعداد Claude Code خطوة بخطوة

بعد كتابة الخادم، يحتاج Claude Code إلى معرفة أنه موجود.

أيدٍ تكتب على حاسوب محمول ونافذة طرفية مفتوحة على الشاشة

تسجيل الخادم

من أي مجلد، أضفه باستخدام CLI. كل ما يأتي بعد الشرطتين المزدوجتين هو الأمر الذي يشغّل الخادم:

claude mcp add support-desk -- npx -y tsx /absolute/path/to/support-desk-mcp/src/server.ts

لمشاركة الإعداد مع زملائك، أضف --scope project. عندها يكتب Claude Code ملف .mcp.json في جذر المستودع:

{
  "mcpServers": {
    "support-desk": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "tsx", "/absolute/path/to/support-desk-mcp/src/server.ts"]
    }
  }
}
النطاقيُحمَّل فيمشترك مع الفريقيُخزَّن في
local (الافتراضي)المشروع الحالي فقطلا~/.claude.json
projectالمشروع الحالي فقطنعم، عبر التحكم في الإصدارات.mcp.json
userجميع مشاريعكلا~/.claude.json

💡 على Windows الأصلي، غلّف المشغّل: claude mcp add support-desk -- cmd /c npx -y tsx C:\path\to\src\server.ts.

تأكيد الاتصال

فحصان يخبرانك أن الخادم يعمل:

claude --version
claude mcp list

داخل الجلسة، يفتح /mcp لوحة الخادم مع حالة الاتصال. يجب أن ترى support-desk مدرجًا كمتصل.

إذا توقف خادم عن الاتصال بعد تحديث، فراجع سجل التغييرات في Claude Code. تنص ملاحظات الإصدار 2.1.287، التي أضافت روابط URL من الخوادم وفق بروتوكول 2025-11-25، على إضافة "bareElicitationCapability": true إلى إدخال الإعداد الخاص بذلك الخادم عندما لم يعد يتصل.

تشغيل تدفق التصعيد

ابدأ جلسة في مشروعك واكتب طلبًا بسيطًا:

Escalate ticket SUP-1042 using the support-desk tool.

يستدعي Claude الأداة mcp__support-desk__escalate_ticket. تتوقف الأداة مؤقتًا، ويعرض Claude Code النموذج، ويملأ الوكيل الأولوية والمجال وعدد العملاء المتأثرين والبريد الإلكتروني وعلامة الانقطاع.

شاشة حاسوب محمول تعرض مربع حوار نموذجًا بسيطًا وإصبع فوق لوحة التتبع

بعد أن يرسل الوكيل النموذج، تستأنف الأداة وتعيد شيئًا مثل Escalated SUP-1042 as p1 in login. Reference ESC-LQ3F9A2. يمكن للنموذج أن ينقل هذا المرجع مباشرة إلى ردّه.

يوفّر Claude Code أيضًا خطافات Elicitation وElicitationResult، تُطابَق مع اسم الخادم. يمكن لسكربت أن يجيب على نموذج معروف تلقائيًا، أو أن يسجّل كل رد قبل وصوله إلى الخادم. استخدم ذلك في النماذج منخفضة المخاطر ضمن الأتمتة، وأبقِ البشر أمام أي شيء يمس العملاء.

معالجة الرفض والإلغاء والمدخلات الخاطئة

عروض المسار السعيد تخفي الجزء الذي يحدد ما إذا كان الوكلاء سيثقون بالأداة. الناس يغلقون مربعات الحوار، ويغيّرون رأيهم، ويدخلون قيمًا خاطئة.

إصبع يحوم فوق زر Escape على حاسوب محمول

ما الذي ينبغي أن يُطلقه كل إجراء

الإجراءما فعله الشخصما ينبغي أن تفعله الأداة
acceptأرسل النموذجتحقق مرة أخرى، ثم أنشئ التصعيد
declineقال "لا" عن قصدلا تمسّ التذكرة، وأبلغ عن ذلك، واعرض مسارًا يدويًا
cancelأغلق مربع الحوارلا تغيّر شيئًا، واسمح بإعادة المحاولة لاحقًا

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

أعد نتيجة isError عند وجود مدخلات خاطئة بدلًا من رمي خطأ. يرى النموذج الرسالة ويستطيع أن يطلب من الوكيل تشغيل الأداة مرة أخرى.

أخطاء تكسر Elicitation

تأتي معظم الإخفاقات من قائمة قصيرة من العادات.

البيانات الحساسة في النماذج

قفل نحاسي على باب خشبي أخضر متآكل

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

الاسم أو عنوان البريد الإلكتروني مختلف. يجوز للخادم أن يطلبهما، ويستطيع الشخص مراجعتهما ورفضهما.

المخططات المتداخلة

requestedSchema يحتوي على كائن متداخل أو قائمة من الكائنات سيُرفض أو سيُعرض بشكل سيئ. سطّحه. إذا احتجت إلى قائمة بالبنود، فشغّل عدة عمليات Elicitation صغيرة، أو استخدم enum متعدد الاختيار.

عادات أخرى تسبب المشاكل:

  • معاملة cancel كأنها decline، فيبدو مربع الحوار المغلق كأنه رفض.
  • الثقة بهوية كُتبت في نموذج. حدّد هوية المستخدمين عبر التفويض، لا عبر حقل نصي.
  • طلب التفاصيل نفسها مرتين في الجلسة الواحدة.
  • نسيان أن الخادم البعيد يجب أن يربط حالته بالمستخدم، لا بمعرّف الجلسة فقط.

قائمة فحص قصيرة للاختبار

مهندس ضمان الجودة يحمل لوحة قائمة فحص وأمامه حاسوبان محموليان

شغّل هذه الحالات الخمس قبل أن تلمس التذاكر الحقيقية الأداة:

  • قبول مع القيم الافتراضية فقط، وتأكد أن affectedCustomers يصبح 1.
  • قبول ببريد إلكتروني فيه خطأ مطبعي، وتأكد أن الخادم يرفضه.
  • رفض، وتأكد أن التذكرة لم تتغير.
  • إلغاء بزر Escape، وتأكد أنه لم يُكتب شيء.
  • الاتصال من عميل لا يدعم Elicitation، وتأكد من ظهور الرسالة النصية الاحتياطية.

يمكنك أيضًا تشغيل الخادم تحت MCP Inspector من مجلد المشروع باستخدام npx @modelcontextprotocol/inspector npx tsx src/server.ts لمراقبة رسائل elicitation/create الخام وهي تمر.

صياغة الردود باستخدام Claude Sonnet 5

بعد أن يعيد التصعيد مرجعًا، ما زال على الوكيل أن يقدّم جوابًا للعميل. يتولى Claude Sonnet 5 على PicassoIA خطوة الصياغة، ويقرأ لقطات الشاشة أيضًا، وهذا يفيد عندما يرفق العميل صورة لخطأ ما.

  1. افتح صفحة Claude Sonnet 5 والصق ملخص التذكرة مع مرجع التصعيد في Prompt.
  2. اضبط System Prompt مرة واحدة: "You write short, calm support replies. Never promise a fix time."
  3. أبقِ Effort على low للمسودات السريعة. ارفعه إلى medium أو high عندما تحتاج التذكرة إلى استدلال حقيقي. وفقًا لصفحة النموذج، يعطّل low التفكير للحصول على أسرع الردود وأرخصها.
  4. خفّض Max Tokens من القيمة الافتراضية 8192 إلى نحو 600 حتى تبقى الردود قصيرة.
  5. أرفق لقطة شاشة في Image إذا أرسلها العميل. القيمة الافتراضية للحقل Max Image Resolution هي 0.5 ميغابكسل، وهي كافية لمربع حوار خطأ.
المعاملالقيمة الافتراضيةنصيحة لردود الدعم
Effortlowارفعه للأخطاء المعقدة فقط
Max Tokens8192اضبطه قرب 600
System Promptفارغحدّد النبرة والحدود مرة واحدة
Max Image Resolution0.5 MPأبقه كما هو للقطات الشاشة

للاستدلال الأصعب، يُدرج Claude Opus 4.7 ضمن المجموعة نفسها. ابدأ باستخدام Sonnet 5 ولا تنتقل إلى الأعلى إلا عندما لا تصيب المسودة الهدف.

أنشئ صورك الخاصة مع Picasso IA

توثيق الدعم ومقالات مركز المساعدة تُقرأ بشكل أفضل مع صور حقيقية. مشاهد المكتب نفسها التي رأيتها أعلاه، كسماعة رأس على طاولة أو لوحة مشبك ورق تحت ضوء النافذة، تحتاج إلى أمر نصي واحد لإنشائها.

جرّب PicassoIA Image للمحاولة الأولى السريعة، أو Flux 2 Pro عندما تريد نسيجًا أدق. أمر نصي يعمل جيدًا:

A support engineer at a wooden desk, 35mm lens, soft window light from the left, shallow depth of field, Kodak Portra 400 film grain, no text.

اختر نموذجًا، والصق الأمر النصي، وغيّر تفصيلًا واحدًا في كل تشغيل، ثم قارن النتائج. عشر دقائق من التجريب ستعلمك عن صياغة الأوامر النصية أكثر من أي قائمة قواعد. افتح Picasso IA، وأنشئ صورة الرأس الأولى لك، وضعها في مقال الدعم التالي.

شارك هذا المقال

اختر لغتك

مقالات ذات صلة