अपना पहला MCP सर्वर बनाना
Model Context Protocol (MCP) AI इकोसिस्टम में एक यूनिवर्सल एडेप्टर के सबसे करीब है। यह परिभाषित करता है कि AI मॉडल टूल कैसे खोजते और कॉल करते हैं, और वे टूल संरचित परिणाम कैसे लौटाते हैं। एक बार आपका MCP सर्वर चलने लगे, कोई भी संगत क्लाइंट — Claude, Claude Code, या MCP बोलने वाला कोई भी एजेंट फ्रेमवर्क — अतिरिक्त इंटीग्रेशन कोड के बिना इसका उपयोग कर सकता है।
यह गाइड एक वास्तविक MCP सर्वर को शून्य से बनाने की प्रक्रिया को समझाती है। कोई खिलौना उदाहरण नहीं, बल्कि एक ऐसा पैटर्न जिसे आप प्रोडक्शन उपयोग के लिए बढ़ा सकते हैं।
MCP वास्तव में क्या है
MCP एक JSON-RPC 2.0 प्रोटोकॉल है जो stdio पर चलता है (रिमोट सर्वर के लिए HTTP+SSE भी)। क्लाइंट और सर्वर संदेश प्रकारों का एक छोटा सेट आदान-प्रदान करते हैं:
tools/list— क्लाइंट पूछता है कि कौन से टूल उपलब्ध हैंtools/call— क्लाइंट तर्कों के साथ एक टूल को इनवोक करता हैresources/list/resources/read— क्लाइंट फ़ाइलें, डेटाबेस, या सर्वर द्वारा उजागर किया गया कोई भी संदर्भ पढ़ता है
सर्वर अपने टूल पहले से घोषित करता है, प्रत्येक टूल के इनपुट के लिए JSON Schema के साथ। क्लाइंट इस Schema का उपयोग करके वैध कॉल बनाता है। पूरी इंटरेक्शन क्लाइंट के दृष्टिकोण से stateless है — सर्वर आंतरिक रूप से आवश्यक स्थिति प्रबंधित करता है।
यह सरलता ही उद्देश्य है। MCP एक फ्रेमवर्क नहीं है। यह एक अनुबंध है जो आपको कुछ भी — Postgres डेटाबेस, Kubernetes क्लस्टर, GitHub रेपो, एक मालिकाना आंतरिक API — को लपेटने और टाइप किए गए, कॉल करने योग्य फ़ंक्शन के एक सेट के रूप में उजागर करने देता है जिसे कोई भी AI मॉडल उपयोग कर सकता है।
सेटअप
आपको Node.js 18+ और एक TypeScript प्रोजेक्ट चाहिए। आधिकारिक MCP SDK बॉयलरप्लेट को न्यूनतम करता है:
mkdir mcp-server && cd mcp-servernpm init -ynpm install @modelcontextprotocol/sdk zodnpm install -D typescript @types/node tsxtsconfig.json जोड़ें:
{ "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "strict": true, "outDir": "./dist" }, "include": ["src"]}और package.json में एक स्टार्ट स्क्रिप्ट:
{ "scripts": { "dev": "tsx src/index.ts", "build": "tsc", "start": "node dist/index.js" }}सर्वर बनाना
src/index.ts बनाएं। संरचना हमेशा एक जैसी होती है: सर्वर को इनिशियलाइज़ करें, टूल रजिस्टर करें, stdio ट्रांसपोर्ट से कनेक्ट करें।
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: "my-mcp-server", version: "1.0.0",});अब टूल रजिस्टर करें। प्रत्येक टूल में एक नाम, एक विवरण जिसे मॉडल यह तय करने के लिए उपयोग करता है कि इसे कब कॉल करना है, और एक इनपुट Schema होता है:
server.tool( "get_weather", "किसी शहर के लिए वर्तमान मौसम की स्थिति प्राप्त करें", { city: z.string().describe("मौसम जानने के लिए शहर का नाम"), units: z.enum(["celsius", "fahrenheit"]).default("celsius"), }, async ({ city, units }) => { // यहाँ आपकी वास्तविक इम्प्लीमेंटेशन const data = await fetchWeather(city, units); return { content: [ { type: "text", text: `${city} में मौसम: ${data.temp}°${units === "celsius" ? "C" : "F"}, ${data.condition}`, }, ], }; });सर्वर को stdio ट्रांसपोर्ट से कनेक्ट करें:
const transport = new StdioServerTransport();await server.connect(transport);यह पूरा सर्वर स्केलेटन है। बाकी सब कुछ टूल जोड़ना है।
टूल डिज़ाइन पैटर्न
आपके MCP सर्वर की गुणवत्ता इस बात पर निर्भर करती है कि आप टूल कितनी अच्छी तरह डिज़ाइन करते हैं। कुछ महत्वपूर्ण पैटर्न:
विशाल मोनोलिथ के बजाय संकीर्ण, कंपोजेबल टूल
एक टूल जो एक काम करता है वह बेहतर है जो कई काम करता है। मॉडल संकीर्ण टूल को अप्रत्याशित तरीकों से मिला सकता है; एक विशाल टूल उसे सीमित करता है।
यह न करें:
server.tool("manage_database", "डेटाबेस के साथ कुछ भी करें", { operation: z.enum(["read", "write", "delete", "schema"]), query: z.string(), // ... कई वैकल्पिक पैरामीटर})यह करें:
server.tool("query_records", "SELECT क्वेरी चलाएं और JSON के रूप में रो लौटाएं", { table: z.string(), where: z.string().optional().describe("SQL WHERE क्लॉज़, जैसे 'status = active'"), limit: z.number().default(50),})
server.tool("get_schema", "किसी टेबल की कॉलम परिभाषाएं लौटाएं", { table: z.string(),})इनपुट को सटीकता से वर्णित करें
मॉडल आपकी describe() स्ट्रिंग पढ़ता है यह जानने के लिए कि क्या पास करना है। उन्हें ऐसे दस्तावेज़ के रूप में मानें जो किसी ऐसे डेवलपर के लिए लिखा गया हो जिसने आपका कोडबेस कभी नहीं देखा:
{ date_range: z.string().describe( "ISO 8601 तारीख रेंज YYYY-MM-DD/YYYY-MM-DD प्रारूप में। " + "उदाहरण: 2025-01-01/2025-03-31" ),}अस्पष्ट विवरण गलत इनपुट उत्पन्न करते हैं। सटीक विवरण सही इनपुट उत्पन्न करते हैं।
कच्चा JSON नहीं, संरचित टेक्स्ट लौटाएं
मॉडल टूल परिणामों में कच्चे JSON blobs की तुलना में टेक्स्ट को अधिक विश्वसनीय रूप से पार्स करते हैं। अपना आउटपुट फॉर्मेट करें:
return { content: [ { type: "text", text: [ `${rows.length} रिकॉर्ड मिले:`, ...rows.map(r => `- ${r.id}: ${r.name} (${r.status})`), ].join("\n"), }, ],};एरर हैंडलिंग
एरर को थ्रो किए गए एक्सेप्शन के रूप में नहीं, बल्कि टूल रिजल्ट के रूप में लौटाएं। isError: true फ्लैग एजेंट को विफलता का संकेत देता है ताकि वह रिकवर करने का तरीका तय कर सके:
async ({ table, where }) => { try { const rows = await db.query(table, where); return { content: [{ type: "text", text: formatRows(rows) }] }; } catch (err) { return { content: [ { type: "text", text: `क्वेरी विफल: ${err instanceof Error ? err.message : "अज्ञात एरर"}। ` + `जांचें कि टेबल का नाम सही है और WHERE क्लॉज़ वैध कॉलम नामों का उपयोग करता है।`, }, ], isError: true, }; }}वास्तविक उदाहरण: GitHub टूल सर्वर
यहाँ एक ठोस टूल है जो GitHub API को लपेटता है ताकि एजेंट रिपॉजिटरी सामग्री पढ़ सके:
import { Octokit } from "@octokit/rest";
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
server.tool( "get_file_contents", "GitHub रिपॉजिटरी से फ़ाइल की सामग्री पढ़ें", { owner: z.string().describe("रिपॉजिटरी मालिक (यूज़रनेम या ऑर्ग)"), repo: z.string().describe("रिपॉजिटरी का नाम"), path: z.string().describe("रिपॉजिटरी के भीतर फ़ाइल पाथ"), ref: z.string().optional().describe("ब्रांच, टैग या commit SHA। डिफ़ॉल्ट डिफ़ॉल्ट ब्रांच है।"), }, async ({ owner, repo, path, ref }) => { try { const { data } = await octokit.rest.repos.getContent({ owner, repo, path, ref });
if (Array.isArray(data)) { const listing = data.map(f => `${f.type === "dir" ? "📁" : "📄"} ${f.name}`).join("\n"); return { content: [{ type: "text", text: `${path} की डायरेक्टरी सूची:\n${listing}` }], }; }
if (data.type !== "file" || !data.content) { return { content: [{ type: "text", text: `${path} एक पठनीय फ़ाइल नहीं है` }], isError: true, }; }
const content = Buffer.from(data.content, "base64").toString("utf-8"); return { content: [{ type: "text", text: `${owner}/${repo}/${path} की सामग्री:\n\`\`\`\n${content}\n\`\`\`` }], }; } catch (err: unknown) { const message = err instanceof Error ? err.message : "अज्ञात एरर"; return { content: [{ type: "text", text: `${path} पढ़ने में विफल: ${message}` }], isError: true, }; } });Claude Desktop से कनेक्ट करना
सर्वर चलने के बाद, ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) या %APPDATA%\Claude\claude_desktop_config.json (Windows) पर इसकी कॉन्फ़िग एडिट करके Claude Desktop से कनेक्ट करें:
{ "mcpServers": { "my-server": { "command": "node", "args": ["/absolute/path/to/dist/index.js"], "env": { "GITHUB_TOKEN": "आपका_token" } } }}Claude Desktop को रीस्टार्ट करें। आपके टूल अपने आप टूल सेलेक्टर में दिखाई देंगे।
Claude Code से कनेक्ट करना
MCP सर्वर CLI के माध्यम से Claude Code से जुड़ते हैं:
claude mcp add my-server node /absolute/path/to/dist/index.jsClaude Code स्वचालित रूप से उन कार्यों पर काम करते समय आपके टूल का उपयोग करेगा जो उनसे लाभान्वित होते हैं।
आगे क्या बनाएं
एक MCP सर्वर अनिवार्य रूप से एक क्षमता सीमा है: एजेंट क्या देख और कर सकता है। कुछ दिशाएं जो खोजने योग्य हैं:
- डेटाबेस सर्वर — Postgres, SQLite, या DynamoDB तक केवल-पढ़ने योग्य क्वेरी एक्सेस दें, Schema इंट्रोस्पेक्शन टूल के साथ
- कोड एनालिसिस सर्वर — tree-sitter या language server protocol को लपेटें ताकि एजेंटों को कोडबेस की सिमेंटिक समझ मिले
- मॉनिटरिंग सर्वर — मेट्रिक्स सिस्टम (Prometheus, Datadog) को ब्रिज करें ताकि एजेंट वास्तविक ऑब्जर्वेबिलिटी डेटा के साथ घटनाओं की जांच कर सकें
- डॉक्यूमेंटेशन सर्वर — आंतरिक दस्तावेज़ को इंडेक्स करें और सर्व करें, एजेंटों को ऑपरेशनल प्रश्नों का उत्तर देने में सक्षम बनाएं
MCP इकोसिस्टम अभी भी प्रारंभिक अवस्था में है। अधिकांश उपयोगी सर्वर अभी तक नहीं बनाए गए हैं। वह बनाएं जो आपके वातावरण में एक वास्तविक समस्या हल करे, और प्रोटोकॉल बाकी का ध्यान रखेगा।
संबंधित लेख
- एजेंटिक विकास का परिचय
- टूल उपयोग पैटर्न: विश्वसनीय एजेंट-टूल इंटरफेस बनाना
- मल्टी-एजेंट पैटर्न: ऑर्केस्ट्रेटर, Workers और पाइपलाइन