Claude Code और GitHub Copilot के लिए MCP सर्वर बनाएँ

एक ही TypeScript MCP सर्वर बनाएँ और उसे Claude Code और GitHub Copilot दोनों में रजिस्टर करें। आपको काम करने वाला टूल कोड, हर क्लाइंट के लिए सटीक कॉन्फ़िग, MCP Inspector के साथ डीबगिंग की प्रक्रिया और PicassoIA API को कॉल करने वाला एक इमेज टूल मिलेगा।

Claude Code और GitHub Copilot के लिए MCP सर्वर बनाएँ
Cristian Da Conceicao
Picasso IA के संस्थापक

आपने एक स्क्रिप्ट लिखी है जो रोज़ आपके दस मिनट बचाती है, और अब आप चाहते हैं कि आपका AI असिस्टेंट उसे कॉपी-पेस्ट के झंझट के बिना चलाए। इसे एक बार Model Context Protocol सर्वर के रूप में बनाएँ, तो Claude Code और GitHub Copilot दोनों एक ही टूल्स को कॉल कर सकते हैं, क्योंकि MCP वह साझा भाषा है जिसमें वे एडिटर के बाहर की किसी भी चीज़ से बात करते हैं। यह वॉकथ्रू एक छोटा TypeScript सर्वर बनाता है, उसे Claude Code में रजिस्टर करता है, VS Code के अंदर Copilot में रजिस्टर करता है, और अंत में PicassoIA API को कॉल करने वाला एक असली इमेज टूल जोड़ता है। लगभग 40 मिनट और करीब 100 लाइन कोड का अनुमान रखें।

एक सर्वर दो से बेहतर क्यों है

MCP से पहले, हर असिस्टेंट अपना अलग प्लगइन फ़ॉर्मेट, अपना मैनिफ़ेस्ट और अपने पैकेजिंग नियम माँगता था। MCP सर्वर उस सारे झंझट की जगह एक ही प्रोसेस रखता है, जो बताता है कि वह क्या कर सकता है। क्लाइंट प्रोसेस शुरू करता है, उसकी क्षमताओं की सूची माँगता है, और वह सूची मॉडल को दे देता है। फिर मॉडल बातचीत के बीच ही तय करता है कि कॉल करना कब सार्थक है।

डेस्क का ऊपर से लिया दृश्य, जिस पर सादे कागज़ पर हाथ से बने बॉक्स और तीरों वाला डायग्राम है, साथ में लैपटॉप और कॉफ़ी रखी है

एक ही प्रोटोकॉल, दो क्लाइंट

एक सर्वर तीन तरह की क्षमताएँ दे सकता है:

  • Tools: ऐसे फ़ंक्शन जिन्हें मॉडल कॉल कर सकता है, जैसे add_note या generate_image।
  • Resources: केवल-पढ़ने वाला डेटा जिसे क्लाइंट बातचीत में जोड़ सकता है, जैसे कोई लॉग फ़ाइल या स्कीमा।
  • Prompts: दोबारा इस्तेमाल होने वाले टेम्पलेट जिन्हें यूज़र जानबूझकर चलाता है।

आज लगभग सारी वैल्यू टूल्स में है, इसलिए यह लेख उन्हीं पर केंद्रित रहता है। Claude Code और Copilot दोनों एक ही तरह के JSON-RPC मैसेज एक ही ट्रांसपोर्ट पर बोलते हैं, यानी जो सर्वर एक क्लाइंट के साथ चलता है, वह लगभग बिना बदलाव के दूसरे के साथ भी चलेगा।

व्हाइटबोर्ड के बगल में खड़ा डेवलपर, जिस पर तीन कॉलम में व्यवस्थित स्टिकी नोट्स लगे हैं

सेटअप कहाँ अलग है

सर्वर एक जैसा है। रजिस्ट्रेशन एक जैसा नहीं है। पूरा अंतर एक टेबल में यह है:

