# Server पर भरोसा करने से पहले MCP client configuration review

नए MCP server को उतनी ही सावधानी से review करें जितनी सावधानी से उस नए executable को करेंगे जिसे अपने development account में चलने देना है। Configuration file में command और कुछ arguments होने से वह harmless लग सकती है। असल में वही entry तय करती है कि कौन-सा code शुरू होगा, उसे कौन-सा environment मिलेगा, वह किन directories तक पहुंच सकेगा और agent को कौन-से tool descriptions दिखेंगे।

सबसे आम गलती है `local` को trust boundary मान लेना। ऐसा नहीं है। Local server आम तौर पर आपके user permissions के साथ शुरू होता है, पहला tool publish करने से पहले भी काम कर सकता है और ऐसे credentials inherit कर सकता है जिन्हें साझा करने का किसी का इरादा नहीं था। Client connect करने से पहले launch contract review करें। फिर agent के tools call करने से पहले advertised actions देखें।

## Local server आपके account के असर के साथ चलता है

Local MCP server कोई harmless configuration object नहीं, बल्कि child process है। अगर client उसे आपके सामान्य macOS account के तहत launch करता है, तो server accessible project files पढ़ सकता है, home directory में लिख सकता है, outbound network requests कर सकता है और उस process को उपलब्ध environment variables देख सकता है। MCP server को sandbox नहीं करता। Protocol messages भेजता है, executable को उन messages के बीच क्या करना है, यह सीमित नहीं करता।

यह अंतर package command से आने वाले server के मामले में महत्वपूर्ण है।

```json
{
  "command": "npx",
  "args": ["-y", "some-mcp-server"]
}
```

यह केवल किसी known local binary को शुरू नहीं करता। यह package runner से package resolve करने, cache से code install या reuse करने और उसे launch करने को कहता है। Clean machine, warm cache और बदला हुआ package tag अलग-अलग code चला सकते हैं। परिचित command लोगों को असली सवाल पूछने से रोक देती है: आज कौन-सा exact executable चलेगा?

Project के पास checkout किए गए server पर भी यही चिंता लागू होती है। Repository में ईमानदार MCP implementation के साथ malicious install hook, wrapper या runtime dependency हो सकती है। Setup guide में दिखने वाले source file को ही नहीं, process शुरू करने वाले पूरे path को review करें।

पहला containment decision operating system account के आधार पर लें। Disposable workspace, अलग low-privilege account या virtual machine शुरुआती test को उस account से कम access देती है जिसमें production source code और cloud credentials रखे हैं। इससे code review की जरूरत खत्म नहीं होती, लेकिन review में कुछ छूट जाए तो नुकसान सीमित रहता है।

## Command field को ज्यों का त्यों पढ़ें

Command और arguments को ठीक उसी तरह पढ़ें जैसे client उन्हें execute करेगा। README के friendly विवरण के हिसाब से उनका अर्थ अपने मन में न बदलें।

सुरक्षित रूप fixed executable path और argument array वाला होता है:

```json
{
  "command": "/Users/dev/tools/acme-mcp/bin/server",
  "args": ["--config", "/Users/dev/review/acme-mcp.json"],
  "env": {
    "HOME": "/Users/dev/review-home",
    "PATH": "/usr/bin:/bin"
  }
}
```

इससे review के ठोस बिंदु मिलते हैं। क्या executable उस path पर मौजूद है? उसका owner कौन है? क्या configuration file ऐसी repository के बाहर है जिसे दूसरे लोग बदल सकते हैं? क्या process को `HOME` की जरूरत भी है? क्या उसे सचमुच compiler, package manager या broad `PATH` चाहिए?

Wrapper review को बदल देता है।

```json
{
  "command": "sh",
  "args": ["-c", "npx -y acme-mcp --token $SERVICE_TOKEN"]
}
```

