# MCP tool name collisions और सुरक्षित एजेंट व्यवहार

एजेंट MCP टूल catalog को उस सावधानी से नहीं पढ़ता, जिस तरह कोई अनुभवी इंजीनियर SDK पढ़ता है। वह संक्षिप्त निर्देश से संभावित कार्रवाई तक पहुँचता है। अगर आप उसे `get_user`, `get_users`, `user_lookup` और `admin_get_user` दें और फिर इन्हें अलग करने के लिए केवल सावधानियों वाला एक पैराग्राफ लिखें, तो आपने authority के चारों ओर अनुमान लगाने का खेल बना दिया है।

MCP tool name collisions केवल ऐसे duplicate identifiers नहीं हैं, जिनकी वजह से कोई client catalog को अस्वीकार कर दे। इससे भी गंभीर collision semantic होता है: दो callable actions एक जैसी लगती हैं, लेकिन एक व्यापक system तक पहुँचती है, अधिक अधिकार वाला credential इस्तेमाल करती है या state बदलती है। मैंने टीमों को एजेंट द्वारा गलत action चुनने के बाद इसे prompting issue कहते देखा है। ज़्यादातर मामलों में यह interface issue होता है, जिसे उन्होंने खुद production में भेजा था।

इसका समाधान कोई विशाल taxonomy या औपचारिक naming committee नहीं है। हर action का ऐसा नाम रखें, जो बताए कि वह क्या करता है, कहाँ करता है और उसकी authority कितनी दूर तक जाती है। फिर ऐसे descriptions लिखें, जो उस सीमा को स्पष्ट करें जिसे नाम अकेले नहीं बता सकता। Ambiguity को tests में तब दिखा दें, जब वह approval card, अनपेक्षित API call या उलझी हुई incident review में बदलने से पहले हो।

## Collision पहले semantic होता है, syntactic बाद में

Syntactic collision तब होता है, जब दो MCP servers `search` नाम का टूल प्रकाशित करते हैं। Client के आधार पर एक entry दूसरी को overwrite कर सकती है, namespace ज़रूरी हो सकता है या catalog confusing बन सकता है। इसे ठीक करें, क्योंकि अलग-अलग clients में behavior अलग हो सकता है।

Semantic collision तब भी बना रहता है, जब हर identifier तकनीकी रूप से unique हो। इन tools पर विचार करें:

```text
search_customer
search_customer_records
lookup_customer
customer_admin_search
```

Compiler के लिए चारों valid हो सकते हैं और उन्हें बनाने वाली टीम के लिए समझने योग्य भी। लेकिन जब एजेंट से कहा जाए, «Maya Chen का customer record ढूँढकर उसका address अपडेट करो», तो ये नाम routing के लिए कमजोर संकेत देते हैं। एजेंट को अनुमान लगाना पड़ता है कि सही जानकारी किस system में है, action read-only है या नहीं, क्या वह पूरे tenant में खोज सकता है और क्या administrative credential का उपयोग उचित है।

Vague catalog को tool schemas भी नहीं बचाते। मॉडल argument names देख सकता है, लेकिन समान schemas ambiguity को और बढ़ा सकते हैं। Read-only directory search और production CRM search, दोनों `query`, `limit` और `organization_id` स्वीकार कर सकते हैं। एक केवल data लौटाता है, जबकि दूसरा enrichment शुरू कर सकता है या audit event लिख सकता है। यह फर्क केवल description में मौजूद हो सकता है, जिसे मॉडल apparent task match से कम महत्व दे।

इन defects को अलग-अलग समझें:

- Identifier collision: client दो tools को लगातार और स्पष्ट रूप से प्रस्तुत नहीं कर सकता।
- Intent collision: दो tools एक ही user request पूरा करने वाले लगते हैं।
- Authority collision: व्यापक credential ऐसे टूल के पीछे है, जिसका नाम सीमित access जैसा लगता है।
- Environment collision: समान labels अलग accounts, regions या production status को छिपाते हैं।