सेटिंगClaude CodeVS Code में GitHub Copilot
कॉन्फ़िग फ़ाइलप्रोजेक्ट में .mcp.json, या ~/.claude.json.vscode/mcp.json, या आपकी यूज़र प्रोफ़ाइल
रूट प्रॉपर्टीmcpServersservers
टर्मिनल से जोड़ेंclaude mcp addCommand Palette: MCP: Add Server
Transport फ़ील्डtype (stdio, http, sse)type ज़रूरी है (stdio या http)
सीक्रेट्स--env फ़्लैग या ${VAR} एक्सपैंशनinputs ब्लॉक, जिसमें ${input:id} हो
टूल कहाँ चलते हैंकोई भी सेशनकेवल Agent mode में

💡 टिप: रूट प्रॉपर्टी सबसे आम जाल है। Claude Code का कॉन्फ़िग बिना बदले VS Code में चिपकाएँ, तो कुछ भी लोड नहीं होता, क्योंकि Copilot servers ढूँढता है, mcpServers नहीं।

प्रोजेक्ट सेट करें

अपनी मुख्य रिपॉज़िटरी के बाहर कोई फ़ोल्डर चुनें, ताकि सर्वर बाद में कई प्रोजेक्ट्स की सेवा कर सके। आपको Node.js 20 या उससे नया और एक टर्मिनल चाहिए।

डेवलपर के हाथों का क्लोज़-अप, जो टाइप कर रहे हैं, पीछे एक धुंधला कोड एडिटर

SDK इंस्टॉल करें

mkdir team-notes-mcp && cd team-notes-mcp
npm init -y
npm install @modelcontextprotocol/sdk zod
npm install -D typescript tsx @types/node

package.json खोलें और "type": "module" के साथ दो स्क्रिप्ट जोड़ें, "build": "tsc" और "dev": "tsx src/index.ts"। फिर एक tsconfig.json बनाएँ:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src"]
}

उदाहरणों में @modelcontextprotocol/sdk 1.x API का उपयोग है, जिसमें McpServer और registerTool शामिल हैं। अगर कोई नया मेजर वर्ज़न इम्पोर्ट पाथ बदलता है, तो नीचे की अवधारणाएँ वही रहेंगी।

stdio से शुरू करें

MCP में दो मुख्य ट्रांसपोर्ट हैं। stdio का मतलब है कि क्लाइंट आपके सर्वर को चाइल्ड प्रोसेस के रूप में शुरू करता है और मैसेज standard input और output के ज़रिए बदलता है। Streamable HTTP का मतलब है कि सर्वर अपने आप चलता है और क्लाइंट URL से जुड़ते हैं। stdio से शुरू करें। इसमें न पोर्ट चाहिए, न ऑथेंटिकेशन लेयर, न होस्टिंग, और दोनों क्लाइंट इसे सीधे सपोर्ट करते हैं। HTTP पर तभी जाएँ जब कई लोगों को एक ही चलते इंस्टेंस को साझा करना हो।

सर्वर लिखें

हमारा उदाहरण एक छोटा टीम नोट्स सर्वर है, जिसमें दो टूल हैं: एक नोट सेव करता है, दूसरा उन्हें खोजता है। यह इतना छोटा है कि एक मिनट में पढ़ा जा सके, और इतना असली है कि काम का हो।

दो डेवलपर साथ-साथ बैठे हैं, जिनमें से एक लैपटॉप स्क्रीन की ओर इशारा कर रहा है

एक टूल रजिस्टर करें

src/index.ts बनाएँ:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { promises as fs } from "node:fs";
import path from "node:path";

const NOTES_FILE = path.join(process.env.NOTES_DIR ?? process.cwd(), "notes.json");

type Note = { id: number; text: string; tags: string[]; createdAt: string };

async function readNotes(): Promise<Note[]> {
  try {
    return JSON.parse(await fs.readFile(NOTES_FILE, "utf8"));
  } catch {
    return [];
  }
}

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

server.registerTool(
  "add_note",
  {
    title: "Add note",
    description:
      "Save a short engineering note with optional tags. Use it when the user asks to remember a decision, a command or a bug.",
    inputSchema: {
      text: z.string().min(3).max(2000),
      tags: z.array(z.string()).default([]),
    },
  },
  async ({ text, tags }) => {
    const notes = await readNotes();
    const note: Note = {
      id: notes.length + 1,
      text,
      tags,
      createdAt: new Date().toISOString(),
    };
    await fs.writeFile(NOTES_FILE, JSON.stringify([...notes, note], null, 2));
    return { content: [{ type: "text", text: `Saved note #${note.id}` }] };
  }
);

