MCP एलिसिटेशन उदाहरण: क्लाइंट सपोर्ट और Claude Code सेटअप
क्लाइंट सपोर्ट के लिए एक काम करने वाला MCP एलिसिटेशन उदाहरण: एक TypeScript सर्वर जो टिकट एस्केलेशन को रोकता है, फ़ॉर्म के ज़रिए एजेंट से प्राथमिकता, प्रोडक्ट एरिया और आउटेज की स्थिति पूछता है, फिर काम आगे बढ़ाता है। इसमें Claude Code सेटअप, अस्वीकार और रद्द करने को संभालना, और एक टेस्ट चेकलिस्ट शामिल है।
आपका सपोर्ट एजेंट Claude Code में "escalate SUP-1042" लिखता है और टूल चलना शुरू करता है। फिर वह रुक जाता है, क्योंकि किसी ने उसे प्राथमिकता, प्रोडक्ट एरिया, या यह नहीं बताया कि ग्राहक लॉक आउट हैं या नहीं। एक कमज़ोर सेटअप अंदाज़ा लगाता है और गलत टीम को पेज करता है। एक बेहतर सेटअप पूछता है। यही सवाल सर्वर से वापस टर्मिनल पर बैठे व्यक्ति तक जाता है, और MCP एलिसिटेशन यही करता है। क्लाइंट सपोर्ट डेस्क के लिए यह MCP एलिसिटेशन उदाहरण पूरा लूप दिखाता है: सर्वर कोड, फ़ॉर्म स्कीमा, Claude Code सेटअप, और जब एजेंट मना कर दे तो क्या करना है।
नीचे दी गई हर बात Model Context Protocol के 2025-11-25 संस्करण और TypeScript SDK पर आधारित है। सर्वर इतना छोटा है कि एक बैठक में पढ़ा जा सकता है, और इसका हर हिस्सा स्पेक के किसी नियम से जुड़ता है।
MCP एलिसिटेशन असल में क्या करता है
आम तौर पर MCP क्लाइंट एक टूल कॉल करता है, सर्वर काम करता है, और परिणाम वापस आता है। एलिसिटेशन बीच में एक कदम जोड़ता है। टूल चलते समय सर्वर क्लाइंट को एक elicitation/create अनुरोध भेजता है। क्लाइंट व्यक्ति को एक डायलॉग दिखाता है, जवाब इकट्ठा करता है और उसे लौटाता है। फिर टूल अंदाज़े की जगह असली डेटा के साथ आगे बढ़ता है।
इस तरह एलिसिटेशन एक 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
"क्या यह आउटेज है?"
single-select enum
enum, या titles वाला oneOf
प्राथमिकता, प्रोडक्ट एरिया
multi-select enum
minItems और maxItems वाला array
प्रभावित प्लेटफ़ॉर्म
नेस्टेड ऑब्जेक्ट और ऑब्जेक्ट के array जानबूझकर शामिल नहीं किए गए हैं, ताकि कोई भी क्लाइंट बिना अंदाज़े के फ़ॉर्म बना सके।
तीन संभावित उत्तर
हर जवाब में एक action होता है:
accept: व्यक्ति ने फ़ॉर्म सबमिट किया, और content में मान हैं।
decline: व्यक्ति ने जानबूझकर मना किया।
cancel: व्यक्ति ने बिना कुछ चुने डायलॉग बंद कर दिया।
आपके सर्वर को तीनों को सामान्य परिणाम मानकर चलना होगा। ज़्यादातर एलिसिटेशन की गड़बड़ियाँ केवल पहले वाले को हैंडल करने से आती हैं।
क्लाइंट सपोर्ट परिदृश्य
एक सपोर्ट टीम की कल्पना करें जिसके हेल्पडेस्क में टिकटों का ढेर है और एक छोटा ऑन-कॉल रोस्टर है। एजेंट Claude Code के अंदर काम करते हैं, और support-desk नाम का एक MCP सर्वर मॉडल को एक राइट एक्शन देता है: escalate_ticket। यह एक टिकट ID लेता है और केस को सही इंजीनियरों को सौंप देता है।
यहाँ अंदाज़ा क्यों विफल होता है
मॉडल टिकट पढ़कर प्राथमिकता का अंदाज़ा लगा सकता है। वह अक्सर सही होगा। जब गलत होगा, तो बिलिंग का सवाल इंसिडेंट चैनल में पहुँच जाएगा, या लॉगिन आउटेज रात भर धीमी कतार में पड़ा रहेगा। आप टूल का इनपुट स्कीमा चौड़ा करके उम्मीद कर सकते हैं कि मॉडल हर फ़ील्ड सही भरे, लेकिन गढ़े हुए मानों वाली टूल कॉल असली मानों वाली कॉल जैसी ही दिखती है।
एलिसिटेशन फ़ैसला उस व्यक्ति के पास ले जाता है जो उसका मालिक है। मॉडल टिकट ID देता है। इंसान विवेक देता है।
सर्वर किन फ़ील्ड्स के बारे में पूछता है
पाँच फ़ील्ड काफ़ी हैं। इससे ज़्यादा होने पर एजेंट डायलॉग को खारिज करने लगते हैं।
फ़ील्ड
प्रकार
यह क्यों है
priority
single-select enum
सही on-call कतार में भेजता है
area
single-select enum
ज़िम्मेदार टीम चुनता है
affectedCustomers
integer, 1 से 10000
एक यूज़र को बड़े इंसिडेंट से अलग करता है
customerEmail
string, format email
इंजीनियर को फ़ॉलो-अप करने देता है
outage
boolean
इंसिडेंट चैनल खोलता है
केवल priority और area ज़रूरी हैं। बाकी के डिफ़ॉल्ट मान हैं, इसलिए जल्दी में रहने वाला एजेंट स्वीकार करके आगे बढ़ सकता है।
💡 फ़ॉर्म छोटा रखें। हर अतिरिक्त फ़ील्ड एजेंट के cancel दबाने का एक कारण बनता है।
सपोर्ट सर्वर बनाएँ
सर्वर एक TypeScript फ़ाइल, एक stdio ट्रांसपोर्ट और दो छोटी डिपेंडेंसी है।
type को module पर सेट करने से फ़ाइल में टॉप-लेवल await और ES imports इस्तेमाल हो सकते हैं।
एस्केलेशन टूल
इसे 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());
ध्यान दें कि elicitInput कॉल में mode नहीं है। फ़ॉर्म मोड डिफ़ॉल्ट है, जिससे अनुरोध पुराने क्लाइंट्स के लिए भी पढ़ने योग्य रहता है।
पहले क्लाइंट क्षमताएँ जाँचें
हैंडलर की पहली कुछ लाइनें दिखने से ज़्यादा मायने रखती हैं। जो क्लाइंट एलिसिटेशन सपोर्ट करता है, वह इनिशियलाइज़ेशन के दौरान elicitation क्षमता घोषित करता है। एक खाली elicitation ऑब्जेक्ट को केवल फ़ॉर्म मोड माना जाता है, और सर्वर कभी ऐसा मोड नहीं भेजे जिसे क्लाइंट ने घोषित न किया हो।
अगर क्षमता नहीं है, तो सर्वर अटकने के बजाय एक सादा टेक्स्ट एरर लौटाता है। मॉडल वह संदेश पढ़कर चैट में एजेंट से पूछ लेता है। जो टूल सलीके से विफल होता है, वह उस टूल से बेहतर है जो जम जाता है।
💡 stdio सर्वर में standard output पर कभी प्रिंट न करें। भटकी हुई 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 फ़ाइल लिखता है:
💡 नेटिव Windows पर, launcher को रैप करें: claude mcp add support-desk -- cmd /c npx -y tsx C:\path\to\src\server.ts।
कनेक्शन की पुष्टि करें
दो जाँचें बताती हैं कि सर्वर चालू है:
claude --version
claude mcp list
सेशन के अंदर /mcp कनेक्शन स्थिति के साथ सर्वर पैनल खोलता है। आपको support-desk connected के रूप में दिखना चाहिए।
अगर अपडेट के बाद सर्वर कनेक्ट होना बंद कर दे, तो Claude Code का changelog देखें। 2.1.287 के नोट्स, जिनमें 2025-11-25 प्रोटोकॉल वाले सर्वरों से URL prompts जोड़े गए, कहते हैं कि जब सर्वर कनेक्ट न हो तो उस सर्वर की config एंट्री में "bareElicitationCapability": true जोड़ें।
एस्केलेशन फ़्लो चलाएँ
अपने प्रोजेक्ट में एक सेशन शुरू करें और एक सादा अनुरोध टाइप करें:
Escalate ticket SUP-1042 using the support-desk tool.
Claude mcp__support-desk__escalate_ticket कॉल करता है। टूल रुकता है, Claude Code फ़ॉर्म दिखाता है, और एजेंट priority, area, प्रभावित ग्राहक, ईमेल और outage flag भरता है।
एजेंट सबमिट करने के बाद टूल आगे बढ़ता है और कुछ ऐसा लौटाता है जैसे Escalated SUP-1042 as p1 in login. Reference ESC-LQ3F9A2.। मॉडल इस रेफ़रेंस को सीधे अपने जवाब में उद्धृत कर सकता है।
Claude Code सर्वर के नाम के आधार पर मैच होने वाले Elicitation और ElicitationResult hooks भी देता है। एक स्क्रिप्ट किसी ज्ञात फ़ॉर्म का जवाब अपने-आप दे सकती है, या सर्वर तक पहुँचने से पहले हर जवाब लॉग कर सकती है। इसे ऑटोमेशन में कम जोखिम वाले फ़ॉर्म के लिए इस्तेमाल करें, और ग्राहकों पर असर डालने वाली किसी भी चीज़ पर इंसानों की निगरानी रखें।
Decline, Cancel और गलत इनपुट को संभालें
हैप्पी-पाथ डेमो वह हिस्सा छिपा देते हैं जो तय करता है कि एजेंट टूल पर भरोसा करेंगे या नहीं। लोग डायलॉग बंद करते हैं, मन बदलते हैं और मानों में गलतियाँ करते हैं।
हर क्रिया पर टूल को क्या करना चाहिए
क्रिया
व्यक्ति ने क्या किया
टूल को क्या करना चाहिए
accept
फ़ॉर्म सबमिट किया
दोबारा जाँचें, फिर एस्केलेशन बनाएँ
decline
जानबूझकर मना किया
टिकट को न छुएँ, रिपोर्ट करें, मैन्युअल रास्ता दें
cancel
डायलॉग बंद किया
कुछ न बदलें, बाद में फिर से कोशिश की अनुमति दें
सर्वर में safeParse कॉल पर ध्यान दें। क्लाइंट्स को जवाबों को स्कीमा के आधार पर जाँचना चाहिए, और सर्वर को यह दोबारा करना चाहिए। डिफ़ॉल्ट और फ़ॉर्मेट इंटरफ़ेस के लिए संकेत भर हैं, वे इस बात की गारंटी नहीं कि जो डेटा आएगा वह सही होगा।
गलत इनपुट पर throw करने के बजाय isError परिणाम लौटाएँ। मॉडल संदेश देखता है और एजेंट से टूल फिर से चलाने को कह सकता है।
वे गलतियाँ जो एलिसिटेशन तोड़ती हैं
ज़्यादातर विफलताएँ कुछ आदतों से आती हैं।
फ़ॉर्म में संवेदनशील डेटा
स्पेक साफ़ कहता है: सर्वरों को फ़ॉर्म मोड से पासवर्ड, API tokens या पेमेंट क्रेडेंशियल कभी नहीं माँगने चाहिए। फ़ॉर्म के जवाब क्लाइंट से होकर गुज़रते हैं, इसलिए वे logs और transcripts में पहुँच सकते हैं। कोई भी गुप्त चीज़ URL मोड में जानी चाहिए, जहाँ व्यक्ति एक ऐसे पेज पर टाइप करता है जिसे क्लाइंट पढ़ नहीं सकता।
नाम या ईमेल पता अलग है। सर्वर इन्हें माँग सकता है, और व्यक्ति उन्हें जाँचकर मना कर सकता है।
नेस्टेड स्कीमा
नेस्टेड ऑब्जेक्ट या ऑब्जेक्ट की सूची वाला requestedSchema अस्वीकार होगा या खराब तरीके से रेंडर होगा। इसे फ़्लैट करें। अगर line items की सूची चाहिए, तो कई छोटे elicitations चलाएँ या multi-select enum स्वीकार करें।
ऐसी और आदतें भी परेशानी पैदा करती हैं:
cancel को decline की तरह मानना, जिससे बंद डायलॉग इनकार जैसा दिखे।
फ़ॉर्म में टाइप की गई पहचान पर भरोसा करना। यूज़र की पहचान authorization से करें, टेक्स्ट फ़ील्ड से नहीं।
एक ही सेशन में एक ही विवरण दो बार माँगना।
यह भूल जाना कि रिमोट सर्वर को अपनी स्थिति केवल सेशन ID से नहीं, बल्कि यूज़र से जोड़नी होगी।
एक छोटी टेस्ट चेकलिस्ट
असली टिकट टूल को छूने से पहले ये पाँच केस चलाएँ:
केवल डिफ़ॉल्ट मानों के साथ accept करें, और पुष्टि करें कि affectedCustomers 1 बनता है।
टाइपो वाले ईमेल के साथ accept करें, और पुष्टि करें कि सर्वर उसे अस्वीकार करता है।
decline करें, और पुष्टि करें कि टिकट नहीं बदला।
Escape बटन से cancel करें, और पुष्टि करें कि कुछ नहीं लिखा गया।
बिना एलिसिटेशन वाले क्लाइंट से कनेक्ट करें, और पुष्टि करें कि सादा टेक्स्ट फ़ॉलबैक दिखता है।
आप प्रोजेक्ट फ़ोल्डर से npx @modelcontextprotocol/inspector npx tsx src/server.ts के साथ सर्वर को MCP Inspector के अंतर्गत भी चला सकते हैं, ताकि कच्चे elicitation/create संदेश गुज़रते हुए दिखें।
Claude Sonnet 5 के साथ जवाबों का ड्राफ़्ट बनाएँ
एस्केलेशन से रेफ़रेंस मिलने के बाद भी एजेंट को ग्राहक को जवाब देना होता है। PicassoIA पर Claude Sonnet 5 वह ड्राफ़्टिंग कदम संभालता है, और यह स्क्रीनशॉट भी पढ़ता है, जो तब काम आता है जब ग्राहक कोई एरर इमेज भेजे।
Claude Sonnet 5 पेज खोलें और टिकट का सार तथा एस्केलेशन रेफ़रेंस Prompt में चिपकाएँ।
System Prompt एक बार सेट करें: "आप छोटे, शांत सपोर्ट जवाब लिखते हैं। कभी भी समाधान का समय देने का वादा न करें।"
त्वरित ड्राफ़्ट के लिए Effort को low पर रखें। जब टिकट को सच में रीज़निंग चाहिए, तो इसे medium या high तक बढ़ाएँ। मॉडल पेज के अनुसार, low सबसे तेज़ और सस्ते जवाबों के लिए थिंकिंग बंद कर देता है।
Max Tokens को 8192 डिफ़ॉल्ट से घटाकर लगभग 600 करें, ताकि जवाब छोटे रहें।
अगर ग्राहक ने स्क्रीनशॉट भेजा है, तो उसे Image में अटैच करें। Max Image Resolution का डिफ़ॉल्ट 0.5 megapixels है, जो एरर डायलॉग के लिए काफ़ी है।
पैरामीटर
डिफ़ॉल्ट
सपोर्ट जवाबों के लिए सुझाव
Effort
low
केवल कठिन बग के लिए बढ़ाएँ
Max Tokens
8192
लगभग 600 रखें
System Prompt
खाली
टोन और सीमाएँ एक बार तय करें
Max Image Resolution
0.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 खोलें, अपनी पहली हेडर इमेज बनाएँ, और उसे अपने अगले सपोर्ट लेख में लगाएँ।