आखिरी तीन महंगी गलतियाँ कराते हैं। Client duplicate names अस्वीकार कर सकता है। वह भरोसेमंद तरीके से यह नहीं बता सकता कि `sync_contact` का अर्थ «organization-wide token से production CRM record patch करना» है, जबकि `update_contact` का अर्थ «local test fixture में लिखना» है।

## टूल नामों में routing के लिए ज़रूरी तथ्य होने चाहिए

अच्छा नाम वे तथ्य पहले ही देता है, जिनकी मदद से एजेंट लंबा description पढ़ने से पहले चुनाव कर सके। External systems को छूने वाली actions के लिए मैं यह क्रम अपनाता हूँ: target system, object, verb, और फिर scope, अगर scope authority या परिणाम बदलता है।

`crm_contact_update`, `update_contact` से बेहतर है, क्योंकि वह system बताता है। अगर उसी catalog में sandbox भी है, तो `crm_production_contact_update` और भी बेहतर हो सकता है। `github_org_member_remove`, `manage_member` से स्पष्ट है, क्योंकि वह बताता है कि कौन-सा resource बदलेगा और नतीजा removal होगा।

हर implementation detail को नाम में न भरें। एजेंट को `crm_v3_contacts_patch_with_bearer_auth` की ज़रूरत नहीं है। उसे वे distinctions चाहिए, जो selection बदलती हैं। Versioning, transport और authentication आमतौर पर server implementation या description में होने चाहिए। Account, environment, side effect और privilege boundary अक्सर नाम में होने चाहिए।

एक व्यावहारिक pattern इस तरह दिखता है:

```text
\u003csystem\u003e_\u003cobject\u003e_\u003cverb\u003e[_\u003cscope\u003e]
```

उदाहरण:

```text
billing_invoice_get
billing_invoice_send_customer
billing_production_refund_create
source_control_repo_issue_list
source_control_org_member_remove
warehouse_inventory_adjust
warehouse_inventory_adjust_dry_run
```

यह pattern कोई कठोर नियम नहीं है। ज़रूरी बात यह है कि पास-पास रखे गए नाम उसी जगह अलग हों, जहाँ उनका effect अलग होता है। अगर `billing_invoice_send_customer` और `billing_invoice_preview_email` साथ हैं, तो verbs और objects मॉडल को बताते हैं कि कौन-सा action वास्तव में किसी व्यक्ति से संपर्क करता है। अगर फर्क केवल schema में छिपे boolean parameter में दिखता है, तो catalog routing से बहुत अधिक अपेक्षा कर रहा है।

`process`, `manage`, `handle`, `run`, `execute`, `sync` और `apply` जैसे अस्पष्ट verbs से बचें, जब तक object खुद effect को पूरी तरह स्पष्ट न कर दे। ये लोकप्रिय हैं, क्योंकि product teams इन्हें कई operations के umbrella की तरह इस्तेमाल करती हैं। यही कारण है कि ये खराब tool names हैं। मॉडल umbrella को ऐसा अधिकार समझता है, जिसमें request पूरी करने वाला सबसे व्यापक अर्थ चुना जा सकता है।

## Descriptions सीमा बताते हैं, marketing नहीं

Model Context Protocol tool specification किसी tool को name, description और input schema के साथ परिभाषित करती है। यह interface contract है, product copy लिखने की जगह नहीं। Description को चार operational सवालों का जवाब देना चाहिए: कौन-सी action होगी, कौन-सा external target उसे प्राप्त करेगा, कौन-सा scope लागू है और tool क्या करने से इनकार करता है।

इन दो descriptions की तुलना करें:

```json
{
  "name": "crm_contact_update",
  "description": "Updates customer contact information in the CRM.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "contact_id": {"type": "string"},
      "address": {"type": "string"}
    },
    "required": ["contact_id"]
  }
}
```