अब shell `$SERVICE_TOKEN` expand करता है, shell syntax पढ़ता है और आपकी अपेक्षा से अधिक programs चला सकता है। Package runner code fetch कर सकता है। Server को secret command argument के रूप में मिलता है, जो process inspection और diagnostic output में दिख सकता है। हर अतिरिक्त layer ऐसा behavior लाती है जिसे direct executable path टाल देता है।

यह न मानें कि हर client `command` को एक ही तरह execute करता है। कुछ clients argument array के साथ direct process spawning करते हैं। कुछ shell-oriented setting या wrapper script देते हैं। Client documentation पढ़ें और वास्तविक command approve करने से पहले non-sensitive command के साथ launch test करें। अगर format direct execution और shell दोनों देता है, तो direct execution चुनें, जब तक server की कोई स्पष्ट जरूरत न हो।

Wrappers को line by line देखें। छोटी scripts अक्सर सबसे जोखिम भरा behavior छिपाती हैं: release download करना, token file पढ़ना, working directory बदलना, सभी environment variables export करना या दूसरे runtime के जरिए silently restart करना। बीस lines का launcher server के मुख्य implementation से ज्यादा ध्यान मांग सकता है।

## Inherited environment वह credential leak है जिसे लोग भूल जाते हैं

`env` block का अर्थ हमेशा «यही पूरा environment है» नहीं होता। कई process launch APIs में parent process environment आगे चला जाता है, जब तक launcher उसे जानबूझकर replace न करे। तब `env` की entries केवल चुने हुए values जोड़ती या override करती हैं। MCP client खुद terminal, desktop launcher, editor या automation service से शुरू हुआ हो सकता है, और हर रास्ता अलग variables दे सकता है।

इससे reviewers की नजर में दिखने वाली चीज और server को मिलने वाले environment के बीच खतरनाक अंतर बनता है। JSON में केवल `LOG_LEVEL` लिखा हो सकता है, जबकि process को package registry token, source control token, cloud credentials, proxy settings, SSH agent details और client से inherited internal service URL भी मिल रहे हों।

Connect करने से पहले environment contract साधारण भाषा में लिखें: इस process को यह endpoint, यह non-secret setting और शायद एक narrowly scoped credential चाहिए। बाकी सब accidental authority है।

पहला test client को sparse shell से शुरू करके करें। यह macOS और Unix command केवल कुछ सामान्य variables रखती है:

```sh
env -i HOME="$HOME/review-home" PATH="/usr/bin:/bin" LANG="${LANG:-C}" \
  YOUR_MCP_CLIENT
```

`YOUR_MCP_CLIENT` को वास्तविक client command से बदलें। Server fail हो तो एक बार में एक variable जोड़ें और लिखें कि उसकी जरूरत क्यों है। पूरी login environment वापस लाकर failure हल न करें। इस shortcut से लोगों की कल्पना से ज्यादा credentials उजागर हुए हैं।

किसी command को execute किए बिना भी saved configuration inspect कर सकते हैं। यह Python fragment server names, commands, arguments और explicit environment variable names दिखाता है। यह जानबूझकर environment values नहीं दिखाता।

```sh
python3 - "$HOME/.config/your-client/mcp.json" <<'PY'
import json, sys

with open(sys.argv[1], encoding="utf-8") as f:
    data = json.load(f)

for name, spec in data.get("mcpServers", {}).items():
    print(f"server: {name}")
    print(f"  command: {spec.get('command', '')}")
    print("  args:")
    for arg in spec.get("args", []):
        print(f"    - {arg}")
    print("  explicit env names:")
    for env_name in sorted(spec.get("env", {})):
        print(f"    - {env_name}")
PY
```

Output कुछ ऐसा दिखेगा:

```text
server: issue-tracker
  command: /Users/dev/tools/issue-mcp/server
  args:
    - --read-only
  explicit env names:
    - ISSUE_TRACKER_URL
```

