docs: refresh translations for recent English changes (#3379)

This commit is contained in:
Max 2026-08-24 19:29:54 +01:00 • committed by GitHub
commit c5d7d0b6d0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 3149 additions and 1047 deletions

View file

@ -1,25 +1,25 @@
---
translation:
sections: [e33d441f12d50535, 7099694c603e0f5f, c1df4cf9673433e6, c9cd294541422e6e, 6cec073617bfd037, efa92b8f99e908c8, 6a22a29e27fb4601]
sections: [7be05607887e6853, e7375894888d9750, c36f73fc7e3af13b, 2fec2d7e129e62fe, 809b0e0a7c27295a, b4395a04d2a5d906, 1a436007f5f54779, c6b2078ed1e63ba5]
tool: 1
---
# errors संभालना {#handling-errors}
tool दो तरीकों से fail हो सकता है, और SDK दोनों के साथ बहुत अलग बर्ताव करता है।
tool तीन तरीकों से fail हो सकता है, और SDK हर एक के साथ अलग बर्ताव करता है।
साधारण exception raise करें तो उसे **model** देखता है। `MCPError` raise करें तो उसे **protocol** देखता है।
`ToolError` raise करें तो आपका message **model** देखता है। `MCPError` raise करें तो उसे **protocol** देखता है। कुछ और raise करें तो वह crash है: model को सिर्फ़ इतना पता चलता है कि call fail हुआ, और traceback आपके log में जाता है।
यह page इन दोनों में से चुनने के बारे में है।
यह page इनमें से चुनने के बारे में है।
## ऐसा error जिसे model ठीक कर सकता है {#an-error-the-model-can-fix}
ऐसा tool लें जो कुछ खोजता है, और खोज को नाकाम होने दें:
```python title="server.py" hl_lines="11-12"
```python title="server.py" hl_lines="2 12-13"
--8<-- "docs_src/handling_errors/tutorial001.py"
```
उन दो lines में MCP जैसा कुछ नहीं है। `get_author` सादा `ValueError` raise करता है, जैसे कोई भी Python function करता।
`mcp.server.mcpserver.exceptions` से आने वाला `ToolError` वह तरीका है जिससे tool model को बताता है कि कुछ गड़बड़ हुई।
इसे ऐसे title से call करें जो catalog में नहीं है और result देखें:
@ -30,13 +30,15 @@ result.structured_content # None
```
* request **सफल रही**। result मौजूद है; caller की तरफ़ कुछ raise नहीं हुआ।
* `is_error` `True` है, और आपके exception का message (आगे tool का नाम लगा हुआ) `content` में है, ठीक वहीं जहाँ model पढ़ता है।
* `is_error` `True` है, और आपका message (आगे tool का नाम लगा हुआ) `content` में है, ठीक वहीं जहाँ model पढ़ता है।
* `structured_content` `None` है। fail हुए call के पास structure करने को कोई return value नहीं होती।
यह **tool error** है, और आपका tool **कोई भी** exception raise करे, default यही है। और लगभग हमेशा आप यही चाहते भी हैं।
यह **tool error** है, और लगभग हमेशा आप यही चाहते हैं।
आपके tool को call करने वाला model ही है। arguments उसी ने चुने। इसलिए tool error बातचीत का एक turn है: model *"No book titled 'Nothing' in the catalog."* पढ़ता है, समझ जाता है कि उसने title का गलत अंदाज़ा लगाया, और बेहतर title के साथ फिर call करता है। आपने एक `raise` लिखा और बदले में खुद को सुधारने वाला agent मिल गया।
server पर `ToolError` log में बस एक `INFO` line है, बिना traceback के। इसका आपको पहले से अंदाज़ा था, इसलिए जाँचने को कुछ नहीं है।
!!! tip
tool से कभी error message `return` न करें। लौटाई गई string का `is_error=False` होता है, इसलिए
model को (और हर client UI को) लगता है कि tool ठीक चला और वही string जवाब थी।
@ -44,7 +46,7 @@ result.structured_content # None
## ऐसा error जिसे model ठीक नहीं कर सकता {#an-error-the-model-cannot-fix}
अब `ValueError` की जगह `MCPError` रखें।
अब `ToolError` की जगह `MCPError` रखें।
```python title="server.py" hl_lines="1 3 14"
--8<-- "docs_src/handling_errors/tutorial002.py"
@ -77,10 +79,10 @@ result.structured_content # None
दोनों रास्ते दो अलग-अलग सवालों का जवाब देते हैं।
* **कोई भी exception raise करें** जब नाकामी **execution** की हो: आपके tool ने जो करने की कोशिश की, वह नहीं हुआ। call model ने चुना था, इसलिए नतीजा भी model को दिखना चाहिए और उसे संभलने का मौका मिलना चाहिए। गलत वर्तनी वाला title, timeout हो गया upstream API, ऐसी row जो मौजूद नहीं: सब tool errors।
* **`ToolError` raise करें** जब नाकामी **execution** की हो: आपके tool ने जो करने की कोशिश की, वह नहीं हुआ। call model ने चुना था, इसलिए नतीजा भी model को दिखना चाहिए और उसे संभलने का मौका मिलना चाहिए। गलत वर्तनी वाला title, timeout हो गया upstream API, ऐसी row जो मौजूद नहीं: सब tool errors।
* **`MCPError` raise करें** जब **request खुद** ठुकराई जानी चाहिए: client के पास वह capability नहीं जिस पर आपका tool निर्भर है, server किसी को भी serve करने की हालत में नहीं है, caller ने कोई ज़रूरी चरण छोड़ दिया। model का कोई retry इनमें से किसी को ठीक नहीं करता, इसलिए उसे message थमाने से कुछ हासिल नहीं।
एक सवाल से फ़ैसला हो जाता है: **क्या ज़्यादा समझदार model इससे बच सकता था?** हाँ -> साधारण exception। नहीं -> `MCPError`।
एक सवाल से फ़ैसला हो जाता है: **क्या ज़्यादा समझदार model इससे बच सकता था?** हाँ -> `ToolError`। नहीं -> `MCPError`।
इस कसौटी पर `get_author` के दूसरे version ने गलत चुनाव किया: बेहतर title से बात बन जाती है, इसलिए model message देखने का हक़दार था। वह version आपको mechanism दिखाने के लिए है, उसकी सिफ़ारिश करने के लिए नहीं।
@ -89,6 +91,25 @@ result.structured_content # None
`data` payload लेता है। इनमें आप जो भी रखें, client को वही मिलता है: SDK raise किए गए
`MCPError` को sanitise करने के बजाय जस का तस आगे भेज देता है।
## कोई और exception {#any-other-exception}
अब check हटा दें और dictionary lookup को अपने आप fail होने दें:
```python title="server.py" hl_lines="11"
--8<-- "docs_src/handling_errors/tutorial004.py"
```
`CATALOG[title]` `KeyError` raise करता है। आपने इसकी कोई योजना नहीं बनाई थी, इसलिए SDK इसे crash मानता है:
```python
result.is_error # True
result.content # [TextContent(text="Error executing tool get_author")]
```
call अब भी `is_error=True` लौटाता है, इसलिए model जानता है कि वह fail हुआ और आगे बढ़ सकता है। जो उसे नहीं मिलता वह है exception का text: आपके code का `KeyError`, या तीन libraries नीचे के किसी driver से आया SQL का ढेर, आपके server की अंदरूनी बातें बयान कर सकता है, इसलिए वह server से बाहर कभी नहीं जाता।
वह आपको मिलता है। server crash को पूरे traceback के साथ `ERROR` पर log करता है, `Tool 'get_author' raised an unexpected exception` के रूप में। इसलिए `WARNING` पर चलने वाला production log हर `ToolError` के दौरान चुप रहता है और जैसे ही कुछ सच में टूटता है, बोल उठता है।
## ऐसा resource जो मौजूद नहीं है {#a-resource-that-doesnt-exist}
resources भी यही रेखा खींचते हैं, और आम मामले के लिए एक नाम वाला exception साथ देते हैं।
@ -109,7 +130,7 @@ resources भी यही रेखा खींचते हैं, और आ
}
```
ध्यान दें, यहाँ कोई `is_error=True` वाला आधा-अधूरा result नहीं है। resource read या तो contents लौटाता है या fail होता है: resources के पास सिर्फ़ protocol वाला रास्ता है। templates और resources के बारे में बाकी सब कुछ **[Resources](resources.md)** में है।
ध्यान दें, यहाँ कोई `is_error=True` वाला आधा-अधूरा result नहीं है। resource read या तो contents लौटाता है या fail होता है: resources के पास सिर्फ़ protocol वाला रास्ता है। `ResourceError` वही चीज़ है ऐसी नाकामी के लिए जो "not found" नहीं है (`-32603`, आपका message), और दोनों आपके log में एक `INFO` line हैं। `MCPError` को छोड़कर कोई भी और exception crash है: client को `-32603` मिलता है जिसमें सिर्फ़ URI का नाम होता है, और traceback `ERROR` पर आपके log में जाता है। templates और resources के बारे में बाकी सब कुछ **[Resources](resources.md)** में है।
## ऐसे errors जो आप कभी raise नहीं करते {#errors-you-never-raise}
@ -120,19 +141,21 @@ resources भी यही रेखा खींचते हैं, और आ
इसका मतलब है `raise` statements की एक पूरी श्रेणी जो आपको लिखनी नहीं पड़ती: अपने ही type hints को दोबारा validate न करें।
!!! info
इस page पर सब कुछ वही है जो **client** को दिखता है, और जिस in-memory `Client` से आप
tests लिखेंगे, उसे भी ठीक यही दिखता है। `raise_exceptions=True` भी tool error को वापस
traceback में नहीं बदलता: जब तक वह flag कुछ कर पाता, आपका exception पहले ही
`is_error=True` result बन चुका होता है। result पर assert करें। **[Testing](../get-started/testing.md)** में यह pattern बताया गया है।
इस page पर जो कुछ **client** को दिखता है, वह उस in-memory `Client` को भी दिखता है जिससे आप
tests लिखेंगे। `raise_exceptions=True` भी fail होते tool का exception caller को वापस नहीं
थमाता: जब तक वह flag कुछ कर पाता, आपका exception पहले ही `is_error=True` result बन चुका
होता है। result पर assert करें। crash का traceback चाहिए तो वह server के log में है, और
pytest का `caplog` उसे capture कर लेता है। **[Testing](../get-started/testing.md)** में यह pattern बताया गया है।
## सारांश {#recap}
* tool में **कोई भी exception** raise करें -> call `is_error=True` लौटाता है, `content` में आपके message के साथ। model उसे पढ़ता है और retry कर सकता है। यही default है।
* tool में **`ToolError`** raise करें -> call `is_error=True` लौटाता है, `content` में आपके message के साथ। model उसे पढ़ता है और retry कर सकता है।
* **`MCPError`** raise करें -> call खुद JSON-RPC error के साथ fail हो जाता है। model को कुछ नहीं दिखता; host इससे निपटता है। `code`, `message`, और `data` जस के तस बचे रहते हैं।
* फ़ैसला करने वाला सवाल: **क्या ज़्यादा समझदार model इससे बच सकता था?** हाँ -> exception। नहीं -> `MCPError`।
* फ़ैसला करने वाला सवाल: **क्या ज़्यादा समझदार model इससे बच सकता था?** हाँ -> `ToolError`। नहीं -> `MCPError`।
* कोई भी **और exception** crash है -> model के लिए `is_error=True` जिसमें सिर्फ़ `Error executing tool <name>`, और आपके लिए traceback वाला `ERROR` record।
* resource handler से `ResourceNotFoundError` -> protocol का `-32602`, `data` में URI के साथ।
* गलत arguments आपका function चलने से पहले ही schema के आधार पर ठुकरा दिए जाते हैं; उनके लिए आप `raise` नहीं करते।
* `from mcp import MCPError`; error-code constants `mcp.types` से आते हैं।
* Imports: `from mcp import MCPError`, `from mcp.server.mcpserver.exceptions import ToolError, ResourceError, ResourceNotFoundError`, और error-code constants `mcp.types` से।
errors संभल गए। server जो कुछ **expose** करता है, वह सब यही है। हर handler क्या पढ़ सकता है, और चलते-चलते client के साथ वापस क्या कर सकता है, यह अगला section है: **[आपके handler के अंदर](../handlers/index.md)**।

View file

@ -1,6 +1,6 @@
---
translation:
sections: [496394d24d221bf1, 4ceb4591180dc6c3, 0fd63e4682d02e0c, 969ede0bd3686a16, 043f526230dd243d, 6ee3e9bcfd24047a]
sections: [496394d24d221bf1, 4ceb4591180dc6c3, 0fd63e4682d02e0c, 969ede0bd3686a16, 864137b5e9c61e91, 043f526230dd243d, db1ef91db7d6b3f3]
tool: 1
---
# Media {#media}
@ -86,6 +86,24 @@ result.structured_content # None
MP3 bytes से `Audio` बनाएँ तो client को `mime_type="audio/wav"` बताया जाता है, और फिर
वह ईमानदारी से उसे decode करने में नाकाम रहता है। जब `data=` दें, तो `format=` भी दें।
## resource embed करना {#embedding-a-resource}
tool एक document भी लौटा सकता है: कुछ text या bytes, साथ में वह URI जहाँ वह रहता है और एक MIME type। यह **`EmbeddedResource`** है, content block की एक और किस्म। सादे `str` के उलट यह client को बताता है कि content क्या है, ताकि client उसे attachment की तरह दिखा सके या ऐसे resource को पहचान सके जिसे वह पहले से जानता है।
```python title="server.py" hl_lines="7 14 16-18"
--8<-- "docs_src/media/tutorial005.py"
```
* `brand://guidelines` एक साधारण resource है (इनके बारे में **[Resources](resources.md)** बताता है)। माँगे जाने पर tool वही document model को सौंपता है, और `guidelines()` को सीधे call करने से सच का एक ही स्रोत बना रहता है।
* `EmbeddedResource` और `TextResourceContents` `mcp.types` से आते हैं। images जैसा कोई helper यहाँ नहीं है: जो block आप बनाते हैं वह बिना छुए result में जाता है, और कोई `structured_content` नहीं होता।
* वही URI इस्तेमाल करें जिसके तहत resource register है, ताकि client बता सके कि attachment और `brand://guidelines` एक ही document हैं। कोई भी URI मान्य है, register हो या न हो।
```python
result.content # [EmbeddedResource(type="resource", resource=TextResourceContents(uri="brand://guidelines", mime_type="text/markdown", text="# Brand guidelines\n\n..."))]
```
binary content के लिए `TextResourceContents` की जगह `BlobResourceContents(uri=..., mime_type=..., blob=...)` इस्तेमाल करें, जिसमें bytes base64-encoded होकर `blob` में जाते हैं। सिर्फ़ एक pointer भेजना हो, जिसे client बाद में `resources/read` कर सके, तो उसकी जगह `ResourceLink(name=..., uri=...)` लौटाएँ; यह भी content block ही है।
## Icons {#icons}
`Icon` metadata है, content नहीं। इसमें image नहीं होती; यह URI से किसी image की ओर इशारा करता है, और client उसे fetch करके आपके server के नाम, किसी tool, resource या prompt के बगल में दिखा सकता है।
@ -115,6 +133,7 @@ tool के icons `tools/list` से मिले `Tool` object पर हो
* tool से `Image` या `Audio` लौटाएँ तो client को `ImageContent` / `AudioContent` block मिलता है: आपके bytes base64-encoded, MIME type के साथ।
* इसे `path=` से बनाएँ और suffix को MIME type तय करने दें, या in-memory `data=` और स्पष्ट `format=` से बनाएँ।
* result में कोई document (text या base64 blob, उसके URI और MIME type के साथ) डालने के लिए `EmbeddedResource` लौटाएँ, या सिर्फ़ pointer भेजने के लिए `ResourceLink`।
* media results में न `structured_content` होता है, न output schema।
* `Icon` एक pointer है: `src` URI और साथ में optional `mime_type`, `sizes` और `theme`।
* `icons=[...]` server पर, tools पर, resources पर और prompts पर काम करता है, और clients इन्हें संबंधित objects पर पाते हैं।

View file

@ -1,6 +1,6 @@
---
translation:
sections: [d65c098f37f5b6c3, dd0c2724d6f2877e, 6835bb3570c6714c, ffe823cb0fedd488, f33651add1b59094]
sections: [d65c098f37f5b6c3, dd0c2724d6f2877e, 6835bb3570c6714c, d30d3c20168b88b2, f5ef38dad59d6f76, 6e38a699ba57fbdf, 2b984a3bf37a0ddd]
tool: 1
---
# Prompts {#prompts}
@ -112,9 +112,9 @@ Code review एक message है। Debugging session एक बातचीत
आख़िरी message पर ध्यान दें। `assistant` turn पहले से भरना ही वह तरीका है जिससे आप model के **अगले** जवाब की दिशा तय करते हैं, बिना user से वह निर्देश खुद type करवाए।
## Titles और argument descriptions {#titles-and-argument-descriptions}
## titles और argument descriptions {#titles-and-argument-descriptions}
`review_code` function का नाम है, label नहीं। Client को button पर लगाने के लिए कुछ बेहतर दें, और हर argument का description लिखें ताकि form खुद ही समझ में आ जाए:
`review_code` function का नाम है, label नहीं। client को button पर लगाने के लिए कुछ बेहतर दें, और हर argument का description लिखें ताकि form खुद ही समझ में आ जाए:
```python title="server.py" hl_lines="10-13"
--8<-- "docs_src/prompts/tutorial003.py"
@ -139,17 +139,64 @@ Code review एक message है। Debugging session एक बातचीत
```
!!! info
अगर आपने **[Tools](tools.md)** पढ़ लिया है, तो इस page की हर बात आप पहले से जानते हैं। वही decorator, वही
अगर आपने **[Tools](tools.md)** पढ़ लिया है, तो यहाँ तक की हर बात आप पहले से जानते हैं। वही decorator, वही
docstring-as-description, वही `Annotated`/`Field`। बदलता सिर्फ़ इतना है कि इसे
trigger कौन करता है (user) और result कहाँ जाता है (बातचीत में)।
## सिर्फ़ text ही नहीं {#more-than-text}
`UserMessage` और `AssistantMessage` जहाँ भी `str` लेते हैं, वहाँ content block या `Image` / `Audio` helper भी ले लेते हैं। prompts में दो मामले सामने आते हैं: document जोड़ना और तस्वीर जोड़ना।
### file embed करना {#embedding-a-file}
```python title="server.py" hl_lines="5 12 21 23"
--8<-- "docs_src/prompts/tutorial004.py"
```
* style guide `style://python` पर एक resource है (**[Resources](resources.md)** में इनकी बात है), जो `server.py` के बगल में रखी `style-guide.md` से पढ़ा जाता है। वहाँ कोई भी Markdown file रख दें।
* `EmbeddedResource(resource=TextResourceContents(...))`, दोनों `mcp.types` से, file को उसके URI और MIME type के साथ पहले message के रूप में ले जाता है; उसका ज़िक्र करने वाली request उसके बाद plain text के रूप में आती है।
* guide को f-string में चिपकाने के बजाय embed करने से client उसे attachment की तरह दिखा सकता है और बाद में `style://python` फिर से खोल सकता है, और model को file ज्यों की त्यों मिलती है। binary file के लिए base64 `blob` के साथ `BlobResourceContents` इस्तेमाल करें।
render होने पर पहले message का `content` एक `resource` block है:
```json
{"type": "resource", "resource": {"uri": "style://python", "mimeType": "text/markdown", "text": "* Prefer early returns.\n..."}}
```
### image जोड़ना {#attaching-an-image}
```python title="server.py" hl_lines="4 15"
--8<-- "docs_src/prompts/tutorial005.py"
```
* `Image` **[Images, audio और icons](media.md)** वाला helper है। prompt render होते समय `UserMessage` इसे `ImageContent` block में बदल देता है (file base64-encoded, MIME type `.png` से अंदाज़ा लगाया गया); `Audio` इसी तरह `AudioContent` बन जाता है।
* `server.py` के बगल में `architecture.png` नाम की कोई भी PNG रख दें। prompt arguments strings होते हैं, इसलिए तस्वीर हमेशा server से आती है; `component` सिर्फ़ शब्द देता है।
```json
{"type": "image", "data": "iVBORw0KGgoAAAANSUhEUg...", "mimeType": "image/png"}
```
## runtime पर list बदलना {#changing-the-list-at-runtime}
clients जुड़े रहते हुए भी prompts जोड़े जा सकते हैं, उदाहरण के लिए ताकि user किसी निर्देश को अपनी खुद की menu entry के रूप में save कर सके। prompt register करें, फिर notify करें:
```python title="server.py" hl_lines="5 23-27"
--8<-- "docs_src/prompts/tutorial006.py"
```
* `mcp.add_prompt(Prompt.from_function(fn, name=..., description=...))` किसी function को ठीक वैसे ही register करता है जैसे `@mcp.prompt()` करता, और `mcp.remove_prompt(name)` इसका उल्टा है। `add_prompt` उसी नाम की मौजूदा entry को overwrite करने के बजाय बनाए रखता है, इसलिए tool पहले कोई भी पुरानी entry हटा देता है ताकि save करना replace बन जाए। `prompts/list` बदलाव तुरंत दिखाती है।
* `await ctx.notify_prompts_changed()` हर उस `2026-07-28` client को `notifications/prompts/list_changed` भेजता है जो `subscriptions/listen` stream पर सुन रहा हो (**[Subscriptions](../handlers/subscriptions.md)**)। `await ctx.session.send_prompt_list_changed()` इसे call करने वाले client को भेजता है, जब वह client 2026 से पहले का हो (**[legacy clients को serve करना](../run/legacy-clients.md)**)। दोनों call करें; जब बताने के लिए कोई न हो तो दोनों में से कोई कुछ नहीं करता।
* जिस client को notification मिलता है, वह `prompts/list` फिर से call करता है। Python `Client` में यह `async with client.listen(prompts_list_changed=True) as sub:` है, जो `PromptsListChanged` event देता है।
## सारांश {#recap}
* Function पर `@mcp.prompt()` लगाने से वह prompt बन जाता है। नाम function से, description docstring से।
* Prompts **user-controlled** हैं: client इन्हें list करता है, user कोई एक चुनता है और arguments भरता है।
* Arguments named strings की flat list हैं (कोई schema नहीं)। Default वाला parameter optional है।
* `str` लौटाएँ और वह एक user message बन जाता है। Multi-turn बातचीत की शुरुआत करने के लिए `UserMessage` / `AssistantMessage` की list लौटाएँ।
* function पर `@mcp.prompt()` लगाने से वह prompt बन जाता है। नाम function से, description docstring से।
* prompts **user-controlled** हैं: client इन्हें list करता है, user कोई एक चुनता है और arguments भरता है।
* arguments named strings की flat list हैं (कोई schema नहीं)। default वाला parameter optional है।
* `str` लौटाएँ और वह एक user message बन जाता है। multi-turn बातचीत की शुरुआत करने के लिए `UserMessage` / `AssistantMessage` की list लौटाएँ।
* `title=` और `Field(description=...)` वही हैं जो client अपने UI में दिखाता है।
* कोई required argument छूट जाए तो पूरी request fail होती है। हर prompt का अलग error result नहीं होता।
* document या तस्वीर जोड़ने के लिए `EmbeddedResource` या `Image` को `UserMessage` में wrap करें।
* runtime पर `mcp.add_prompt(...)` / `mcp.remove_prompt(...)` से prompts जोड़ें या हटाएँ, फिर `await ctx.notify_prompts_changed()` और `await ctx.session.send_prompt_list_changed()` call करें।
Prompt के (या resource template के) arguments के लिए server-side autocomplete **[Completions](completions.md)** में है।
prompt के (या resource template के) arguments के लिए server-side autocomplete **[Completions](completions.md)** में है।

View file

@ -1,6 +1,6 @@
---
translation:
sections: [a838d57f003aed44, 857d03886a0137ed, 42d9efcb9f542867, 2290ff08435b5573, e866c192e11d1c14, 6cdbad079f7b47f0, d4b607372fb28b51, 18dbf726ac45e0b7, c6f7d2a148aa49f4, c851964bb3301907, d715db6f8dccc9cc, ef86634aa70498a7]
sections: [a838d57f003aed44, 857d03886a0137ed, 42d9efcb9f542867, 2290ff08435b5573, 91be9b73602abcf1, 6cdbad079f7b47f0, d4b607372fb28b51, 18dbf726ac45e0b7, c7eff2a5698225fa, c851964bb3301907, 8f296f1f09e4c400, d715db6f8dccc9cc, a0c344a48450dbe4]
tool: 1
---
# Structured output {#structured-output}
@ -105,7 +105,7 @@ result.structured_content # {"temperature": 16.2, "humidity": 0.83, "conditions
--8<-- "docs_src/structured_output/tutorial003.py"
```
runtime पर `TypedDict` सादा `dict` होता है, इसलिए आप वही बनाते और लौटाते हैं। schema, validation और `structured_content` ठीक `BaseModel` वाले version जैसे हैं (descriptions को छोड़कर, जिनके लिए `TypedDict` में कोई जगह नहीं)।
runtime पर `TypedDict` सादा `dict` होता है, इसलिए आप वही बनाते और लौटाते हैं। schema, validation और `structured_content` उन्हीं नियमों पर चलते हैं जिन पर `BaseModel` वाला version चलता है: class docstring या `Annotated[..., Field(description=...)]` जोड़ें और वही descriptions बन जाते हैं, और जो `NotRequired` key आप dict में नहीं डालते, वह `structured_content` से भी बाहर रहती है।
## Dataclass {#a-dataclass}
@ -187,18 +187,19 @@ keys का `str` होना ज़रूरी है। `dict[int, float]` J
annotation `WeatherData` का वादा करता है। upstream response ने `humidity` भेजना बंद कर दिया।
!!! check
`get_weather` को call करें और यह चुपचाप client को आधा-खाली object नहीं थमाता। call fail होता है,
और error की पहली lines field का नाम बताती हैं:
`get_weather` को call करें और यह चुपचाप client को आधा-खाली object नहीं थमाता। call fail होता है:
client को `Error executing tool get_weather` के साथ `is_error=True` मिलता है, ताकि model को पता रहे कि
call fail हुआ है, बजाय इसके कि वह पूरे भरोसे से ऐसा मौसम पढ़े जो है ही नहीं। field का नाम आपके लिए है,
server log में `ERROR` पर:
```text
Error executing tool get_weather: 1 validation error for WeatherData
Tool 'get_weather' raised an unexpected exception
...
pydantic_core._pydantic_core.ValidationError: 1 validation error for WeatherData
humidity
Field required [type=missing, input_value={'temperature': 16.2, 'conditions': 'Overcast'}, input_type=dict]
```
यह text `is_error=True` के साथ tool result बनकर लौटता है, ताकि model को पता रहे कि call fail हुआ है,
बजाय इसके कि वह पूरे भरोसे से ऐसा मौसम पढ़े जो है ही नहीं।
वैसे, `-> WeatherData` वाले tool से सादा `dict` लौटाना ठीक है। `json.loads` ने ठीक वही तो बनाया था। validation value पर होता है, Python type पर नहीं।
## इससे बाहर रहना {#opting-out}
@ -213,6 +214,10 @@ annotation `WeatherData` का वादा करता है। upstream res
इसका उल्टा, `structured_output=True`, automatic detection को शर्त बना देता है: जिस tool का return type schema नहीं बना सकता, वह text पर वापस आने के बजाय import के समय ही raise करता है।
## Content blocks और media {#content-blocks-and-media}
content blocks और media (`TextContent`, `EmbeddedResource`, `Image`, `Audio` वगैरह, चाहे अकेले हों, किसी `list`, `tuple` या `Sequence` के items हों, या किसी union के हिस्से हों) आपके लिए अपने आप इससे बाहर रखे जाते हैं: ये model के पढ़ने के लिए हैं, इसलिए auto-detection इनसे कोई schema नहीं बनाता (`Image` और `Audio` की जानकारी **[Images, audio और icons](media.md)** में है)। content-block classes के लिए `structured_output=True` फिर भी schema बनवा देता है।
## बिना type hints वाली class {#a-class-without-type-hints}
बिना माँगे unstructured रह जाने का एक तरीका है: ऐसी class लौटाना जिसकी **body पर कोई annotations न हों**।
@ -245,6 +250,6 @@ annotation `WeatherData` का वादा करता है। upstream res
* scalars, lists, tuples और unions `{"result": ...}` में wrap होते हैं। models, `TypedDict`, dataclasses, annotated classes और `dict[str, ...]` पहले से object हैं और जैसे हैं वैसे ही रहते हैं।
* हर result में `content` (text, model के लिए) **और** `structured_content` (data, application के लिए) होता है।
* आप जो लौटाते हैं वह schema के मुक़ाबले validate होता है। मेल न खाना tool error है, ख़राब result नहीं।
* `structured_output=False` tool को इससे बाहर रखता है। बिना type hints वाली class चुपचाप बाहर हो जाती है; इस पर नज़र रखें।
* `structured_output=False` tool को इससे बाहर रखता है। content blocks, `Image` और `Audio` default रूप से बाहर रहते हैं; बिना type hints वाली class चुपचाप बाहर हो जाती है, इसलिए इस पर नज़र रखें।
अब tool जो कुछ भी जवाब में कह सकता है, वह सब आपके हाथ में है। आगे, दूसरा primitive: **[Resources](resources.md)**।

View file

@ -1,6 +1,6 @@
---
translation:
sections: [e4cc390d56573409, 8566e2b68594e9ad, 2c97b9f888398951, 048e5471dfa71aea, 3076b1e16ad95950, edbedf2a16e71311, 3d8ef8da89fa87c1, f6c0e02e6ea5a363]
sections: [e4cc390d56573409, f30cf8103a6e918c, 2c97b9f888398951, 048e5471dfa71aea, 3076b1e16ad95950, edbedf2a16e71311, 3d8ef8da89fa87c1, f6c0e02e6ea5a363]
tool: 1
---
# Tools {#tools}
@ -39,6 +39,8 @@ translation:
दोनों arguments `required` में हैं क्योंकि किसी का भी default नहीं है। इसे आप थोड़ी ही देर में ठीक करेंगे। (`title` keys Pydantic की देन हैं; properties, उनके types और `required` ही असली contract हैं।)
`$schema` key भी नहीं है: जिस schema में यह न हो उसे MCP **JSON Schema 2020-12** मानता है, और Pydantic यही बनाता है, इसलिए चुनने को कुछ नहीं है जब तक आप **[low-level Server](../advanced/low-level-server.md#the-dialect-is-json-schema-2020-12)** पर हाथ से schemas न लिखें।
!!! tip
यहाँ type hints documentation नहीं हैं। वे ही **contract** हैं। अगर कोई client `"limit": "ten"` भेजता है,
तो SDK उसे आपके function के चलने से पहले ही reject कर देता है।

View file

@ -1,6 +1,6 @@
---
translation:
sections: [4a7033e1ed8ad602, 55dcbfff0c6271bf, 101ef9d14bf4ec46, 4b6c4a845438abc7, f98b46bafbee4acd]
sections: [4a7033e1ed8ad602, 55dcbfff0c6271bf, 317f4256a650cab6, 4b6c4a845438abc7, f98b46bafbee4acd]
tool: 1
---
# URI templates और path safety {#uri-templates-and-path-safety}
@ -115,7 +115,7 @@ template parameters client से आते हैं। अगर वे बि
built-in जाँचें आम मामलों को रोकती हैं लेकिन आपकी sandbox सीमा नहीं जान सकतीं। filesystem access के लिए, path resolve करने और यह पक्का करने के लिए कि वह आपकी base directory के अंदर ही रहे, `safe_join` इस्तेमाल करें:
```python title="server.py" hl_lines="4 14"
```python title="server.py" hl_lines="5 15"
--8<-- "docs_src/uri_templates/tutorial002.py"
```
@ -146,7 +146,7 @@ configure की जा सकने वाली जाँचें:
`safe_join` ही containment boundary बना रहता है।
!!! tip
अगर आपका handler request पूरी नहीं कर सकता (file मौजूद नहीं है, id अनजान है), तो exception raise करें। SDK उसे error response में बदल देता है। protocol error और tool error के बीच के फ़र्क़ के लिए **[errors संभालना](handling-errors.md)** देखें।
अगर आपका handler request पूरी नहीं कर सकता (file मौजूद नहीं है, id अनजान है), तो `ResourceNotFoundError` raise करें, जैसा ऊपर `read_manual` करता है। client को आपके message और URI के साथ `-32602` मिलता है। कोई अनपेक्षित exception इसकी जगह generic `-32603` बन जाता है। **[errors संभालना](handling-errors.md#a-resource-that-doesnt-exist)** देखें।
## Low-level Server पर resources {#resources-on-the-low-level-server}