```json
{
  "name": "crm_production_contact_update",
  "description": "Changes address, phone, or email fields for one existing contact in the production CRM. This writes immediately. Use crm_contact_search first when the caller supplies a name rather than a contact ID. It cannot create contacts, merge records, or update more than one contact per call.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "contact_id": {
        "type": "string",
        "description": "Stable production CRM contact ID, not an email address or display name."
      },
      "changes": {
        "type": "object",
        "properties": {
          "address": {"type": "string"},
          "phone": {"type": "string"},
          "email": {"type": "string"}
        },
        "minProperties": 1,
        "additionalProperties": false
      }
    },
    "required": ["contact_id", "changes"],
    "additionalProperties": false
  }
}
```

दूसरा description एजेंट को sequence देता है, परिणाम स्पष्ट करता है और उन tempting substitutions को रोकता है जिन्हें वह चुन सकता था। यह disambiguating details को action के पास रखता है, किसी अलग operations manual में नहीं, जिसे एजेंट शायद कभी देखे ही न।

Side effects के बारे में सीधे लिखें। लिखें, «ईमेल तुरंत भेजता है», «charge बनाता है», «remote branch मिटाता है» या «production में लिखता है»। «परिवर्तनों को persist करता है» या «अनुरोधित operation करता है» न लिखें। ऐसे वाक्य reviewer को सटीक लग सकते हैं, लेकिन उस एक बात को छिपा देते हैं जिसे एजेंट और इंसान, दोनों को देखना ज़रूरी है।

Input field descriptions भी इसी कारण महत्वपूर्ण हैं। अगर कोई field resource ID स्वीकार करती है, तो बताएं कि display name मान्य नहीं है। अगर date का default UTC है, तो यह स्पष्ट करें। Optional strings वाले loose schemas अर्थ को prose में धकेल देते हैं और एजेंट को ऐसे arguments बनाने देते हैं जो parse तो हो जाएँ, लेकिन गलत अर्थ रखें।

## Broad access को कभी convenient fallback जैसा न दिखाएं

सबसे खतरनाक catalog में एक narrow tool और एक broad tool होता है, जो एक ही request पूरा करने वाले लगते हैं। Broad tool अक्सर सही कारणों से मौजूद होता है: administrator को emergency access चाहिए, migration को cross-account search चाहिए या support workflow को override चाहिए। गलती यह है कि उसे friendly name के साथ peer की तरह expose किया जाए।

इन entries की कल्पना करें:

```text
support_ticket_get
support_ticket_update
support_admin_query
```

एजेंट ticket का context चाहता है। `support_admin_query` tickets, users, billing history, internal notes और deleted records खोज सकता है। अगर उसका description «Query the support platform» से शुरू होता है, तो एजेंट उसे इसलिए चुन सकता है क्योंकि उसका व्यापक coverage उपयोगी लगता है। Tool ने वही किया, जो उसके नाम से कहा गया था। Design call से पहले ही विफल हो चुका था।

इसे rename और constrain करें:

```text
support_internal_cross_account_search
```

Description में स्पष्ट होना चाहिए कि यह accounts के बीच internal support data खोजता है, ticket record से बाहर की सामग्री लौटाता है और account boundary बताने वाले explicit instruction की माँग करता है। अगर workflow इसकी अनुमति देता है, तो free-text query अकेले स्वीकार करने के बजाय schema में account ID आवश्यक करें।

मैं flexibility के लिए एक «power tool» expose करने की सामान्य सलाह से असहमत हूँ। यह लोकप्रिय है, क्योंकि इससे server code कम होता है और अनुभवी operators कम calls में अधिक काम कर सकते हैं। Autonomous agent के लिए यह ordinary work और exceptional authority के बीच का फर्क मिटा देता है। जिन tools की authority वास्तव में अलग है, उन्हें अलग रखें। अधिक catalog entries उस स्थिति से सस्ती हैं, जिसमें broad search ने गलत customer history दिखा दी हो और आपको इसका कारण समझाना पड़े।