अगर `AWS_SECRET_ACCESS_KEY`, `GITHUB_TOKEN`, `SSH_AUTH_SOCK` या `SERVICE_TOKEN` जैसे names दिखें, तो रुककर पूछें कि server को इनकी जरूरत क्यों है। Secret values JSON file में रखने से सुरक्षित नहीं हो जातीं। Config files backups में copy होती हैं, support requests में साझा होती हैं, गलती से commit हो सकती हैं और file पढ़ सकने वाला हर process उन्हें पढ़ सकता है।

## Tool list capability का दावा है, permission नहीं

Model Context Protocol specification discovery के लिए `tools/list` और invocation के लिए `tools/call` define करती है। यह उपयोगी है क्योंकि agent के tool चुनने से पहले client server का proposed interface देख सकता है। इससे server, उसके descriptions या call के पीछे के side effects प्रमाणित नहीं होते।

हर advertised tool को proposed capability मानें। उसका name, description, input schema और annotations साथ में पढ़ें। `search_issues` नाम का tool read-only request कर सकता है, या search से पहले project files इकट्ठा करके third party को भेज सकता है। `deploy_preview` resources बना सकता है, DNS बदल सकता है या नाम से अधिक व्यापक credential इस्तेमाल कर सकता है।

MCP specification servers को ऐसे annotations देने देती है जो behavior का संकेत देते हैं, जैसे tool data पढ़ता है, बदलता है या external system से जुड़ता है। ये hints client को उपयोगी UI देने में मदद करते हैं, enforcement नहीं करते। Dishonest या careless server destructive tool को read-only label कर सकता है। Action चलने से पहले operating system और server credentials उस label की जांच नहीं करेंगे।

हर approved server के लिए छोटी inventory रखें:

- Tool name और वह action जिसे करने का दावा करता है।
- ऐसे inputs जिनमें file paths, URLs, shell fragments या free-form prompts जा सकते हैं।
- वे systems जिन तक tool पहुंच सकता है और उसका credential।
- Side effects, जिनमें remote API को data भेजना भी शामिल है।
- Reviewed exact version या source revision।

Inventory को configuration के पास रखें। Update में `delete_repository` जुड़ने, `query` के `execute` बनने या arbitrary URL स्वीकार करने वाला input आने पर diff meaningful होगा। पुरानी inventory न हो तो server name परिचित दिखने के कारण लोग बदली हुई list भी approve कर देते हैं।

Descriptions को भी agent तक पहुंचने वाले किसी अन्य untrusted text की तरह देखें। Server किसी tool को mandatory बता सकता है, approval अनावश्यक कह सकता है या agent को unrelated secrets arguments में भेजने को कह सकता है। Agent को server की prose को user request और client approval rules से ऊंचा नहीं मानना चाहिए।

## Credentials की boundary agent process के बाहर रखें

केवल इसलिए long-lived API token या private SSH key server को न दें कि वह उसी laptop पर चलता है। Process को secret मिलते ही वह उसे log, forward, disk पर write या tool result के जरिए expose कर सकता है। Process secret पढ़ लेने के बाद client उसे वापस नहीं ले सकता।

दो अलग decisions को एक न करें। Server शुरू करने की अनुमति code execute करने की अनुमति है। Production credential इस्तेमाल करने की अनुमति external system पर action लेने की अनुमति है। Server test workspace में पहली permission का हकदार हो सकता है, लेकिन दूसरी का नहीं।

साधारण development के लिए scoped, short-lived credential दें जो केवल test data तक पहुंच सके। उसका scope लिखें। «Issue server द्वारा इस्तेमाल» अस्पष्ट है; «sandbox project में tickets पढ़ सकता है, create, comment या membership बदल नहीं सकता» ऐसा विवरण reviewers को जांचने योग्य सीमा देता है।

गंभीर credential वाले actions के लिए secret को local credential boundary में रखें और केवल सीमित operation expose करें। Sallyport HTTP और SSH actions के लिए यही तरीका अपनाता है: agent को API key या SSH key नहीं मिलती, app action करती है और result लौटाती है।