server.registerTool(
  "search_notes",
  {
    title: "Search notes",
    description: "Find saved notes whose text or tags contain the query.",
    inputSchema: { query: z.string().min(1) },
  },
  async ({ query }) => {
    const q = query.toLowerCase();
    const hits = (await readNotes()).filter(
      (n) =>
        n.text.toLowerCase().includes(q) ||
        n.tags.some((t) => t.toLowerCase().includes(q))
    );
    const text = hits.length
      ? hits.map((n) => `#${n.id} [${n.tags.join(", ")}] ${n.text}`).join("\n")
      : "No notes matched.";
    return { content: [{ type: "text", text }] };
  }
);

await server.connect(new StdioServerTransport());
console.error("team-notes MCP server running on stdio");

npm run build चलाएँ। अब आपके पास dist/index.js है, और यही फ़ाइल वह अकेली चीज़ है जो दोनों क्लाइंट्स को जाननी है।

साफ़ नतीजे लौटाएँ

मॉडल जो भी आप लौटाते हैं वह पढ़ता है, इसलिए रिटर्न वैल्यू को एक इंटरफ़ेस की तरह समझें। नतीजे छोटे, स्ट्रक्चर्ड और ईमानदार रखें। जब कुछ विफल हो, तो ऐसा एक्सेप्शन न फेंकें जो ट्रांसपोर्ट लेयर में ही मर जाए। ऐसा एरर लौटाएँ जिसे मॉडल पढ़ और उस पर प्रतिक्रिया दे सके:

return {
  isError: true,
  content: [{ type: "text", text: "notes.json is not valid JSON. Fix or delete it." }],
};

isError नतीजा असिस्टेंट को समस्या समझाने, या अलग इनपुट के साथ दोबारा कोशिश करने देता है। क्रैश होने पर सिर्फ़ एक धुंधला "server disconnected" बैनर दिखता है।

stdout को शांत रखें

पहला सर्वर विफल होने का यह सबसे आम कारण है। stdio के साथ, standard output प्रोटोकॉल का है। एक भटका हुआ console.log सादा टेक्स्ट JSON-RPC स्ट्रीम में डाल देता है और क्लाइंट कनेक्शन तोड़ देता है। console.error पर लॉग करें, जो stderr पर लिखता है, और दोनों क्लाइंट उसे डायग्नोस्टिक आउटपुट के रूप में पकड़ लेंगे।

💡 टिप: टूल डिस्क्रिप्शन को इंसानों के लिए डॉक्यूमेंटेशन की तरह नहीं, बल्कि मॉडल के लिए निर्देश की तरह लिखें। "जब यूज़र कोई फ़ैसला याद रखने को कहे, तब इसका उपयोग करें" से टूल सही समय पर चुना जाता है। "Notes utility" से नहीं।

Claude Code से जोड़ें

चश्मे में परावर्तित होती लैपटॉप स्क्रीन पर टर्मिनल विंडो का मैक्रो शॉट

CLI से जोड़ें

एक कमांड सर्वर रजिस्टर करता है। विकल्प नाम से पहले जाते हैं, और डबल डैश नाम को उस कमांड से अलग करता है जिसे Claude Code चलाएगा:

claude mcp add --transport stdio --scope user \
  --env NOTES_DIR=/home/dev/notes \
  team-notes -- node /absolute/path/to/team-notes-mcp/dist/index.js

एब्सोल्यूट पाथ इस्तेमाल करें। Claude Code प्रोसेस को उस डायरेक्टरी से शुरू करता है जहाँ आपका सेशन है, इसलिए रिलेटिव पाथ तब टूट जाते हैं जब आप कोई दूसरा प्रोजेक्ट खोलते हैं। फिर इसकी पुष्टि करें:

claude mcp list
claude mcp get team-notes

सेशन के अंदर /mcp टाइप करें, ताकि कनेक्शन स्थिति और टूल्स की सूची दिखे। कोई स्वाभाविक सवाल पूछें, जैसे "याद रखें कि हम गुरुवार को डिप्लॉय करते हैं, इसे release टैग करें", और देखें कि Claude Code add_note कॉल करने की अनुमति कैसे माँगता है।