यह नियम environments पर भी लागू होता है। `environment` argument वाला `deploy` expose न करें, जिसका default production हो। जब गलत value का blast radius अलग हो, तो अलग action names का उपयोग करें:

```text
release_staging_deploy
release_production_deploy
```

Schema enum फिर भी उपयोगी है, लेकिन अलग नाम production को selection phase, approval phase और बाद के audit record में स्पष्ट बनाते हैं।

## Parameters सारी safety meaning नहीं संभाल सकते

Parameter action को तब बदलता है, जब एजेंट tool चुन चुका होता है। Name और description उस choice को प्रभावित करते हैं। Teams अक्सर इन दोनों कामों को मिला देती हैं और एक बड़े argument object वाला universal tool बना देती हैं।

यह design compact दिखता है:

```json
{
  "name": "repository_action",
  "description": "Performs repository operations.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "operation": {"enum": ["read_file", "create_branch", "delete_branch", "open_pull_request"]},
      "repository": {"type": "string"},
      "branch": {"type": "string"}
    },
    "required": ["operation", "repository"]
  }
}
```

लेकिन इसमें read operation, write operation और destructive operation को एक ही routing label के पीछे रखा गया है। एजेंट ने `repository_action` चुन लिया, तो वह meaningful boundary पार कर चुका है। Reviewer को opaque umbrella action की approval दिखाई देती है और time pressure में arguments की जाँच करनी पड़ती है।

Action class बदलने वाली जगह पर इसे अलग करें:

```text
repository_file_read
repository_branch_create
repository_branch_delete
repository_pull_request_create
```

ऐसे facts के लिए parameters रखें, जो एक ही action के भीतर बदलते हैं: repository ID, branch name, file path, commit message या page cursor। किसी parameter को यह तय न करने दें कि call read, write, send, charge, delete करेगी या production तक पहुँचेगी।

यही नियम scope पर भी लागू होता है। `scope: all_accounts` वाला `report_export` किसी harmless दिखने वाले export को cross-account extraction में बदल देता है। अगर scope यह बदलता है कि किस पर असर पड़ेगा या कौन-सा data बाहर जा सकता है, तो उसे अपना tool दें या stronger authorization path आवश्यक करें। एजेंट को authority का अंतर केवल JSON field भरने के बाद पता नहीं चलना चाहिए।

## Tool selection के लिए ambiguity test suite चाहिए

आप catalog को एक बार देखकर यह घोषित नहीं कर सकते कि वह समझने योग्य है। इसे उन requests से test करें, जो users वास्तव में करते हैं, खासकर अधूरी requests से, जिनमें एजेंट को scope का अनुमान लगाना पड़े।

हर server के लिए एक छोटी selection suite बनाएं। इसे अपने supported agent client के साथ manually चला सकते हैं या catalog और prompts को controlled evaluation harness में दे सकते हैं। चुना गया tool, proposed arguments और यह रिकॉर्ड करें कि कोई इंसान call स्वीकार करेगा या नहीं। केवल यह score न करें कि task अंततः सफल हुआ या नहीं। जब narrow tool उपलब्ध हो, तब broad tool का सही उत्तर लौटाना भी गलत selection है।

इन जैसे prompts इस्तेमाल करें:

1. «Order 1842 का invoice ढूँढो।» Expected choice read-only billing lookup होना चाहिए, general ledger search नहीं।
2. «Priya का phone number अपडेट करो।» अगर stable contact ID नहीं है, तो एजेंट को पूछना चाहिए कि कौन-सी Priya, न कि search करके संभावित match में बदलाव करना चाहिए।
3. «Fix deploy करो।» अगर catalog में staging और production actions हैं, तो एजेंट को environment पूछना चाहिए।
4. «Alex को repository से हटाओ।» एजेंट को repository membership और organization membership में अंतर करना चाहिए।
5. «Invoice भेजो।» एजेंट को send action चुननी चाहिए, preview generator या generic invoice update call नहीं।

