MCP बनाम फ़ंक्शन कॉलिंग: OpenAI और Claude के उदाहरणों के साथ अंतर
MCP और function calling अलग-अलग समस्याएँ हल करते हैं। Function calling मॉडल को किसी एक्शन का अनुरोध करने देता है, जबकि MCP ऐप्स को टूल खोजने के लिए एक साझा प्रोटोकॉल देता है। यह लेख दोनों की तुलना OpenAI और Claude के कोड सैंपल, एक सिक्योरिटी चेकलिस्ट और चुनने के लिए एक सरल नियम के साथ करता है।
गलत लेयर चुनेंगे तो एक ही इंटीग्रेशन दो बार बनाना पड़ेगा। MCP बनाम function calling देखने में दो रास्तों जैसा लगता है, पर ये दोनों एक ही स्टैक की अलग-अलग परतों पर बैठते हैं। Function calling वह तरीका है जिससे मॉडल किसी एक्शन के लिए अनुरोध करता है। Model Context Protocol (MCP) वह तरीका है जिससे कोई एप्लिकेशन उन टूल्स को खोजता और उन तक पहुँचता है जिन पर वह एक्शन चलता है।
कोड से पहले छोटा जवाब: function calling एक मॉडल फ़ीचर है, MCP एक वायर प्रोटोकॉल है, और ज़्यादातर MCP सेटअप अंदर से function calling का ही इस्तेमाल करते हैं। एक ही ऐप में दो-तीन टूल हों तो सादा function calling सरल रहता है। जब कई ऐप्स को एक ही टूल चाहिए, तब MCP जल्दी ही अपनी लागत वसूल लेता है। नीचे दिए भागों में दोनों तरीकों के OpenAI और Claude उदाहरण साथ-साथ दिखाए गए हैं।
Function Calling असल में क्या करता है
भाषा मॉडल सिर्फ़ टेक्स्ट बनाता है। Function calling उस टेक्स्ट को ऐसा आकार देता है जिस पर आपका कोड भरोसा कर सके। हर अनुरोध के साथ आप टूल डेफ़िनिशन की सूची भेजते हैं: एक नाम, सरल भाषा में एक विवरण, और arguments के लिए एक JSON Schema। जब मॉडल को लगता है कि कोई टूल चाहिए, तो वह कुछ चलाता नहीं। वह टूल के नाम और arguments के साथ एक स्ट्रक्चर्ड कॉल लौटाता है, और काम आपका कोड करता है।
रिक्वेस्ट और रिस्पॉन्स का लूप
आपका ऐप यूज़र का मैसेज और टूल डेफ़िनिशन भेजता है।
मॉडल अंतिम टेक्स्ट की जगह एक टूल कॉल लौटाता है।
आपका कोड फ़ंक्शन चलाता है और रिज़ल्ट कैप्चर करता है।
आप रिज़ल्ट को एक नए मैसेज के रूप में वापस भेजते हैं।
मॉडल अंतिम जवाब लिखता है, या कोई और टूल माँगता है।
💡 टिप: मॉडल कभी कोड नहीं चलाता। वह एक कॉल प्रस्तावित करता है, और यह आपका ऐप तय करता है कि उसे चलाना है या नहीं। यही वह जगह है जहाँ परमिशन चेक और लॉगिंग होनी चाहिए।
Schema कहाँ रहता है
डेफ़िनिशन आपके अपने कोडबेस में रहते हैं, आमतौर पर उस फ़ंक्शन के बगल में जिसे वे बताते हैं। OpenAI schema फ़ील्ड को parameters कहता है। Claude उसे input_schema कहता है। प्रोवाइडर के बीच ढाँचा थोड़ा अलग है, इसलिए एक के लिए लिखे टूल को दूसरे के लिए हल्के एडेप्टर की ज़रूरत पड़ती है।
सादे function calling की असली लागत यही है: हर ऐप अपनी हर डेफ़िनिशन की अपनी कॉपी रखता है, और हर प्रोवाइडर अपना अलग रूप चाहता है। एक चैट ऐप, एक IDE प्लगइन और एक सपोर्ट बॉट के लिए एक ही ऑर्डर लुकअप बनाएँ, तो आपको तीन कॉपी मेंटेन करनी पड़ेंगी।
MCP ऊपर से क्या जोड़ता है
Anthropic ने नवंबर 2024 में MCP को एक ओपन प्रोटोकॉल के रूप में जारी किया, और OpenAI ने मार्च 2025 में इसे अपनाया। MCP यह मानकीकृत करता है कि टूल्स कैसे बताए, सूचीबद्ध और कॉल किए जाते हैं, इसलिए एक बार MCP सर्वर के रूप में लिखा गया टूल उस हर क्लाइंट में चलता है जो यह प्रोटोकॉल समझता है। यह ऊपर की फ़ोटो वाले स्टैंडर्ड पोर्ट जैसा है: एक कनेक्टर का आकार, कई डिवाइस। N ऐप्स और M टूल्स के बराबर कस्टम ग्लू लिखने के बजाय आप N क्लाइंट और M सर्वर बनाते हैं।
Hosts, Clients और Servers
MCP की तीन भूमिकाएँ हैं:
Host: वह एप्लिकेशन जो यूज़र देखता है, जैसे चैट ऐप, IDE, या आपका अपना एजेंट।
Client: होस्ट के अंदर का एक कनेक्टर जो एक सर्वर के साथ एक सेशन रखता है।
Server: एक छोटा प्रोग्राम जो टूल्स, डेटा और प्रॉम्प्ट एक्सपोज़ करता है।
मैसेज JSON-RPC 2.0 में जाते हैं। लोकल सर्वर stdio पर बात करते हैं, और रिमोट सर्वर Streamable HTTP पर। क्लाइंट एक सेशन खोलता है, सर्वर से पूछता है कि वह क्या देता है, और नाम से चीज़ें कॉल करता है।
Tools, Resources और Prompts
एक सर्वर तीन तरह की क्षमताएँ एक्सपोज़ कर सकता है:
Primitive
यह क्या है
इसे कौन नियंत्रित करता है
Tools
एक्शन या गणनाएँ जिन्हें मॉडल कॉल कर सकता है
मॉडल
Resources
URI से पहचाना जाने वाला पढ़ने योग्य डेटा, जैसे फ़ाइल या रिकॉर्ड
ऐप्लिकेशन
Prompts
दोबारा इस्तेमाल होने वाले मैसेज टेम्पलेट
यूज़र
केवल टूल्स ही फ़ंक्शन कॉलिंग से मेल खाते हैं। सादे फ़ंक्शन कॉलिंग में Resources और prompts का कोई मानक तरीका नहीं होता, और इसी वजह का एक हिस्सा है कि लोग MCP की तरफ़ जाते हैं।
एक टूल के लिए वायर ट्रैफ़िक यह रहा। क्लाइंट सर्वर से उसके टूल्स माँगता है:
सर्वर ऐसी डेफ़िनिशन लौटाता है जो उन जैसी दिखती हैं जो आप हाथ से लिखते, बस schema फ़ील्ड camelCase में inputSchema है:
{"jsonrpc": "2.0", "id": 1, "result": {"tools": [{
"name": "get_order_status",
"description": "Look up the shipping status of an order by its ID.",
"inputSchema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"]
}
}]}}
बाद में, जब मॉडल उस टूल को माँगता है, तब क्लाइंट यह भेजता है:
हाँ, मॉडल अब भी function calling से ही टूल कॉल करता है
सेटअप की मेहनत
मिनट
पहले सर्वर के लिए कुछ घंटे, मौजूदा सर्वर के लिए मिनट
सबसे अच्छा किसके लिए
कुछ टूल्स, निजी ऐप लॉजिक
साझा टूल्स और थर्ड-पार्टी इंटीग्रेशन
MCP कॉल Function Calls कैसे बनती हैं
ये दोनों प्रतिद्वंद्वी नहीं हैं, क्योंकि MCP function calling को ही फ़ीड करता है। MCP सेटअप में एक अनुरोध का पूरा रास्ता यह है:
MCP क्लाइंट हर जुड़े सर्वर से टूल्स की सूची लेता है।
वह उन्हें प्रोवाइडर के अपने टूल फ़ॉर्मेट में बदलता है और अनुरोध के साथ भेजता है।
मॉडल एक सामान्य function call लौटाता है।
MCP क्लाइंट उसे सही सर्वर को tools/call के रूप में आगे भेजता है।
सर्वर का रिज़ल्ट एक सामान्य टूल रिज़ल्ट के रूप में वापस मॉडल के पास जाता है।
मॉडल की नज़र से कुछ नहीं बदला। उसने टूल डेफ़िनिशन देखीं और एक कॉल भेजी। जो बदला वह यह है कि डेफ़िनिशन किसने लिखीं और फ़ंक्शन किसने चलाया।
💡 मोटा नियम: अगर आप अपने कोड की वह लाइन बता सकते हैं जो फ़ंक्शन चलाती है, तो आप सादा function calling कर रहे हैं। अगर उसे कोई अलग सर्वर चलाता है, तो आप MCP कर रहे हैं, और मॉडल और क्लाइंट के बीच function calling फिर भी होती है।
कोड में OpenAI और Claude के उदाहरण
एक ही टूल, चार तरीके: ऑर्डर स्टेटस लुकअप। उदाहरण Python में हैं, और MCP सर्वर URL एक प्लेसहोल्डर है जिसे आप अपने URL से बदलेंगे।
OpenAI Function Calling
यह संस्करण GPT 5 के साथ Responses API का इस्तेमाल करता है। आप टूल डेफ़िनिशन करते हैं, फ़ंक्शन खुद चलाते हैं, और एक function_call_output आइटम वापस भेजते हैं।
import json
from openai import OpenAI
client = OpenAI()
def get_order_status(order_id: str) -> dict:
return {"order_id": order_id, "status": "shipped", "eta": "2026-10-09"}
tools = [{
"type": "function",
"name": "get_order_status",
"description": "Look up the shipping status of an order by its ID.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
"additionalProperties": False,
},
"strict": True,
}]
input_items = [{"role": "user", "content": "Where is order 8841?"}]
response = client.responses.create(model="gpt-5", tools=tools, input=input_items)
input_items += response.output
for item in response.output:
if item.type == "function_call":
result = get_order_status(**json.loads(item.arguments))
input_items.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(result),
})
final = client.responses.create(model="gpt-5", tools=tools, input=input_items)
print(final.output_text)
OpenAI Remote MCP
वही सवाल, आपके कोड में कोई schema नहीं और कोई लूप नहीं। API सर्वर से कनेक्ट होता है, उसके टूल्स की सूची लेता है, और आपके लिए उन्हें कॉल करता है।
response = client.responses.create(
model="gpt-5",
tools=[{
"type": "mcp",
"server_label": "orders",
"server_url": "https://mcp.example.com/mcp",
"require_approval": "always",
}],
input="Where is order 8841?",
)
print(response.output_text)
require_approval को "always" पर सेट करने पर, रिस्पॉन्स में हर कॉल के लिए एक अप्रूवल अनुरोध आता है, और आपका कोड तय करता है कि उसकी अनुमति देनी है या नहीं। "never" का इस्तेमाल केवल उन सर्वरों के लिए करें जिन पर आप पूरा भरोसा करते हैं।
Claude Tool Use
Messages API उसी लूप का पालन करता है, बस फ़ील्ड के नाम अलग हैं। Schema input_schema में जाता है, मॉडल stop_reason == "tool_use" से कॉल का संकेत देता है, और आप एक tool_result ब्लॉक से जवाब देते हैं।
import json
import anthropic
client = anthropic.Anthropic()
tools = [{
"name": "get_order_status",
"description": "Look up the shipping status of an order by its ID.",
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}]
messages = [{"role": "user", "content": "Where is order 8841?"}]
response = client.messages.create(
model="claude-sonnet-5-5", max_tokens=1024, tools=tools, messages=messages
)
if response.stop_reason == "tool_use":
messages.append({"role": "assistant", "content": response.content})
results = []
for block in response.content:
if block.type == "tool_use":
output = get_order_status(**block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(output),
})
messages.append({"role": "user", "content": results})
response = client.messages.create(
model="claude-sonnet-5-5", max_tokens=1024, tools=tools, messages=messages
)
print(response.content[-1].text)
एक टर्न के सभी tool_result एक ही यूज़र मैसेज में भेजें। उन्हें अलग-अलग मैसेज में बाँटने से मॉडल सीख लेता है कि टूल्स को समानांतर में कॉल करना बंद कर दे।
Claude MCP Connector
MCP कनेक्टर के दो हिस्से चाहिए: mcp_servers में सर्वर, और tools में एक मेल खाती mcp_toolset एंट्री। इसके लिए एक beta header भी चाहिए, और यह लोकल stdio सर्वरों के बजाय रिमोट सर्वरों तक HTTP से पहुँचता है।
चारों की तुलना करें। MCP वाले संस्करण छोटे हैं, क्योंकि schema और लूप आपके कोड से बाहर चले गए। इसकी कीमत नियंत्रण है: आप लूप API को सौंप देते हैं और सर्वर अपने बारे में जो भी कहे उस पर भरोसा करते हैं।
सिक्योरिटी और लागत के जाल जिन पर नज़र रखें
भरोसे के बिना टूल विवरण
टूल के नाम, विवरण और रिज़ल्ट, सब मॉडल के कॉन्टेक्स्ट में जाते हैं। कोई लापरवाह या दुर्भावनापूर्ण सर्वर उनमें निर्देश छिपा सकता है, और यह एक प्रॉम्प्ट इंजेक्शन का रास्ता है। सादे function calling में भी टूल रिज़ल्ट के साथ यही जोखिम है, लेकिन MCP इसे बढ़ाता है क्योंकि विवरण थर्ड पार्टी लिखती हैं।
केवल भरोसेमंद सर्वर कनेक्ट करें, और जहाँ संभव हो वर्ज़न पिन करें।
लिखने, भेजने या मिटाने वाले हर एक्शन पर इंसानी अप्रूवल रखें।
हर सर्वर को सबसे सीमित क्रेडेंशियल दें जो अब भी काम करे।
हर कॉल को उसके arguments के साथ लॉग करें।
लंबी टूल सूचियों की टोकन लागत
हर डेफ़िनिशन हर अनुरोध पर इनपुट टोकन के रूप में भेजी जाती है। लंबे विवरण वाले चालीस टूल, यूज़र के एक शब्द बोलने से पहले ही हज़ारों टोकन जोड़ सकते हैं। MCP इसे अनजाने में आसान बना देता है, क्योंकि कोई सर्वर जोड़ते ही उसके सारे टूल एक साथ आ जाते हैं।
तीन उपाय अच्छा काम करते हैं:
किसी खास काम के लिए केवल ज़रूरी सर्वर जोड़ें।
विवरण को उतना ही छोटा करें जितना मॉडल को टूल चुनने के लिए जानना ज़रूरी है।
डेफ़िनिशन को ज़रूरत पड़ने पर लोड करें, जैसे Claude के tool search tool से, और सूची का स्थिर हिस्सा कैश होने लायक रखें।
💡 आम गलतियाँ: हर अनुरोध में हर सर्वर जोड़ना, लिखने वाले एक्शन को अपने-आप अप्रूव करना, और कॉल लॉग छोड़ देना। इनमें से हर एक से पहले दिन बचना आसान है, और किसी घटना के बाद ठीक करना महँगा।
कब कौन सा चुनें
Function Calling कब चुनें
आपके पास एक ही ऐप द्वारा इस्तेमाल होने वाले कुछ टूल्स हैं।
टूल्स को आपकी अपनी स्थिति, जैसे डेटाबेस सेशन या लॉग-इन यूज़र, तक इन-प्रोसेस पहुँच चाहिए।
आप लेटेंसी, रीट्राई और अप्रूवल स्क्रीन पर पूरा नियंत्रण चाहते हैं।
आप प्रोटोटाइप बना रहे हैं और सबसे कम हिस्सों वाला सेटअप चाहते हैं।
MCP कब चुनें
कई क्लाइंट्स को वही टूल्स चाहिए: एक चैट ऐप, एक IDE, और एक एजेंट।
कोई थर्ड पार्टी पहले से उस सेवा के लिए MCP सर्वर देती है, जिसकी आपको ज़रूरत है।
टूल्स और ऐप्स अलग-अलग टीमों के पास हैं, और उन्हें एक-दूसरे को रोकना नहीं चाहिए।
आप टूल ग्लू दोबारा लिखे बिना मॉडल प्रोवाइडर बदलना चाहते हैं।
ज़्यादातर प्रोडक्शन स्टैक अंत में मिले-जुले बनते हैं। निजी लॉजिक इन-प्रोसेस function tools के रूप में रहता है, और साझा या थर्ड-पार्टी क्षमताएँ MCP सर्वरों के ज़रिए आती हैं। दोनों एक ही function-calling इंटरफ़ेस से मॉडल तक पहुँचते हैं, इसलिए इन्हें मिलाने की लागत लगभग शून्य है।
एक असली MCP सर्वर: PicassoIA
PicassoIA अपनी इमेज और वीडियो जनरेशन एक MCP कनेक्टर के ज़रिए एक्सपोज़ करता है, जो ऊपर बताए डिज़ाइन विकल्पों का एक उपयोगी उदाहरण है। जनरेशन में समय लगता है, इसलिए टूल्स को स्टार्टर्स और स्टेटस चेक में बाँटा गया है। यह वही शेप है जो आप दो function डेफ़िनिशन से हाथ से बनाते।
कनेक्टर क्या एक्सपोज़ करता है
टूल
यह क्या करता है
generate_image
एक इमेज जॉब शुरू करता है और prediction ID लौटाता है
edit_image
मौजूदा इमेज का एडिट शुरू करता है
generate_video_picassoia
PicassoIA वीडियो मॉडल के साथ एक वीडियो जॉब शुरू करता है
generate_video_seedance
Seedance के साथ एक वीडियो जॉब शुरू करता है
get_generation
Prediction तब तक पोल करता है जब तक वह सफल या विफल न हो जाए
list_generations
पिछली जनरेशन की सूची दिखाता है
cancel_generation
उस जॉब को रद्द करता है जो अब भी कतार में या चल रही है
list_models
दिखाता है कि आपका अकाउंट कौन से मॉडल इस्तेमाल कर सकता है
get_account
आपका प्लान और समानांतर सीमाएँ दिखाता है
यह पैटर्न अपने सर्वरों में कॉपी करने लायक है: जल्दी ID लौटाएँ, एक अलग टूल से पोल करें, और मॉडल को एक cancel टूल दें ताकि वह खराब रन से पीछे हट सके। डेवलपर डॉक्स बताते हैं कि हर अकाउंट के लिए 5 एक साथ चलने वाले predictions हैं, जो API क्रेडेंशियल और MCP कनेक्शन के बीच साझा हैं, इसलिए एक अच्छा व्यवहार करने वाला क्लाइंट सब कुछ एक साथ भेजने के बजाय पोल करता है। वही जॉब https://api.picassoia.com/v1 पर Replicate-शैली REST API के ज़रिए भी उपलब्ध हैं। कौन से प्लान API और MCP एक्सेस शामिल करते हैं, यह जानने के लिए प्राइसिंग पेज देखें।
PicassoIA पर Claude Sonnet 5 का इस्तेमाल कैसे करें
कोड जोड़ने से पहले, आप Claude Sonnet 5 पेज पर टूल schemas और टेस्ट प्रॉम्प्ट का ड्राफ़्ट बना सकते हैं। मॉडल पेज ये इनपुट दिखाता है:
प्रॉम्प्ट: अनुरोध लिखें, जैसे: "get_order_status नाम के एक टूल के लिए JSON Schema लिखें, जो एक ऑर्डर ID ले और शिपिंग स्टेटस लौटाए।"
System prompt (वैकल्पिक): एक बार भूमिका तय करें, जैसे "आप एक API डिज़ाइनर हैं। केवल JSON में जवाब दें।"
Effort: डिफ़ॉल्ट low है, जो सबसे तेज़ और सस्ते जवाबों के लिए थिंकिंग बंद रखता है। किसी जटिल मल्टी-फ़ाइल बग या कई टूल्स वाले डिज़ाइन के लिए high या max पर जाएँ। स्तर low, medium, high, xhigh और max हैं।
Max tokens: डिफ़ॉल्ट 8192 है, जो पूरे schema और व्याख्या के लिए काफ़ी है।
Image (वैकल्पिक): अतिरिक्त संदर्भ के रूप में किसी एरर का स्क्रीनशॉट या वायरफ़्रेम अटैच करें।
चलाएँ और तुलना करें: वही प्रॉम्प्ट GPT 5 को भेजें और देखें कि कौन सा schema ज़्यादा साफ़ है।
💡 टिप: पहले schema माँगें, फिर मॉडल से उसके अपने विवरण की समीक्षा करवाएँ। छोटे, विशिष्ट विवरण टूल को सही ढंग से चुने जाने में आसान बनाते हैं।
Picasso IA के साथ अपनी इमेज बनाएँ
इस लेख की हर फ़ोटो एक टेक्स्ट प्रॉम्प्ट से शुरू हुई: एक पेगबोर्ड, एक स्विचबोर्ड, एक कार्ड कैटलॉग, एक पगडंडी का काँटा। हर एक अमूर्त विचार को कुछ ऐसा बनाती है जिसे आप देख सकें, और वही तरीका आपकी अपनी पोस्ट, डॉक्स और स्लाइड डेक के लिए भी काम करता है।
इस ढाँचे का इस्तेमाल करें: सब्जेक्ट और एक्शन, परिवेश, रोशनी, कैमरा और लेंस, टेक्सचर के विवरण। उदाहरण के लिए: "ओक की मेज़ पर लैपटॉप में केबल लगाते हुए हाथ का क्लोज़-अप, दाईं ओर से नरम खिड़की की रोशनी, 100mm मैक्रो लेंस, शैलो डेप्थ ऑफ़ फ़ील्ड, ब्रश किए हुए एल्युमिनियम का टेक्सचर।"
Picasso IA खोलें, पूरी मॉडल सूची से एक टेक्स्ट-टू-इमेज मॉडल चुनें, उस ढाँचे में एक प्रॉम्प्ट चिपकाएँ और चलाएँ। एक बार में एक विवरण बदलें, जैसे लेंस या रोशनी की दिशा, और देखें कि नतीजा कैसे बदलता है। अगर आप पहले से Claude में काम करते हैं, तो अपने अकाउंट से PicassoIA MCP कनेक्टर जोड़ें और चैट से सीधे इमेज माँगें। आज ही एक विचार के तीन वैरिएशन आज़माएँ और सबसे अच्छा रखें।