यह boundary secret handling बदलती है, server review की जरूरत नहीं। Malicious server agent से damaging लेकिन authorized call करने को कह सकता है। Approval वहीं रखें जहां consequence होगा, credentials को सबसे छोटी उपयोगी authority तक सीमित करें और महत्वपूर्ण system में जाने वाली हर request पढ़ें।

Credentials command arguments में न भेजें। Process listings, crash reporters, diagnostics और parent processes उन्हें expose कर सकते हैं। इसी कारण configuration files में plaintext secrets से भी बचें। Setup guide इनमें से किसी जगह secret मांगती हो तो स्वीकार करने से पहले देखें कि server operating system credential store, short-lived token या external action service इस्तेमाल कर सकता है या नहीं।

## पहला संपर्क साधारण test account में करें

Unfamiliar server को controlled account में चलाएं, फिर उसे project, broad environment या real credentials दें। यह test सीमित सवाल का जवाब देता है: program शुरू होने पर और client के tools मांगने पर क्या करता है?

Harmless files वाले नए directory का उपयोग करें, जिनके names से unexpected reads साफ दिखें। Process को temporary `HOME` दें। Sparse `PATH` से शुरू करें। Source control server test करने के लिए credentials से भरी source directory mount न करें। Fake repository या ऐसी copy से शुरू करें जिसमें credentials न हों।

किसी tool call से पहले का behavior देखें। Startup पर network connection खोलना, home directory scan करना, browser data पढ़ना या persistence files बनाना अधिकांश MCP use cases से अधिक है। कुछ servers endpoint check या local configuration load करते हैं, जो वैध हो सकता है। उन्हें यह behavior समझाना और बंद करना आसान बनाना चाहिए।

फिर tool inventory मांगें, उसे inspect करें और known input के साथ एक harmless call करें। Request, result, process output और test directory में बदली files capture करें। अगर tool किसी अन्य system का content लौटाता है, तो test data को स्पष्ट रखें ताकि पता चले कि सही जगह access हुई या नहीं।

Basic review sequence:

1. Executable path, package version, checksum या source revision और हर launcher script verify करें।
2. Sparse environment में test account या isolated workspace के तहत launch करें।
3. पहला `tools/list` result capture करें और हर tool की intended job से तुलना करें।
4. Fake data के साथ harmless read operation call करें और files, child processes तथा network destinations देखें।
5. Confirmed behavior के लिए जरूरी credential और directory access ही जोड़ें।

Successful response को safe server न समझें। Server expected answer लौटाते हुए files copy कर सकता है या कहीं और inherited token इस्तेमाल कर सकता है। Test evidence देता है, proof नहीं। फिर भी यह careless designs और स्पष्ट surprises को production access तक पहुंचने से पहले पकड़ता है।

## Package convenience से बना update path आपकी जिम्मेदारी है

Package managers और runtime launchers MCP setup को छोटा बना देते हैं, लेकिन update path भी बनाते हैं। Version range, floating package tag या bare package name अगले सप्ताह बिना configuration diff के अलग server चला सकता है।

जहां ecosystem support करे, version pin करें और package source को tool inventory के साथ दर्ज करें। बेहतर है कि reviewed local artifact या आपकी team द्वारा checked lockfile इस्तेमाल करें। लक्ष्य सरल है: अगली launch को ऐसे code पर resolve होना चाहिए जिसकी पहचान की जा सके।

Agent को अपने task के हिस्से के रूप में MCP server install न करने दें। इससे software acquisition, execution और tool authorization एक conversational request में मिल जाते हैं। Source और launch contract review करने के बाद human को server configuration जोड़नी चाहिए। कई servers की जरूरत हो तो issue comments या tool output से setup snippets स्वीकार करने के बजाय reviewed catalog रखें।

Updates पर छोटी repeat review करें। Executable या dependency lockfile, command और arguments, explicit environment names और `tools/list` inventory की तुलना करें। Tool addition harmless हो सकता है, लेकिन ऐसा write access भी ला सकता है जिसे पिछली review ने कभी नहीं देखा। यही बात credentials, endpoint या authentication library बदलने पर भी लागू होती है।