ऐसी adversarial wording भी जोड़ें, जो खराब tool के description जैसी लगे। अगर prompt «इस customer के बारे में हमारे पास जो कुछ भी है, सब ढूँढो» होने पर `internal_cross_account_search` जीत जाता है, तो आपका description technically honest हो सकता है, लेकिन फिर भी बहुत inviting है। सही behavior scoped search चुनना या user से account बताने को कहना हो सकता है।

Tool rename करते समय test transcript सुरक्षित रखें। यह ऐसे regressions दिखाता है, जिन्हें schema validator नहीं पकड़ सकता। Catalog valid रह सकता है, लेकिन एक मामूली rename `billing_invoice_get` को `get_invoice` में बदल सकता है, जहाँ वह purchase, logistics और legal systems से compete करेगा।

## Approval screens में action को सरल भाषा में दोहराएं

Human approval आखिरी checkpoint है, tool labels को लापरवाह बनाने की अनुमति नहीं। अगर approval में केवल `POST /v1/contacts/123` जैसा low-level request दिखे, तो approving व्यक्ति को endpoint और payload से intent का अनुमान लगाना पड़ेगा। यह उस समय पता लगाने की खराब जगह है कि एजेंट ने sandbox के बजाय production CRM चुना है।

हर layer में वही business meaning बनाए रखें। Tool name `crm_production_contact_update` कहता है। Description कहता है कि यह एक existing production record में तुरंत लिखता है। Approval में कहना चाहिए कि एजेंट एक production contact के एक named field को बदलना चाहता है, उपलब्ध होने पर target account दिखाना चाहिए और प्रस्तावित changed values भी दिखानी चाहिए। Audit event में tool identity के साथ actual executed channel और target सुरक्षित रहने चाहिए।

Approval wording को action से अधिक reassuring न बनाएं। «Allow CRM update» phone number ठीक करने और account recovery के लिए इस्तेमाल होने वाला email address बदलने के बीच का फर्क छिपा देता है। Meaningful arguments दिखाएं और secrets हटाएं। अगर किसी argument में sensitive customer data है, तो data handling rules का पालन करते हुए review के लिए पर्याप्त structure दिखाएं।

Sallyport का per-session authorization यह तय कर सकता है कि कोई विशेष agent process अपने run के दौरान action ले सकता है, जबकि per-call keys ऐसे credentials के हर उपयोग पर अलग approval माँग सकती हैं, जिनकी जाँच हर बार ज़रूरी है। यह विभाजन तब सबसे अच्छा काम करता है, जब action labels approving व्यक्ति को तुरंत और सही रूप से बता दें कि एजेंट क्या माँग रहा है।

## Credentials और tool identity अलग समस्याएँ हल करते हैं

Credentials को एजेंट से बाहर रखने पर एक आम failure रुकता है: एजेंट API key को log, source file, issue या chat reply में copy नहीं कर सकता, क्योंकि secret उसे मिलता ही नहीं। लेकिन इससे हर request सुरक्षित नहीं हो जाती। एजेंट अब भी gateway से legitimate credential के साथ गलत tool चलाने को कह सकता है।

Design के दौरान इन सवालों को अलग रखें:

- क्या एजेंट credential प्राप्त या expose कर सकता है?
- क्या एजेंट user के intended scope से बाहर की action माँग सकता है?
- क्या इंसान देख सकता है कि action किस process ने माँगी?
- क्या run के बाद investigator यह verify कर सकता है कि क्या हुआ?

Tool catalog दूसरे सवाल को address करता है। Session identity और approvals तीसरे को। Tamper-evident record चौथे को। हर layer का अपना काम है और कोई layer दूसरी का विकल्प नहीं है।

Sallyport HTTP और SSH credentials को अपने encrypted vault में रखता है और agent को secret दिए बिना action execute करता है। इससे credential exposure घटता है, लेकिन एजेंट को ऐसा catalog फिर भी चाहिए, जिसके नाम उसे केवल इसलिए broad action माँगने से रोकें, क्योंकि उसका नाम पर्याप्त रूप से मिलता-जुलता लगा।