.mcp.json के ज़रिए साझा करें

स्कोप फ़्लैग तय करता है कि सर्वर कौन इस्तेमाल करेगा। local उसे एक प्रोजेक्ट में केवल आपके लिए निजी रखता है, user उसे हर प्रोजेक्ट में उपलब्ध कराता है, और project एक .mcp.json फ़ाइल लिखता है, जिसे आप कमिट कर सकते हैं ताकि पूरी टीम को वह मिले। यहाँ एक साझा कॉन्फ़िग है जो हार्डकोडेड पाथ से बचती है:

{
  "mcpServers": {
    "team-notes": {
      "type": "stdio",
      "command": "node",
      "args": ["${TEAM_NOTES_PATH}/dist/index.js"],
      "env": { "NOTES_DIR": "${NOTES_DIR:-.notes}" }
    }
  }
}

हर टीममेट TEAM_NOTES_PATH को अपने शेल में एक बार सेट करता है। ${NOTES_DIR:-.notes} वाला रूप तब डिफ़ॉल्ट देता है जब वेरिएबल मौजूद न हो। Claude Code किसी प्रोजेक्ट-स्कोप्ड सर्वर को पहली बार देखने पर मंज़ूरी माँगता है, जो रिपॉज़िटरी से खींची गई किसी भी चीज़ के लिए एक समझदारी भरा सुरक्षा उपाय है।

GitHub Copilot से जोड़ें

शाम की रोशनी में दो मॉनिटरों को देखकर मुस्कुराता हुआ, ऑफ़िस कुर्सी पर पीछे झुका डेवलपर

.vscode/mcp.json लिखें

अपने वर्कस्पेस में .vscode/mcp.json बनाएँ। अलग रूट प्रॉपर्टी और ज़रूरी type को याद रखें:

{
  "servers": {
    "team-notes": {
      "type": "stdio",
      "command": "node",
      "args": ["${workspaceFolder}/tools/team-notes-mcp/dist/index.js"],
      "env": { "NOTES_DIR": "${workspaceFolder}/.notes" }
    }
  }
}

${workspaceFolder} फ़ाइल को पोर्टेबल बनाता है, इसलिए आप उसे कमिट कर सकते हैं। सीक्रेट्स के लिए inputs ऐरे जोड़ें। VS Code एक बार पूछता है, वैल्यू सुरक्षित रूप से स्टोर करता है और उसे इंजेक्ट करता है:

{
  "inputs": [
    { "type": "promptString", "id": "picassoia-token", "description": "PicassoIA API token", "password": true }
  ],
  "servers": {
    "team-notes": {
      "type": "stdio",
      "command": "node",
      "args": ["${workspaceFolder}/tools/team-notes-mcp/dist/index.js"],
      "env": { "PICASSOIA_API_TOKEN": "${input:picassoia-token}" }
    }
  }
}

Agent mode पर जाएँ

Copilot Chat डिफ़ॉल्ट रूप से Ask mode में खुलता है, और MCP टूल्स केवल Agent mode में चलते हैं। चैट पैनल में मोड बदलें, टूल्स पिकर खोलें और पुष्टि करें कि team-notes दोनों टूल्स के टिक के साथ दिखता है। अगर वह न दिखे, तो Command Palette से MCP: List Servers चलाएँ, सर्वर चुनें और उसका आउटपुट पढ़ें। हर रीबिल्ड के बाद उसी मेन्यू से उसे फिर से शुरू करें।

Copilot आपको अपने प्लान में मिलने वाले मॉडलों में से चुनने देता है, इसलिए वही सर्वर अलग-अलग मॉडलों से परखा जाता है। यह जाँचने का एक आसान तरीका है कि आपकी टूल डिस्क्रिप्शन हर एक के लिए पर्याप्त साफ़ हैं या नहीं।

शिप करने से पहले टेस्ट और डीबग करें

बारिश वाली खिड़की के बगल में स्टैंडिंग डेस्क पर खड़े, बीनी पहने दाढ़ी वाले डेवलपर का साइड प्रोफ़ाइल

MCP Inspector चलाएँ