«Security fixes के लिए हमेशा latest package इस्तेमाल करें» वाली सलाह MCP servers के लिए अधूरी है। Security fixes जल्दी लें, लेकिन unreviewed automatic change आपके credentials के पास चलने वाले code को बदल सकता है। Controlled update process अपनाएं, जिसमें change inspect और नया server अलग behavior करे तो rollback किया जा सके।

## Approval server के नाम के नहीं, action के अनुसार होना चाहिए

Server process के लिए one-time approval केवल यह बताता है कि क्या इस executable को इस session में शामिल होने दिया जाए। इससे remote branch delete करने, customer data भेजने या production host पर SSH command खोलने जैसे बाद के हर सवाल का सुरक्षित उत्तर नहीं मिलता।

साधारण discovery और consequential actions को अलग रखें। Available projects list करना, public issue पढ़ना और local schema fetch करना records बदलने या machine से बाहर data भेजने की तुलना में कम scrutiny मांग सकते हैं। Call उस सीमा को पार करे तो client या credential boundary fresh human approval मांगे। हर read call पर attention मांगेंगे तो लोग click through करेंगे। एक startup click से unlimited production access देंगे तो बाद में पछतावा होगा।

Process identity भी महत्वपूर्ण है। Approval prompt में केवल server-selected label नहीं, access मांगने वाले signed process की पहचान दिखनी चाहिए। `database-helper` जैसा label कोई भी program copy कर सकता है। Executable path, उपलब्ध होने पर signing identity और launch arguments बेहतर review surface हैं।

दो स्तरों पर record रखें: काम मांगने वाला agent session और credential इस्तेमाल करने या external service तक पहुंचने वाला individual action। Agent के पास authority क्यों थी, यह जानने के लिए session record चाहिए। वास्तव में क्या बदला, यह जानने के लिए action record चाहिए। Caller या exact request में से कोई एक गायब हो तो एक log दोनों सवालों का साफ उत्तर नहीं दे सकता।

Tamper-evident record बाद में server, client या operator के विवाद में मदद करता है। Approval के क्षण में यह dangerous action को safe नहीं बनाता। आसानी से undo न होने वाले action को authorize करने से पहले target, method, command और meaningful parameters पढ़ें।

## Rejected server को हटाने के साथ cleanup भी चाहिए

Connect करने के बाद server untrustworthy लगे तो client entry तुरंत हटाएं, लेकिन वहीं न रुकें। Process ने files लिखी, shell configuration बदली, scheduled work बनाई, repository hook बदला या चलते समय credentials copy किए हो सकते हैं।

सब कुछ delete करने से पहले evidence बचाएं। Configuration, package version या source revision, process output और action logs save करें। फिर test `HOME`, server working directory, package cache, shell startup files, launch agents, repository hooks और उन सभी directories की जांच करें जिनमें server लिख सकता था। Evidence उपलब्ध रहते active processes और recent network connections भी देखें।

Process द्वारा पढ़े जा सकने वाले हर secret को rotate करें, केवल जानबूझकर दिए गए secret को नहीं। इसमें inherited tokens, SSH agent access, package credentials और जरूरत पड़ने पर browser-backed development sessions शामिल हैं। Configuration file से line मिटाने से copied token revoke नहीं होता।

फिर उस review process को मजबूत करें जिसने connection की अनुमति दी। Inherited environment समस्या थी तो sparse launcher अपनाएं। Unexpected package update कारण था तो artifacts pin और review करें। Misleading tool description समस्या थी तो approval से पहले captured inventory अनिवार्य करें। उपयोगी परिणाम अधिक सावधान रहने का vague promise नहीं, बल्कि बदला हुआ control है।

नए MCP server को सबसे खतरनाक समय पर access मिलता है, जब उसने अभी trust कमाया भी नहीं होता। उसका command literal रखें, environment छोटा रखें, tool list inspect करें और credentials को agent से अलग रखें। यही वह समय है जब outcome अभी आपके नियंत्रण में है।