यह फर्क तब महत्वपूर्ण है, जब teams कहती हैं, «एजेंट token देख नहीं सकता, इसलिए tool सुरक्षित है।» Token सुरक्षित हो सकता है, लेकिन action फिर भी overpowered हो सकती है। Read-only reporting credential और production refund credential को लगभग एक जैसी entries के पीछे नहीं रखना चाहिए, भले ही दोनों model से isolated हों।

## Namespaces operators की मदद करते हैं, लेकिन vague actions को सही नहीं ठहराते

कई clients server-derived prefix के साथ tools दिखाते हैं, जैसे `crm.search_contacts` या `billing.search_contacts`। अगर आपका client support करता है, तो namespace का उपयोग करें। इससे एजेंट और operator को एक अतिरिक्त routing clue मिलता है और literal duplicate names कम होते हैं।

फिर भी इसे अकेला clue न बनाएं। Clients labels छोटे कर सकते हैं, server catalogs को flatten कर सकते हैं या ऐसे server names दिखा सकते हैं, जिनका approval पढ़ने वाले व्यक्ति के लिए कोई खास अर्थ न हो। `search_contacts` तब भी अस्पष्ट रहेगा, जब एक server test database और दूसरा live customer data तक पहुँचता हो।

बेहतर pair यह है:

```text
crm_production_contact_search
marketing_audience_contact_search
```

जब client prefix जोड़ता या हटाता है, तब भी ये नाम समझने योग्य रहते हैं। समय के साथ एजेंट अधिक servers से जुड़ने पर mixed catalogs भी इनसे सुरक्षित रहते हैं।

Server boundaries का उपयोग related authority को group करने के लिए करें, उसे छिपाने के लिए नहीं। `operations` नाम का server, जो billing refunds, production deployment, customer export और personnel changes expose करता है, उसे own करने वाली team के लिए convenient हो सकता है। लेकिन इससे unrelated verbs वाला crowded catalog और व्यापक credential surface बनता है। जब अलग domains के owners, credentials, approval expectations या review paths अलग हों, तो servers को अलग करें।

## Catalog review deployment से पहले failures पकड़ लेता है

Tool catalog की review natural-language tasks की सूची के साथ करें, अकेले नहीं। Author को obvious लगने वाला नाम अक्सर ऐसे context पर निर्भर होता है, जो छह servers के तीस tools एक agent session में आने पर गायब हो जाता है।

नई action ship करने से पहले यह छोटी review करें:

1. केवल नाम पढ़ें। क्या कोई व्यक्ति external system, object, side effect और unusual scope समझ सकता है?
2. इसे हर समान tool के पास रखें। क्या किसी नाम में broader access को softer verb के साथ बताया गया है?
3. Description को मन से हटा दें। क्या schema read और write, sandbox और production या single-record और cross-account के बीच का चुनाव किसी argument में छिपा रहा है?
4. कोई ambiguous user request पूछें। क्या एजेंट को clarifying question पूछना चाहिए, और क्या आपने guessing से बेहतर उस विकल्प को बनाया है?
5. Approval और audit labels जाँचें। क्या वे tool name जैसा ही distinction बनाए रखते हैं?

सही उत्तर अक्सर convenient catch-all action की request अस्वीकार करना होता है। यह refusal implementation के दौरान किसी एक व्यक्ति को एक बार परेशान करता है। Ambiguous tool उन लोगों को परेशान करता है, जिन्हें बाद में unexpected call की जाँच करनी पड़ती है, जब context पहले ही गायब हो चुका होता है।

नाम को specific रखें, boundary को सरल भाषा में लिखें और broad authority को गलती से चुनना कठिन बनाएं। एजेंट को अधिक plausible choices की ज़रूरत नहीं है। उसे permission को दूसरी permission समझ लेने के कम रास्तों की ज़रूरत है।