किसी क्लाइंट को दोष देने से पहले, सर्वर को अकेले टेस्ट करें। आधिकारिक Inspector एक लोकल वेब पेज खोलता है, जहाँ आप टूल्स की सूची देख सकते हैं, आर्गुमेंट भर सकते हैं और रॉ रिस्पॉन्स देख सकते हैं:

npx @modelcontextprotocol/inspector node dist/index.js

add_note को एक खाली text के साथ कॉल करें। आपकी Zod स्कीमा इसे एक पढ़ने योग्य वैलिडेशन मैसेज के साथ अस्वीकार करनी चाहिए। फिर search_notes को उस टैग के साथ कॉल करें जो आपने अभी सेव किया है। अगर दोनों यहाँ सही व्यवहार करते हैं, तो बची हुई कोई भी समस्या कॉन्फ़िगरेशन में है, आपके कोड में नहीं।

आम विफलताएँ ठीक करें

लक्षणसंभावित कारणसमाधान
सर्वर कभी कनेक्ट नहीं होताकिसी console.log ने stdout में लिखाconsole.error पर स्विच करें
"Command not found"रिलेटिव पाथ या बिल्ड गायबएब्सोल्यूट पाथ इस्तेमाल करें और npm run build चलाएँ
Copilot में टूल्स गायब हैंचैट Ask mode में हैAgent mode पर स्विच करें
टूल मौजूद है पर कभी चुना नहीं जाताअस्पष्ट डिस्क्रिप्शनट्रिगर वाक्यांशों के साथ उसे दोबारा लिखें
खाली एनवायरनमेंट वेरिएबलकॉन्फ़िग में घोषित नहींइसे env ब्लॉक में जोड़ें
लोड में इमेज कॉल विफल होती हैंएक साथ 5 से ज़्यादा जॉबटूल के भीतर कॉल्स की कतार बनाएँ

अपने सर्वर को इमेज टूल दें

नोट्स ठीक हैं, लेकिन MCP का सबसे अच्छा प्रदर्शन वह टूल है जो वह काम करे जो असिस्टेंट अकेले नहीं कर सकता। इमेज जनरेशन इसके लिए अच्छा फ़िट है: मॉडल एक सटीक प्रॉम्प्ट लिखता है, आपका सर्वर उसे फ़ाइल में बदलता है, और URL सीधे बातचीत में वापस आ जाता है।

लंबी ओक की मेज़ के चारों ओर खड़े चार लोगों का ऊपर से दृश्य, जो छपे डायग्राम की ओर इशारा कर रहे हैं

PicassoIA API को कॉल करें

PicassoIA डेवलपर API https://api.picassoia.com/v1 पर है और एक Bearer टोकन इस्तेमाल करता है जो pia_sk_ से शुरू होता है। प्रेडिक्शन असिंक्रोनस और Replicate-जैसे होते हैं: आप एक बनाते हैं, फिर तब तक पोल करते हैं जब तक स्टेटस succeeded न दिखे। PicassoIA Image मॉडल 4,000 अक्षरों तक का prompt और एक aspect_ratio स्वीकार करता है, और इमेज URLs की एक सूची लौटाता है। इस टूल को server.connect लाइन से पहले जोड़ें:

const API = "https://api.picassoia.com/v1";
const headers = {
  Authorization: `Bearer ${process.env.PICASSOIA_API_TOKEN}`,
  "Content-Type": "application/json",
};

server.registerTool(
  "generate_image",
  {
    title: "Generate image",
    description: "Create an image from a text prompt with PicassoIA and return its URL.",
    inputSchema: {
      prompt: z.string().min(1).max(4000),
      aspect_ratio: z.enum(["1:1", "16:9", "9:16", "4:3", "3:4", "3:2", "2:3"]).default("16:9"),
    },
  },
  async ({ prompt, aspect_ratio }) => {
    const created = await fetch(`${API}/models/picassoia/picassoia-image/predictions`, {
      method: "POST",
      headers,
      body: JSON.stringify({ input: { prompt, aspect_ratio } }),
    }).then((r) => r.json());

    let prediction = created;
    while (["starting", "processing"].includes(prediction.status)) {
      const wait = prediction.eta?.next_poll_in_seconds ?? 2;
      await new Promise((resolve) => setTimeout(resolve, wait * 1000));
      prediction = await fetch(`${API}/predictions/${created.id}`, { headers }).then((r) => r.json());
    }

    if (prediction.status !== "succeeded") {
      return {
        isError: true,
        content: [{ type: "text", text: `Generation ${prediction.status ?? "request failed"}` }],
      };
    }
    return { content: [{ type: "text", text: prediction.output[0] }] };
  }
);

एक अकाउंट पर 5 एक साथ चलने वाले प्रेडिक्शन की अनुमति है, जो हर टोकन और कनेक्शन में साझा होती है, इसलिए एक लूप जो एक साथ दस इमेज चलाए, उस सीमा तक पहुँच जाएगा। टूल के भीतर उन्हें एक के बाद एक जनरेट करें, या एक छोटी कतार रखें।

💡 टिप: दूसरों के लिए सर्वर प्रकाशित करने से पहले PicassoIA API पेज पर मौजूदा प्राइसिंग और प्लान की ज़रूरतें जाँच लें। डॉक्स और प्राइसिंग पेज एक्सेस को अलग-अलग तरह से बताते हैं, इसलिए पक्का करें कि आपके अपने प्लान में क्या शामिल है।

PicassoIA पर Sonnet 5 कैसे इस्तेमाल करें

आपकी टूल डिस्क्रिप्शन भी प्रॉम्प्ट हैं, और इनके लिए लार्ज लैंग्वेज मॉडल सबसे अच्छा एडिटर है। Claude Sonnet 5 इस काम के लिए एक मज़बूत विकल्प है, और आप इसे PicassoIA पर ब्राउज़र छोड़े बिना चला सकते हैं।

  1. लार्ज लैंग्वेज मॉडल कलेक्शन में Claude Sonnet 5 पेज खोलें।
  2. अपनी टूल परिभाषाएँ, जिनमें नाम, डिस्क्रिप्शन और स्कीमा शामिल हैं, प्रॉम्प्ट में चिपकाएँ।
  3. उससे हर डिस्क्रिप्शन को एक छोटे निर्देश के रूप में दोबारा लिखने को कहें, जो बताए कि टूल को कब कॉल करना है और वह क्या लौटाता है।
  4. हर टूल के लिए दस एज केस इनपुट माँगें, जैसे खाली स्ट्रिंग, बहुत लंबा टेक्स्ट और असामान्य टैग।
  5. उन इनपुट्स को MCP Inspector में चलाएँ, हर विफलता ठीक करें, और सुधरी हुई डिस्क्रिप्शन वापस अपने कोड में चिपका दें।

जटिल लॉजिक पर दूसरी राय के लिए, Claude Fable 5 और GPT 5.6 Sol दोनों कोडिंग कार्यों के लिए सूचीबद्ध हैं। एक ही डिस्क्रिप्शन पर उनके दोबारा लिखे गए संस्करणों की तुलना अक्सर यह दिखा देती है कि कौन-सा वाक्यांश अस्पष्ट है।

PicassoIA पर खुद आज़माएँ

अब आपके पास एक ही सर्वर दो असिस्टेंट्स में चल रहा है: याद रखने के लिए नोट्स, आउटपुट के लिए एक इमेज टूल, और एक टेस्टिंग रूटीन जो दोनों को ईमानदार रखता है। यही पैटर्न किसी भी चीज़ पर लागू होता है जिसे आप फ़ंक्शन में लपेट सकते हैं, डिप्लॉय स्क्रिप्ट से लेकर डेटाबेस लुकअप तक।

कैफ़े की मेज़ पर लैपटॉप और फ़्लैट व्हाइट कॉफ़ी, उनके बगल में एक स्मार्टफ़ोन रखा है

इमेज टूल से शुरू करें, क्योंकि उससे तुरंत फ़ीडबैक मिलता है। एक प्रॉम्प्ट लिखें, Claude Code या Copilot से generate_image कॉल करें, और सेकंडों में देखें कि क्या वापस आता है। फिर PicassoIA Image पेज खोलें और आस्पेक्ट रेशियो और प्रॉम्प्ट स्टाइल सीधे आज़माएँ, या picassoia.com/en/all-models पर उपलब्ध हर मॉडल देखें। आपकी पहली इमेज बस एक प्रॉम्प्ट दूर है।

यह लेख शेयर करें

अपनी भाषा चुनें

संबंधित लेख