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
18 changed files with 3149 additions and 1047 deletions

View file

@ -1,6 +1,6 @@
---
translation:
sections: [2c79b6338e09b7ac, 7edc43b3fae11314, 1086e77ce561cd7f, a3f71823df5efc31, 9fc7109f72201cae, 7bf25983df655b66, 6330e1f4c6029683, 2f1749c8c133fa1c, b3530fcf4d11fd56, ebc33704fbd74262, cd0e9c933350390e]
sections: [2c79b6338e09b7ac, 7edc43b3fae11314, 1086e77ce561cd7f, a3f71823df5efc31, 9fc7109f72201cae, d50fe7faead8cf68, 7bf25983df655b66, 6330e1f4c6029683, 2f1749c8c133fa1c, 8db7116fc8ddd0ee, ebc33704fbd74262, cd0e9c933350390e]
tool: 1
---
# Düşük seviyeli Server {#the-low-level-server}
@ -116,6 +116,17 @@ Bu genellenebilir. Düşük seviyeli bir işleyiciden fırlatılan istisna **her
Sunucu bu iki alanı asla karşılaştırmaz. Bu SDK'nın `Client`'ı karşılaştırır: bildirdiğiniz `output_schema`'yı karşılamayan bir `structured_content` döndürün, `call_tool` `Invalid structured content returned by tool search_books` ile başlayıp `jsonschema` hatasını alıntılayarak devam eden bir `RuntimeError` fırlatır. Bir şema vaat etmek ucuzdur; sözünüzü tutmak size kalır. Dönüş türleri ve şemaların tüm basamakları **[Yapılandırılmış çıktı](../servers/structured-output.md)** sayfasında.
## Lehçe: JSON Schema 2020-12 {#the-dialect-is-json-schema-2020-12}
`input_schema` ve `output_schema` birer JSON Schema'dır ve lehçeyi [MCP belirtimi](https://modelcontextprotocol.io/specification/latest/basic#json-schema-usage) sabitler: `$schema` anahtarı olmayan bir şema **JSON Schema 2020-12**'dir. `MCPServer`'ın ürettiği şemalar bu varsayılana dayanır (Pydantic 2020-12 yazar ve anahtarı koymaz); elle yazılmış bir dict de aynı kurala tabidir. Yani 2020-12 söz dağarcığının tamamı kullanılabilir:
```python title="server.py" hl_lines="8 14-15"
--8<-- "docs_src/lowlevel/tutorial007.py"
```
* `input_schema`'nın kökü `"type": "object"` olmalıdır. Onun yanında `oneOf`, `additionalProperties`, `anyOf`, `if`/`then`/`else`, `prefixItems`, yerel `$ref`'lerle `$defs` ve 2020-12 anahtar sözcüklerinin geri kalanı istemciye tam yazıldığı gibi ulaşır.
* `$schema` anahtarı gerekmez. Yalnızca daha eski bir taslağı seçmek için ekleyin: `structured_content`'i bir aracın `output_schema`'sına göre doğrulayan bu SDK'nın `Client`'ı, doğrulayıcısını `$schema`'ya göre seçer ve hiç yoksa 2020-12 kullanır.
## `_meta`: model için değil, uygulama için {#\_meta-for-the-application-not-the-model}
`content`, yanıtın modelin okuduğu kısmıdır. `structured_content`, aynı yanıtın tür bilgisi taşıyan veri halidir. `_meta` üçüncü kanaldır: yanıtın hiçbir şekilde parçası olmadan, **istemci uygulama** için sonuçla birlikte yolculuk eden veri.
@ -167,7 +178,7 @@ Yapıcı, MCP'nin tanımladığı metotları kapsar. `add_request_handler` geri
--8<-- "docs_src/lowlevel/tutorial006.py"
```
* İlk argüman metot dizesidir. Bildirimlerin bir ikizi vardır: `add_notification_handler`.
* İlk argüman metot dizesidir. Bildirimlerin bir ikizi vardır: `add_notification_handler`. Onun işleyicileri stdio'da ve el sıkışma neslinden HTTP bağlantılarında tetiklenir; `2026-07-28` Streamable HTTP yolunda istemcinin bildirim POST'u `202` ile onaylanır ve işleyiciye iletilmez, çünkü o revizyon HTTP üzerinden istemciden sunucuya hiçbir bildirim tanımlamaz.
* `params_type`, gelen `params`'ın işleyiciniz çalışmadan **önce** doğrulandığı modeldir; yani özel metotlar, araçların almadığı doğrulamayı *alır*. `_meta` alanının diğer her metotta olduğu gibi ayrıştırılması için `RequestParams`'tan alt sınıf türetin.
* İşleyici bir `BaseModel`, bir `dict` ya da `None` döndürür. SDK bunu JSON-RPC sonucuna serileştirir.

View file

@ -1,6 +1,6 @@
---
translation:
sections: [6048b4f308edbb8c, 068bda0f21ee9c1b, c3e565b61acd75c5, c62422b159c6ed09, 47204fab253cc45c]
sections: [6048b4f308edbb8c, 46056f318ef205e4, c3e565b61acd75c5, c62422b159c6ed09, 420968f514138f43]
tool: 1
---
# Middleware {#middleware}
@ -21,7 +21,7 @@ Onu `async (ctx, call_next)` biçiminde yazar ve `server.middleware` listesine e
## Bir zamanlama middleware'i {#a-timing-middleware}
Bir sunucu, bir araç ve her mesajın ne kadar sürdüğünü loglayan bir middleware:
Bir sunucu, bir araç ve her mesajın ne kadar sürdüğünü log'a yazan bir middleware:
```python title="server.py" hl_lines="39-45 49"
--8<-- "docs_src/middleware/tutorial001.py"
@ -38,7 +38,7 @@ Bir sunucu, bir araç ve her mesajın ne kadar sürdüğünü loglayan bir middl
### Deneyin {#try-it}
Bir istemci bağlayın, araçları listeleyin, birini çağırın. Logunuzda **üç** satır var:
Bir istemci bağlayın, araçları listeleyin, birini çağırın. Log'unuzda **üç** satır var:
```text
server/discover took 18.3 ms
@ -53,8 +53,11 @@ istemeden önce, istemcinin bağlantıyı kurmak için gönderdiği istek.
* Bağlantı kurulumu: `server/discover` ya da eski nesil bir oturumda `initialize` ve
`notifications/initialized`.
* Her istek ve her bildirim. Bir bildirimde `ctx.request_id is None` olur,
`call_next(ctx)` `None` döndürür ve sizin döndürdüğünüz her şey atılır.
* Sunucuya ulaşan her istek ve her bildirim. Bir bildirimde
`ctx.request_id is None` olur, `call_next(ctx)` `None` döndürür ve sizin döndürdüğünüz her şey atılır.
(`2026-07-28` Streamable HTTP yolunda istemcinin bildirim POST'u aktarım katmanında `202` ile
onaylanır ve hiçbir zaman işlenmek üzere iletilmez; bu yüzden middleware'e de ulaşmaz. O revizyon
HTTP üzerinden istemciden sunucuya hiçbir bildirim tanımlamaz.)
* Sunucunun işleyicisi olmayan bir metot bile: `call_next`,
`MCPError(-32601, "Method not found")` istisnasını istemciye giderken middleware'inizin *içinden* fırlatır.
@ -110,7 +113,7 @@ aklınıza bile gelmez. Bir exporter kurana kadar hiçbir şey yapmaz ve kendi s
* Bir middleware `async (ctx, call_next) -> result` biçimindedir; `MCPServer(middleware=[...])` olarak geçirilir (ya da
`mcp.middleware` listesine eklenir), alt düzey `Server`'da ise `server.middleware` listesine eklenir.
* Gelen **her** mesajı sarar (`server/discover`, `initialize`, istekler, bildirimler,
* Sunucuya ulaşan **her** gelen mesajı sarar (`server/discover`, `initialize`, istekler, bildirimler,
bilinmeyen metotlar) ve dıştan içe doğru çalışır.
* Bir bildirimi bir istekten `ctx.request_id is None` ile ayırt edersiniz.
* Tek bir mesajı reddetmek için `call_next`'i çağırmak yerine istisna fırlatın; bağlantı ayakta kalır.

View file

@ -1,6 +1,6 @@
---
translation:
sections: [ebef1e7a0df854f4, a4c687d3d627d516, 8e79141fc2985342, b345dd05b9c3c7ab, 80ce41579825a6fa, 5f0fa90494de8f65, 83d10514eaa62fa5, 9190555aa39a5d28, 84a4c9d8bf14dddb, 927d71cf40b58c30]
sections: [ebef1e7a0df854f4, 8355cfaf1f76c9d5, 8e79141fc2985342, 46bdb07c7537e8a5, 80ce41579825a6fa, 5f0fa90494de8f65, 83d10514eaa62fa5, 9190555aa39a5d28, 84a4c9d8bf14dddb, 927d71cf40b58c30]
tool: 1
---
# İstemci {#the-client}
@ -27,9 +27,10 @@ Tek bir yaşam döngüsü olan tek bir nesnedir: oluşturun, `async with` bloğu
* Bir `MCPServer` (veya düşük seviyeli `Server`) örneği: **süreç içinde** bağlanır.
* Bir URL dizesi (`Client("http://localhost:8000/mcp")`): Streamable HTTP, yani üretim yolu.
* Bir **aktarım**: `async with ... as (read, write)` ile kullanabileceğiniz herhangi bir şey; örneğin bir alt süreci saran `stdio_client(...)`.
* Bir `StdioServerParameters`: **alt süreç** olarak başlatılacak komut; onunla stdin ve stdout'u üzerinden konuşulur.
* Bir **aktarım**: `async with ... as (read, write)` ile kullanabileceğiniz herhangi bir şey; örneğin kendi HTTP istemcinizi saran `streamable_http_client(url, http_client=...)`.
Bu sayfadaki geri kalan her şey üçünde de aynıdır. Başlıklar, alt süreçler, zaman aşımları ve `Transport` protokolünün kendi sayfası var: **[İstemci aktarımları](transports.md)**.
Bu sayfadaki geri kalan her şey dördünde de aynıdır. Başlıklar, alt süreçler, zaman aşımları ve `Transport` protokolünün kendi sayfası var: **[İstemci aktarımları](transports.md)**.
### Bağlı bir istemcide bulunanlar {#whats-on-a-connected-client}
@ -85,7 +86,7 @@ Bu şema, bir arayüzün argüman formu oluşturması için gereken her şeydir;
`call_tool(name, arguments)` aracı çalıştırır ve size bir `CallToolResult` geri verir.
```python title="client.py" hl_lines="26-33"
```python title="client.py" hl_lines="27-34"
--8<-- "docs_src/client/tutorial003.py"
```
@ -117,7 +118,7 @@ Tek dönüş değeri, okunacak üç şey. Her birinin tüketicisi farklı.
!!! check
`lookup_book`'tan `"Solaris"`'i isteyin (katalogda olmayan bir başlık); fonksiyon
`ValueError` fırlatır. Çağrı yine de normal biçimde döner:
`ToolError` fırlatır. Çağrı yine de normal biçimde döner:
```python
result.is_error # True
@ -125,9 +126,10 @@ Tek dönüş değeri, okunacak üç şey. Her birinin tüketicisi farklı.
result.structured_content # None
```
İstisnanın mesajı `content`'e düştü; **model** onu orada okuyup yeniden deneyebilir. Bu
kasıtlıdır: bir araç hatası çökme değil, konuşmanın bir parçasıdır. `structured_content`'e
güvenmeden önce her zaman `is_error`'a bakın.
`ToolError`'ın mesajı `content`'e düştü; **model** onu orada okuyup yeniden deneyebilir. Bu
kasıtlıdır: bir araç hatası çökme değil, konuşmanın bir parçasıdır. (Araç başka bir istisnayla
çökmüş olsaydı `content`'te yalnızca `Error executing tool lookup_book` yazardı.)
`structured_content`'e güvenmeden önce her zaman `is_error`'a bakın.
!!! warning
`is_error=True`, kendi `raise`'inizden fazlasını kapsar. Sunucuda hiç olmayan bir araç isteyin

View file

@ -1,6 +1,6 @@
---
translation:
sections: [9cac816674181eb0, 0700f337babcd4dd, 2bde0dd58cdf00f5, ff7401df479af877, 3d0832f39b0d7059, d4bf7e4479637768, 05e20c0a798860e7]
sections: [9cac816674181eb0, 0700f337babcd4dd, 2bde0dd58cdf00f5, 40b4916d82eaf1d4, 3d0832f39b0d7059, dfa4446556badef0, 5bd93be2ab2ecb9c]
tool: 1
---
# İstemci aktarımları {#client-transports}
@ -86,15 +86,15 @@ ortam değişkenlerini ayarlayın ya da `httpx2.AsyncClient`'ınıza açıkça b
Bir **stdio** sunucusu bir alt süreçtir. İstemci onu başlatır, stdin'ine JSON-RPC yazar ve stdout'undan JSON-RPC okur. Bir masaüstü host'un makinenizde bir sunucuyu çalıştırma biçimi budur: bir host, bu kod artı bir kullanıcı arayüzü*dür* ve **[Gerçek bir host'a bağlanma](../get-started/real-host.md)**, aynı ilişkinin host'un tarafından, bir yapılandırma dosyası olarak görülen halidir.
Süreci `StdioServerParameters` ile tanımlayın, `stdio_client` ile bir aktarıma dönüştürün ve `Client`'a *onu* verin:
Süreci `StdioServerParameters` ile tanımlayın ve `Client`'a verin:
```python title="client.py" hl_lines="4-8 12"
```python title="client.py" hl_lines="3-7 11"
--8<-- "docs_src/client_transports/tutorial004.py"
```
`Client`, parametre nesnesini tek başına kabul etmez. `StdioServerParameters` yapılandırmadır; `stdio_client(server)` ise ondan bir süreç başlatmayı bilen aktarımdır. Her zaman sarın.
Bloğa girmek süreci başlatır. Bloktan çıkmak alt süreci kapatır: stdin'i kapatır, bekler, oyalanıyorsa sonlandırır. Onu hiçbir zaman kendiniz temizlemezsiniz.
`async with` bloğundan çıkmak alt süreci de kapatır: stdin'i kapat, bekle, oyalanıyorsa sonlandır. Onu hiçbir zaman kendiniz temizlemezsiniz.
Alt sürecin stderr'i sizinkine gider. Başka bir yere göndermek için aktarımı `stdio_client` ile (`mcp` içinden) kendiniz oluşturun ve onun yerine bunu geçirin: `Client(stdio_client(server, errlog=log_file))`.
!!! warning
Alt süreç ortamınızı **devralmaz**. Minimal bir izin listesi alır (POSIX'te `HOME`, `LOGNAME`,
@ -112,16 +112,16 @@ Süreci `StdioServerParameters` ile tanımlayın, `stdio_client` ile bir aktarı
`Client` için yukarıdakilerin hepsi aynı şeydir.
Bir **aktarım**, `(read, write)` mesaj akışı çifti veren herhangi bir asenkron bağlam yöneticisidir: resmi olarak `mcp.client` içindeki `Transport` protokolü. `Client`, argümanını türüne göre çözümler: bir sunucu nesnesi süreç içinde bağlanır, bir `str` `streamable_http_client(url)` olur ve geri kalan her şeye doğrudan bir aktarım olarak girilir. `stdio_client(...)`, `streamable_http_client(...)` ve `sse_client(...)`'in hepsinin aynı yuvaya oturmasının ve kendinizinkini yazabilmenizin nedeni bu son kuraldır.
Bir **aktarım**, `(read, write)` mesaj akışı çifti veren herhangi bir asenkron bağlam yöneticisidir: resmi olarak `mcp.client` içindeki `Transport` protokolü. `Client`, argümanını türüne göre çözümler: bir sunucu nesnesi süreç içinde bağlanır, bir `str` `streamable_http_client(url)` olur, bir `StdioServerParameters` `stdio_client(params)` olur ve geri kalan her şeye doğrudan bir aktarım olarak girilir. `stdio_client(...)`, `streamable_http_client(...)` ve `sse_client(...)`'in hepsinin aynı yuvaya oturmasının ve kendinizinkini yazabilmenizin nedeni bu son kuraldır.
## Özet {#recap}
* `Client(mcp)` (sunucu nesnesi) bellek içinde bağlanır. Testler ve gömme için kullanın.
* `Client("http://.../mcp")` (bir URL), üretim aktarımı olan Streamable HTTP üzerinden bağlanır.
* Başlıklar, kimlik doğrulama, vekil sunucular ve zaman aşımları, `streamable_http_client(url, http_client=...)`'a geçirdiğiniz bir `httpx2.AsyncClient` üzerinde yer alır. `headers=` anahtar sözcüğü yoktur.
* stdio `Client(stdio_client(StdioServerParameters(...)))`'tır; asla tek başına parametre nesnesi değil.
* stdio, `Client(StdioServerParameters(...))` demektir. Onu `stdio_client(...)` ile yalnızca alt sürecin stderr'ini başka yere yönlendirmek için kendiniz sarın.
* Alt süreç sizinkini değil, izin listesine göre oluşturulmuş bir ortam alır; `env=` buna ekleme yapar.
* Bir aktarım, `async with x as (read, write)` yapabildiğiniz herhangi bir şeydir. `Client`, sunucu nesnesi ya da URL olmayan her şeyi doğrudan bu protokole verir.
* Bir aktarım, `async with x as (read, write)` yapabildiğiniz herhangi bir şeydir. `Client`, sunucu nesnesi, URL ya da `StdioServerParameters` olmayan her şeyi doğrudan bu protokole verir.
* Bir `Client` oluşturmak aktarımı seçer. Onu `async with` açar.
Aktarım açıldıktan sonra iki tarafın bir protokol sürümünde anlaşması gerekir. Normalde bunu hiç düşünmezsiniz; düşünmeniz gerektiğinde gidilecek sayfa **[Protokol sürümleri](../protocol-versions.md)**'dir.

View file

@ -1,11 +1,11 @@
---
translation:
sections: [20541a40dbdd5980, 01262a123ad9501d, 429db5b574a2ac08, 56b2d49da412cb28, 6a1717123fe4513c]
sections: [490237e61c3a7a44, 01262a123ad9501d, 429db5b574a2ac08, e2d0d273fbd2d74b, 64ab0331e868f3d4, 6c8878ce2d1f6d56, 4068f23e371bf0b3, eaef75b8725bc931]
tool: 1
---
# Kullanım dışı özellikler {#deprecated-features}
2026-07-28 spesifikasyonu beş şeyi emekliye ayırıyor. SDK hâlâ hepsini uygular ve artık her biri bir **kullanım dışı bırakma uyarısı** taşır.
2026-07-28 spesifikasyonu beş şeyi emekliye ayırıyor. SDK hâlâ hepsini uygular ve artık her biri bir **kullanım dışı bırakma uyarısı** taşır. Bir SDK yardımcısı ise kendi gerekçesiyle kullanım dışı bırakıldı ve [sayfanın sonunda](#deprecated-sdk-helpers) listeleniyor.
Aşağıdaki tablo kullanım dışı bırakılan her özelliği, neden gittiğini ve yerine neyin üzerine inşa etmeniz gerektiğini gösterir.
@ -55,6 +55,55 @@ MCPDeprecationWarning: The logging capability is deprecated as of 2026-07-28 (SE
Bu ikisi yalnızca, istemcisi eşleşen callback'i kaydetmiş bir `mode="legacy"`
bağlantısında uçtan uca çalışır.
## Eski nesil oturumda `ping` {#ping-on-a-legacy-session}
**Ping**, iki taraftan herhangi birinin karşı tarafın hâlâ yanıt verip vermediğini kontrol etmek için gönderebildiği boş bir istektir. 2026-07-28 spesifikasyonu onu kaldırır ([SEP-2575](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2575)): modern bir istemcinin gönderdiği her istek sunucunun orada olduğunu zaten kanıtlar, modern bir sunucunun ise ping gönderecek bir kanalı yoktur. Her iki SDK yöntemi de el sıkışma neslinden bir oturumda hâlâ çalışır. İstemciden:
```python
async def main() -> None:
async with Client("http://localhost:8000/mcp", mode="legacy") as client:
await client.send_ping() # warns; returns an EmptyResult
```
Sunucudan ise herhangi bir işleyicinin içinde:
```python
@mcp.tool()
async def check_client(ctx: Context) -> str:
"""A tool that still pings the client mid-call."""
await ctx.session.send_ping() # no warning; an EmptyResult while the client is connected
return "client answered"
```
* `client.send_ping()` her çağrıda `MCPDeprecationWarning` ile uyarır. Varsayılan (`2026-07-28`) bağlantıda sunucu bunun yerine `MCPError: Method not found` yanıtını verir.
* `ctx.session.send_ping()` uyarı taşımaz. Modern bir bağlantıda, sunucunun başlattığı diğer tüm istekler gibi aynı geri kanal yok (back-channel) hatasını fırlatır.
* İki taraf da ping'e yanıt vermek için herhangi bir şey kaydetmez.
## Kök dizin değişikliği bildirimleri {#roots-change-notifications}
Kök dizinler yeteneğini bildirmiş 2025 neslinden bir istemci, çalışma alanı klasörlerinin değiştiğini sunucuya `notifications/roots/list_changed` göndererek söyleyebilir; sunucu da karşılık olarak `roots/list`'i yeniden ister. 2026-07-28 spesifikasyonu bu bildirimi, push tarzı kök dizin akışının geri kalanıyla birlikte kaldırır. İstemcide `"roots": {"listChanged": true}` bildirimini yapan şey `list_roots_callback=` geçirmektir (**[İstemci callback'leri](client/callbacks.md)**) ve tek bir çağrı bu sözü tutar:
```python
async def open_folder(client: Client, uri: str, name: str) -> None:
"""The user opened another folder: expose it through the roots callback, then tell the server."""
workspace.append(Root(uri=FileUrl(uri), name=name))
await client.send_roots_list_changed()
```
Sunucuda alıcı işleyiciyi düşük seviyeli `Server` alır:
```python
async def roots_changed(ctx: ServerRequestContext, params: NotificationParams | None) -> None:
"""The client's roots changed: ask for the new list."""
roots = (await ctx.session.list_roots()).roots
server = Server("Bookshop", on_roots_list_changed=roots_changed)
```
* `workspace`, `list_roots_callback`'inizin döndürdüğü listedir. `client.send_roots_list_changed()` uyarır ve `mode="legacy"` bir istemci gerektirir: modern bir bağlantıda bildirim sessizce düşürülür. Ardından oturumu açık tutun, çünkü sunucunun takip eden `roots/list` isteği o oturum üzerinden gelir.
* `MCPServer`'da bu bildirim için bir kanca yoktur. Düşük seviyeli `Server`'da işleyiciyi `on_roots_list_changed=` kaydeder (o da kullanım dışıdır ve oluşturma sırasında uyarır). Bildirim yük taşımaz, bu yüzden işleyici yeni liste için `ctx.session.list_roots()`'u çağırır.
## Uyarıyı susturma {#silencing-the-warning}
Yeni kodda susturmayın.
@ -75,22 +124,32 @@ API'nin tamamı bu. Yöntem başına bir anahtar yok, zaten istemezsiniz de: tek
Filtreyi ters yönde çalıştırın, bedava bir regresyon testi elde edersiniz. pytest
yapılandırmanızdaki `filterwarnings` ayarına `"error::mcp.MCPDeprecationWarning"`
ekleyin; kullanım dışı çağrı uyarmak yerine **istisna fırlatır**. Hâlâ `ctx.info()`'yu
çağıran `old_log` adlı bir araç artık geçmez ve şunu bildirmeye başlar:
çağıran `old_log` adlı bir araç artık geçmez: çağrı `Error executing tool old_log` ile
`is_error=True` olarak döner ve yakalanan sunucu log'u suçluyu adıyla gösterir:
```text
Error executing tool old_log: The logging capability is deprecated as of 2026-07-28 (SEP-2577).
mcp.shared.exceptions.MCPDeprecationWarning: The logging capability is deprecated as of 2026-07-28 (SEP-2577).
```
Tek satır pytest yapılandırmasıyla, kullanım dışı bir çağrı bir testi başarısız kılmadan
kod tabanınıza bir daha asla sızamaz.
## Kullanım dışı SDK yardımcıları {#deprecated-sdk-helpers}
Bunlar spesifikasyon değişikliği değil, yalnızca daha iyi bir alternatifi olan SDK iç ayrıntılarıdır. Aynı `MCPDeprecationWarning` ile uyarırlar ve 3.0'da kaldırılacaklar.
| Kullanım dışı | Bunun yerine ne yaparsınız |
|---|---|
| `FuncMetadata.call_fn_with_arg_validation()` | `FuncMetadata.validate_arguments()`, ardından `FuncMetadata.call_fn()`. Bunu yalnızca `FuncMetadata`'yı doğrudan kullanan kod (örneğin özel bir `Tool` alt sınıfı) çağırırdı. |
## Özet {#recap}
* 2026-07-28 spesifikasyonu **kök dizinleri**, sunucunun başlattığı **örneklemeyi** ve protokol üzerinden **log tutmayı** kullanım dışı bırakır (hepsi [SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), **ilerlemeyi** sunucudan istemciye yönle sınırlar ve **`ping`**'i kaldırır.
* Yerine geçenler sütunu sizi ileriye yönlendirir: örnekleme ve kök dizinler için **[Çok turlu istekler](handlers/multi-round-trip.md)**, log tutma için **[Log tutma](handlers/logging.md)**, ilerleme için **[İlerleme](handlers/progress.md)**. `ping` için hiçbir şey gerekmez.
* Kullanım dışı bırakma tavsiye niteliğindedir: iletilen veride değişiklik yok, her şey 2026 öncesi oturumlarda çalışmaya devam eder ve görünür bir `MCPDeprecationWarning` alırsınız (bir `UserWarning`, dolayısıyla varsayılan olarak açık).
* Örnekleme ve kök dizinler ayrıca, 2026-07-28 oturumunda bulunmayan bir geri kanala (back-channel) ihtiyaç duyar. Modern bir bağlantıda önce uyarır, sonra istisna fırlatırlar.
* Örnekleme ve kök dizinler ayrıca, 2026-07-28 oturumunda bulunmayan bir geri kanala ihtiyaç duyar. Modern bir bağlantıda önce uyarır, sonra istisna fırlatırlar.
* `warnings.filterwarnings("ignore", category=MCPDeprecationWarning)` tüm kategoriyi susturur; pytest'te `"error::mcp.MCPDeprecationWarning"` bunu bir test hatasına dönüştürür.
* Bir SDK yardımcısı, `FuncMetadata.call_fn_with_arg_validation()`, 3.0'da kaldırılmak üzere ayrıca kullanım dışı bırakıldı.
* Yeni kod bunların hiçbiri üzerine kurulmamalıdır.
Bu belgelerdeki diğer tüm sayfalar güncel API'yi anlatır.

View file

@ -1,6 +1,6 @@
---
translation:
sections: [3c4f2f06b4e978b6, 22520eecae3d1961, f4e1709db18d635a, 2eb57992049671d9, 1ba83e9af37cc1b4, 4822586344b08d9e, 1c93afef72478992, b6b448f9eddd51dc, fe55370fd931815b]
sections: [3c4f2f06b4e978b6, 51ea5fbcb0e93563, 32d8808606ffdae0, 2eb57992049671d9, 1ba83e9af37cc1b4, 4822586344b08d9e, 1c93afef72478992, b6b448f9eddd51dc, fe55370fd931815b]
tool: 1
---
# Gerçek bir host'a bağlanma {#connect-to-a-real-host}
@ -11,15 +11,15 @@ Yani bir host'a bağlanmak tek bir eylemdir: ona **sunucunuzu başlatan komutu**
## Tek sunucu, her host {#one-server-every-host}
```python title="server.py" hl_lines="3 33-34"
```python title="server.py" hl_lines="4 34-35"
--8<-- "docs_src/real_host/tutorial001.py"
```
İki araç ve bir kaynak, tek dosya. Bu dosyayla ilgili üç şey aşağıdaki her host için önemlidir:
* Argümansız `mcp.run()` bir **stdio** sunucusu başlatır: bloklar, protokol mesajlarını stdin'den okur ve stdout'a yazar. Bu sayfadaki her host'un konuştuğu aktarım budur. Host dosyanızı bir alt süreç olarak başlatır ve bu iki kanalın sahibidir; bağlanmanın her zaman yalnızca "işte komut" olmasının nedeni de budur. Hiçbir zaman port seçmezsiniz ve hiçbir şey bir portu dinlemez.
* `run()`, `if __name__ == "__main__":` altındadır. Aşağıdaki her şey bu dosyayı çalıştırmak yerine **import eder**; bu yüzden korumasız bir `run()`, modülü herhangi bir şey yüklediği anda bir sunucu başlatırdı.
* Sunucu nesnesi, `mcp` adında modül düzeyinde bir globaldir. `mcp run`'ın aradığı ad budur (`server` ve `app` de olur). Başka bir ad verirseniz açıkça belirtirsiniz: `mcp run server.py:bookshop`.
* Argümansız `mcp.run()` bir **stdio** sunucusu başlatır: bloke olur, protokol mesajlarını stdin'den okur ve stdout'a yazar. Bu sayfadaki her host'un konuştuğu aktarım budur. Host dosyanızı bir alt süreç olarak başlatır ve bu iki kanalın sahibidir; bağlanmanın her zaman yalnızca "işte komut" olmasının nedeni de budur. Hiçbir zaman port seçmezsiniz ve hiçbir şey bir portu dinlemez.
* `run()`, `if __name__ == "__main__":` altındadır. Aşağıdaki her şey bu dosyayı çalıştırmak yerine **import eder**; bu yüzden korumasız bir `run()`, herhangi bir şey modülü yüklediği anda bir sunucu başlatırdı.
* Sunucu nesnesi, `mcp` adında modül düzeyinde bir globaldir. `mcp run`'ın aradığı ad budur (`server` ve `app` de olur). Başka bir ad verirseniz adı açıkça belirtirsiniz: `mcp run server.py:bookshop`.
Bu, bu sayfadaki son Python satırı. Buradan aşağısı tamamen host yapılandırması.
@ -33,7 +33,7 @@ uv run --with "mcp[cli]" mcp run /absolute/path/to/server.py
Hepsi için tek komut, çünkü `uv run --with` SDK'yı anında yeni bir ortama çözümler: herhangi bir dizinden çalışır, ne bir projeye ne de etkinleştirilecek bir sanal ortama ihtiyaç duyar. Bu, burada başka her yerden daha önemlidir; çünkü host sunucunuzu sizin kabuğunuzdan değil, *kendi* çalışma dizininden ve neredeyse boş bir ortamla başlatır.
Bu aynı zamanda `mcp install`'un sizin için Claude Desktop'ın yapılandırmasına yazdığı komuttur (aşağıda). Böylece elle yazdığınız ile aracın ürettiği, aracın eklediği tam sürüm sabitlemesi dışında örtüşür.
Bu aynı zamanda `mcp install`'un sizin için Claude Desktop'ın yapılandırmasına yazdığı komuttur (aşağıda). Yani elle yazdığınız ile aracın ürettiği, aracın eklediği tam sürüm sabitlemesi dışında örtüşür.
!!! tip "Host `uv`'yi bulamazsa"
Host sunucunuzu asgari bir `PATH` ile başlatır ve `uv` bunun üzerinde olmayabilir. Yalın
@ -43,15 +43,15 @@ Bu aynı zamanda `mcp install`'un sizin için Claude Desktop'ın yapılandırmas
!!! note "Bu sayfa yerel senaryoyu anlatır"
Buradaki her şey sunucunuzu host'un bulunduğu makinede çalıştırır: host dosyanızı stdio
üzerinden başlatır. Kişisel ya da tek makinelik bir araç için bu tam olarak doğru olandır.
Dosyanıza sahip *olmayan* insanlara bir sunucu vermek için komut değil **URL** dağıtırsınız:
Dosyanız *olmayan* insanlara bir sunucu vermek için komut değil **URL** dağıtırsınız:
aynı `mcp` nesnesi, Streamable HTTP üzerinden sunulur. **[Sunucunuzu çalıştırma](../run/index.md)**
bu kararı tek bir tabloda verir, **[Dağıtım ve ölçekleme](../run/deploy.md)** ise oradan
gerçek bir ana bilgisayar adına giden yoldur.
Ve host, içinde bir MCP istemcisi olan bir uygulamadan başka bir şey değildir; bu yüzden kendi
Host da içinde bir MCP istemcisi olan bir uygulamadan başka bir şey değildir; bu yüzden kendi
Python kodunuz host rolünü oynayabilir: **[İstemci aktarımları](../client/transports.md)**
bu aynı dosyayı `stdio_client(...)` ile bir alt süreç olarak başlatır, **[Test etme](testing.md)**
ise ona hiç süreç olmadan bellek içinde bağlanır.
bu aynı dosyayı `Client(StdioServerParameters(...))` ile bir alt süreç olarak başlatır,
**[Test etme](testing.md)** ise ona hiç süreç olmadan bellek içinde bağlanır.
## Claude Desktop {#claude-desktop}

View file

@ -1,6 +1,6 @@
---
translation:
sections: ['4926721070127497', c52a1de2b6b32f40, 2e410b412c25f314, 627195f7159e24ef]
sections: ['4926721070127497', c52a1de2b6b32f40, 8e792bf8c7489ec6, 627195f7159e24ef]
tool: 1
---
# Test etme {#testing}
@ -85,9 +85,9 @@ async def test_call_add_tool(client: Client):
İki farklı şey ters gidebilir ve bu bayrak yalnızca birine dokunur.
**Araçlarınızdan** birinin içindeki bir istisna, protokol hatası değildir. `is_error=True` taşıyan
normal bir sonuca dönüşür ve model mesajı okur. `raise_exceptions` bunu değiştirmez: onunla da
onsuz da `call_tool` aynı `is_error=True` sonucunu döndürür. Bu konuda ayrı bir sayfa var:
**[Hataları ele alma](../servers/handling-errors.md)**.
normal bir sonuca dönüşür (istisna bir `ToolError` ise model sizin mesajınızı okur). `raise_exceptions`
bunu değiştirmez: onunla da onsuz da `call_tool` aynı `is_error=True` sonucunu döndürür. Bu konuda
ayrı bir sayfa var: **[Hataları ele alma](../servers/handling-errors.md)**.
Araç gövdesinin **dışındaki** bir hata ise farklıdır. `Client(mcp)`'nin size verdiği bağlantıda
sunucu, istemci görmeden önce onu genel bir `"Internal server error"` mesajına dönüştürerek

View file

@ -1,6 +1,6 @@
---
translation:
sections: [335ca2a0b266f003, d1ad562d3fe87bc0, 0bb1396c86daeba4, d1cb1235bb9ee267, 833179c09d239c83, e5d6dec2d2e655e8]
sections: [335ca2a0b266f003, d1ad562d3fe87bc0, 25b49f89c9e6f9d0, d1cb1235bb9ee267, 833179c09d239c83, e5d6dec2d2e655e8]
tool: 1
---
# Elicitation {#elicitation}
@ -90,7 +90,8 @@ Bu şema formun kendisidir. `Field(description=...)` etikettir; bir varsayılan
Bir elicitation şeması, bir aracın girdi şeması kadar ifade gücüne sahip değildir. Yalnızca
düz, ilkel alanlar: `str`, `int`, `float`, `bool` veya dizelerden oluşan bir `Literal`
(bir `enum`'a dönüşür). Modelin içine bir model koyarsanız `ctx.elicit`, istemciye hiçbir
şey gönderilmeden önce istisna fırlatır:
şey gönderilmeden önce istisna fırlatır. Araç çağrısı `Error executing tool <name>` ile
başarısız olur, nedeni de sunucu log'unuzdadır:
```text
TypeError: Elicitation schema field 'address' rendered as {'$ref': '#/$defs/Address'}, which is not a valid PrimitiveSchemaDefinition
@ -113,8 +114,8 @@ Ret bir hata değildir. Reddetmenin ne anlama geldiğine araç karar verir (bura
!!! tip
Yanıt, kodunuz görmeden önce modelinize göre doğrulanır. Bir `bool` için `"maybe"` gönderen
bir istemci rezervasyonunuzu bozmaz: çağrı bir şema uyuşmazlığı hatasıyla başarısız olur,
`if`'iniz hiç çalışmaz.
bir istemci rezervasyonunuzu bozmaz: `ctx.elicit` `ValueError` fırlatır, çağrı başarısız
olur ve `if`'iniz hiç çalışmaz.
## Kullanıcıyı bir URL'ye gönderme {#send-the-user-to-a-url}

View file

@ -1,6 +1,6 @@
---
translation:
sections: [c93a3e1aefd77955, 7851abd5ec54393b, f49d1ca2f330f9cd, c03764bd9dfeef7b, 4a0391691a674ae4, 2df5cd279eabf9f5]
sections: [c93a3e1aefd77955, 7851abd5ec54393b, f49d1ca2f330f9cd, 4cc0a00347c3f534, 4a0391691a674ae4, 2df5cd279eabf9f5]
tool: 1
---
# Log tutma {#logging}
@ -55,6 +55,8 @@ Varsayılan değer `"INFO"`.
`logging.basicConfig()` hâlihazırda var olan işleyicileri asla değiştirmez. Sunucuyu oluşturmadan önce log yapılandırmasını kendiniz yaparsanız sizin yapılandırmanız geçerli olur.
Yalnızca hataları kaydetmek için her işleyiciye bir `try`/`except` koymanız da gerekmez. Bir araç ya da kaynak fonksiyonu istisna fırlattığında SDK bunu sizin yerinize loglar. Neyin hangi düzeyde loglandığını **[Hataları ele alma](../servers/handling-errors.md#any-other-exception)** sayfası açıklar.
## Deneyin {#try-it}
Sunucuyu MCP Inspector ile çalıştırın:

View file

@ -1,6 +1,6 @@
---
translation:
sections: [fea8d769ff9edeba, ce8e2ad42f29ef71, 0d705efb19cf99c2, 7a53ead3e704a7f0, 9adc400e8c88e854, 318893ad8e2e9924, 6b63ab96b34476c0]
sections: [fea8d769ff9edeba, ce8e2ad42f29ef71, 0d705efb19cf99c2, 2fd7cf825e6d2b2c, 9adc400e8c88e854, 318893ad8e2e9924, 6b63ab96b34476c0]
tool: 1
---
# Sunucunuzu çalıştırma {#running-your-server}
@ -72,7 +72,7 @@ Her aktarımın kendi anahtar sözcük argümanları vardır ve hepsi `run()` ü
* `streamable_http_path`: MCP endpoint'inin bulunduğu yol. Varsayılan `/mcp`.
* `json_response=True`: her POST'a SSE akışı yerine tek bir JSON gövdesiyle yanıt verir. Bu gövdede yanıttan başka hiçbir şeye yer yoktur; bu yüzden istek sırasında istemciye geri çağrı yapan bir araç (`ctx.elicit()`, örnekleme (sampling)) bu ayakta `NoBackChannelError` fırlatır ve sürmekte olan çağrıya bağlı bildirimler (`ctx.report_progress()` ile bildirilen ilerleme, çağrıya özel log mesajları) düşürülür; bağımsız `GET` akışı ilgisiz olanları taşımaya devam eder.
* `stateless_http=True`: istek başına yeni bir aktarım, oturum takibi yok.
* `max_request_body_size`: bayt cinsinden kabul edilen en büyük POST gövdesi. Varsayılan olarak 4 MiB;
* `max_request_body_size`: bayt cinsinden kabul edilen en büyük istek gövdesi. Varsayılan olarak 4 MiB;
daha büyük istekler, ayrıştırma veya oturum oluşturma öncesinde HTTP 413 alır. Bunu yalnızca meşru
MCP mesajları bu boyutu aştığında yükseltin.
* `event_store`, `retry_interval`, `transport_security`: kaldığı yerden devam edebilme ve DNS rebinding koruması. localhost dışında bir yere dağıtım yapana kadar bekleyebilirler; `transport_security` konusunu **[Dağıtım ve ölçekleme](deploy.md)** ele alır.

View file

@ -1,13 +1,13 @@
---
translation:
sections: [e33d441f12d50535, 7099694c603e0f5f, c1df4cf9673433e6, c9cd294541422e6e, 6cec073617bfd037, efa92b8f99e908c8, 6a22a29e27fb4601]
sections: [7be05607887e6853, e7375894888d9750, c36f73fc7e3af13b, 2fec2d7e129e62fe, 809b0e0a7c27295a, b4395a04d2a5d906, 1a436007f5f54779, c6b2078ed1e63ba5]
tool: 1
---
# Hataları ele alma {#handling-errors}
Bir araç iki şekilde başarısız olabilir ve SDK bu ikisini çok farklı ele alır.
Bir araç üç şekilde başarısız olabilir ve SDK her birini farklı ele alır.
Sıradan bir istisna fırlatırsanız bunu **model** görür. `MCPError` fırlatırsanız bunu **protokol** görür.
`ToolError` fırlatırsanız mesajınızı **model** görür. `MCPError` fırlatırsanız bunu **protokol** görür. Başka herhangi bir şey fırlatırsanız bu bir çökmedir: model yalnızca çağrının başarısız olduğunu öğrenir, traceback ise log'unuza düşer.
Bu sayfa, hangisini seçeceğinizle ilgili.
@ -15,11 +15,11 @@ Bu sayfa, hangisini seçeceğinizle ilgili.
Bir şeyi arayıp bulan bir araç düşünün; arama sonuçsuz kalsın:
```python title="server.py" hl_lines="11-12"
```python title="server.py" hl_lines="2 12-13"
--8<-- "docs_src/handling_errors/tutorial001.py"
```
Bu iki satırda MCP'ye özgü hiçbir şey yok. `get_author`, herhangi bir Python fonksiyonunun yapacağı gibi düz bir `ValueError` fırlatır.
`mcp.server.mcpserver.exceptions` içindeki `ToolError`, bir aracın modele bir şeylerin ters gittiğini söyleme yoludur.
Katalogda olmayan bir başlıkla çağırın ve sonuca bakın:
@ -30,13 +30,15 @@ result.structured_content # None
```
* İstek **başarılı oldu**. Ortada bir sonuç var; çağıran tarafta hiçbir şey fırlatılmadı.
* `is_error` değeri `True`; istisnanızın mesajı (başına araç adı eklenmiş olarak) `content`'te, tam da modelin okuduğu yerde.
* `is_error` değeri `True`; mesajınız (başına araç adı eklenmiş olarak) `content`'te, tam da modelin okuduğu yerde.
* `structured_content` değeri `None`. Başarısız bir çağrının yapılandırılacak bir dönüş değeri yoktur.
Bu bir **araç hatasıdır** ve aracınızın fırlattığı *her* istisna için varsayılan davranış budur. Neredeyse her zaman istediğiniz şey de budur.
Bu bir **araç hatasıdır** ve neredeyse her zaman istediğiniz şey de budur.
Aracınızı çağıran modeldir. Argümanları o seçti. Bu yüzden araç hatası, konuşmada bir tur demektir: model *"No book titled 'Nothing' in the catalog."* mesajını okur, başlığı yanlış tahmin ettiğini anlar ve daha iyi bir başlıkla tekrar çağırır. Tek bir `raise` yazdınız ve kendi kendini düzelten bir ajan elde ettiniz.
Sunucuda bir `ToolError`, log'da tek bir `INFO` satırıdır; traceback yoktur. Bunu zaten bekliyordunuz, bu yüzden araştırılacak bir şey yok.
!!! tip
Bir araçtan hata mesajını asla `return` ile döndürmeyin. Döndürülen bir dizenin `is_error=False`
değeri vardır; bu yüzden modele (ve her istemci arayüzüne) araç çalışmış ve yanıt o dizeymiş gibi görünür.
@ -44,7 +46,7 @@ Aracınızı çağıran modeldir. Argümanları o seçti. Bu yüzden araç hatas
## Modelin düzeltemeyeceği bir hata {#an-error-the-model-cannot-fix}
Şimdi `ValueError` yerine `MCPError` koyun.
Şimdi `ToolError` yerine `MCPError` koyun.
```python title="server.py" hl_lines="1 3 14"
--8<-- "docs_src/handling_errors/tutorial002.py"
@ -77,10 +79,10 @@ Aracınızı çağıran modeldir. Argümanları o seçti. Bu yüzden araç hatas
İki yol, iki farklı soruyu yanıtlar.
* *Yürütme* başarısızlığı için **herhangi bir istisna fırlatın**: aracınızın yapmaya çalıştığı şey işe yaramadı. Çağrıyı model seçti, bu yüzden sonucunu da model görmeli ve toparlanma şansı bulmalı. Yanlış yazılmış bir başlık, zaman aşımına uğrayan bir dış API, var olmayan bir satır: hepsi araç hatası.
* *Yürütme* başarısızlığı için **`ToolError` fırlatın**: aracınızın yapmaya çalıştığı şey işe yaramadı. Çağrıyı model seçti, bu yüzden sonucunu da model görmeli ve toparlanma şansı bulmalı. Yanlış yazılmış bir başlık, zaman aşımına uğrayan bir dış API, var olmayan bir satır: hepsi araç hatası.
* *İsteğin kendisi* reddedilmesi gerektiğinde **`MCPError` fırlatın**: istemcide aracınızın bağımlı olduğu bir yetenek eksik, sunucu kimseye hizmet verecek durumda değil, çağıran taraf zorunlu bir adımı atlamış. Modelin hiçbir yeniden denemesi bunları düzeltmez; bu yüzden mesajı ona vermenin bir kazancı yok.
Kararı tek bir soru verir: **daha akıllı bir model bundan kaçınabilir miydi?** Evet -> sıradan istisna. Hayır -> `MCPError`.
Kararı tek bir soru verir: **daha akıllı bir model bundan kaçınabilir miydi?** Evet -> `ToolError`. Hayır -> `MCPError`.
Bu ölçüte göre `get_author`'ın ikinci sürümü yanlış seçim yaptı: daha iyi bir başlık sorunu çözer, yani model mesajı görmeyi hak ediyordu. O sürüm size mekanizmayı göstermek için orada, onu önermek için değil.
@ -89,6 +91,25 @@ Bu ölçüte göre `get_author`'ın ikinci sürümü yanlış seçim yaptı: dah
bir `data` yükü alır. Bunlara ne koyarsanız istemci onu alır: SDK, fırlatılan bir
`MCPError`'ı temizlemek yerine olduğu gibi iletir.
## Başka herhangi bir istisna {#any-other-exception}
Şimdi denetimi çıkarın ve sözlük aramasının kendi kendine başarısız olmasına izin verin:
```python title="server.py" hl_lines="11"
--8<-- "docs_src/handling_errors/tutorial004.py"
```
`CATALOG[title]`, `KeyError` fırlatır. Bunu planlamadınız, bu yüzden SDK onu bir çökme olarak ele alır:
```python
result.is_error # True
result.content # [TextContent(text="Error executing tool get_author")]
```
Çağrı yine `is_error=True` döndürür; yani model başarısız olduğunu bilir ve yoluna devam edebilir. Almadığı şey istisnanın metnidir: kodunuzdan gelen bir `KeyError` ya da üç kütüphane alttaki bir sürücüden gelen bir yığın SQL, sunucunuzun iç yapısını ele verebilir; bu yüzden sunucudan asla çıkmaz.
Onu siz alırsınız. Sunucu çökmeyi tam traceback ile `ERROR` düzeyinde, `Tool 'get_author' raised an unexpected exception` olarak log'a yazar. Bu yüzden `WARNING` düzeyindeki bir üretim log'u her `ToolError` boyunca sessiz kalır ve bir şey gerçekten bozulduğu anda sesini çıkarır.
## Var olmayan bir kaynak {#a-resource-that-doesnt-exist}
Kaynaklar da aynı çizgiyi çeker ve yaygın durum için adlandırılmış bir istisna sunar.
@ -109,7 +130,7 @@ Yanıtlayamadığında `ResourceNotFoundError` fırlatın. SDK bunu, spesifikasy
}
```
Burada `is_error=True` taşıyan yarım bir sonuç olmadığına dikkat edin. Bir kaynak okuması ya içerik döndürür ya da başarısız olur: kaynakların yalnızca protokol yolu vardır. Şablonlar ve kaynaklarla ilgili diğer her şey **[Kaynaklar](resources.md)** sayfasında.
Burada `is_error=True` taşıyan yarım bir sonuç olmadığına dikkat edin. Bir kaynak okuması ya içerik döndürür ya da başarısız olur: kaynakların yalnızca protokol yolu vardır. `ResourceError`, "bulunamadı" olmayan bir başarısızlık için aynı şeydir (`-32603`, sizin mesajınız); ikisi de log'unuzda tek bir `INFO` satırıdır. `MCPError` dışındaki diğer her istisna bir çökmedir: istemci yalnızca URI'yi belirten `-32603` alır, traceback ise `ERROR` düzeyinde log'unuza gider. Şablonlar ve kaynaklarla ilgili diğer her şey **[Kaynaklar](resources.md)** sayfasında.
## Hiç fırlatmadığınız hatalar {#errors-you-never-raise}
@ -120,19 +141,21 @@ Hatalı bir argüman fonksiyonunuza asla ulaşmaz.
Bu, yazmadığınız koca bir `raise` ifadesi sınıfı demektir: kendi tür ipuçlarınızı yeniden doğrulamayın.
!!! info
Bu sayfadaki her şey bir **istemcinin** gördüğüdür; testleri yazarken kullanacağınız bellek içi
`Client` da tam olarak aynı şeyi görür. `raise_exceptions=True` bile bir araç hatasını tekrar
traceback'e çevirmez: o bayrak devreye girebilecek noktaya geldiğinde istisnanız çoktan
`is_error=True` sonucuna dönüşmüştür. Doğrulamayı sonuç üzerinde yapın. **[Test etme](../get-started/testing.md)** sayfası bu kalıbı anlatır.
Bu sayfada bir **istemcinin** gördüğü her şeyi, testleri yazarken kullanacağınız bellek içi
`Client` da görür. `raise_exceptions=True` bile başarısız olan bir
aracın istisnasını çağırana geri vermez: o bayrak devreye girebilecek noktaya geldiğinde istisnanız çoktan
`is_error=True` sonucuna dönüşmüştür. Doğrulamayı sonuç üzerinde yapın. Bir çökmenin traceback'ine ihtiyacınız varsa o
sunucunun log'undadır ve pytest'in `caplog`'u onu yakalar. **[Test etme](../get-started/testing.md)** sayfası bu kalıbı anlatır.
## Özet {#recap}
* Bir araçta **herhangi bir istisna** fırlatın -> çağrı, mesajınız `content`'te olacak şekilde `is_error=True` döndürür. Model bunu okur ve yeniden deneyebilir. Varsayılan budur.
* Bir araçta **`ToolError`** fırlatın -> çağrı, mesajınız `content`'te olacak şekilde `is_error=True` döndürür. Model bunu okur ve yeniden deneyebilir.
* **`MCPError`** fırlatın -> çağrının kendisi bir JSON-RPC hatasıyla başarısız olur. Model hiçbir şey görmez; bununla host ilgilenir. `code`, `message` ve `data` bozulmadan ulaşır.
* Belirleyici soru: *daha akıllı bir model bundan kaçınabilir miydi?* Evet -> istisna. Hayır -> `MCPError`.
* Belirleyici soru: *daha akıllı bir model bundan kaçınabilir miydi?* Evet -> `ToolError`. Hayır -> `MCPError`.
* Diğer **her istisna** bir çökmedir -> model için yalnızca `Error executing tool <name>` içeren `is_error=True`, sizin için ise traceback'li bir `ERROR` kaydı.
* Bir kaynak işleyicisinden `ResourceNotFoundError` -> protokolün `-32602` kodu, URI `data`'da.
* Hatalı argümanlar, fonksiyonunuz çalışmadan önce şemaya göre reddedilir; bunlar için `raise` yazmazsınız.
* `from mcp import MCPError`; hata kodu sabitleri `mcp.types`'tan gelir.
* İçe aktarmalar: `from mcp import MCPError`, `from mcp.server.mcpserver.exceptions import ToolError, ResourceError, ResourceNotFoundError` ve `mcp.types`'tan hata kodu sabitleri.
Hatalar halloldu. Bir sunucunun *sunduğu* her şey bu kadar. Her işleyicinin çalışırken neleri okuyabildiği ve istemciye geri neler yapabildiği bir sonraki bölümde: **[İşleyicinin içinde](../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
---
# Medya {#media}
@ -86,6 +86,24 @@ Tanımadığı bir uzantı `application/octet-stream`'e geri düşer.
MP3 baytlarından bu şekilde bir `Audio` oluşturursanız istemciye `mime_type="audio/wav"`
söylenir ve o da sadakatle çözmeyi başaramaz. `data=` geçirdiğinizde `format=` da geçirin.
## Bir kaynağı gömme {#embedding-a-resource}
Bir araç bir belge de döndürebilir: bulunduğu URI ve bir MIME türüyle birlikte bir miktar metin ya da bayt. Bu bir **`EmbeddedResource`**'tur, bir başka içerik bloğu türü. Düz bir `str`'den farklı olarak istemciye içeriğin ne olduğunu söyler; böylece istemci onu bir ek olarak gösterebilir ya da zaten bildiği bir kaynağı tanıyabilir.
```python title="server.py" hl_lines="7 14 16-18"
--8<-- "docs_src/media/tutorial005.py"
```
* `brand://guidelines` sıradan bir kaynaktır (bunları **[Kaynaklar](resources.md)** sayfası anlatır). Araç, istek üzerine aynı belgeyi modele verir ve `guidelines()`'ı doğrudan çağırmak tek bir doğruluk kaynağını korur.
* `EmbeddedResource` ve `TextResourceContents`, `mcp.types` modülünden gelir. Görsellerdeki gibi bir yardımcı yoktur: oluşturduğunuz blok sonuca olduğu gibi girer ve `structured_content` yoktur.
* Kaynağın kaydedildiği URI'yi kullanın; böylece istemci ekin ve `brand://guidelines` kaynağının aynı belge olduğunu anlayabilir. Kayıtlı olsun olmasın her URI geçerlidir.
```python
result.content # [EmbeddedResource(type="resource", resource=TextResourceContents(uri="brand://guidelines", mime_type="text/markdown", text="# Brand guidelines\n\n..."))]
```
İkili içerik için `TextResourceContents` yerine, baytları base64 ile kodlayıp `blob` alanına koyarak `BlobResourceContents(uri=..., mime_type=..., blob=...)` kullanın. Yalnızca istemcinin daha sonra `resources/read` ile okuyabileceği bir işaretçi göndermek için bunun yerine bir `ResourceLink(name=..., uri=...)` döndürün; o da bir içerik bloğudur.
## Simgeler {#icons}
`Icon` içerik değil, meta veridir. Görseli taşımaz; bir URI ile ona işaret eder ve istemci onu getirip sunucunuzun adının, bir aracın, bir kaynağın veya bir prompt'un yanında gösterebilir.
@ -115,6 +133,7 @@ Bir aracın simgeleri `tools/list`'ten gelen `Tool` nesnesinde, bir kaynağınki
* Bir araçtan `Image` veya `Audio` döndürün; istemci bir `ImageContent` / `AudioContent` bloğu alır: base64 ile kodlanmış baytlarınız ve bir MIME türü.
* Bunu bir `path=` ile oluşturup MIME türünü uzantının belirlemesine bırakın ya da bellekteki `data=` ile açık bir `format=` kullanın.
* Sonuca bir belge (URI'si ve MIME türüyle birlikte metin ya da base64 blob) koymak için bir `EmbeddedResource`, yalnızca işaretçiyi göndermek için bir `ResourceLink` döndürün.
* Medya sonuçları `structured_content` ve çıktı şeması taşımaz.
* `Icon` bir işaretçidir: bir `src` URI'si ile isteğe bağlı `mime_type`, `sizes` ve `theme`.
* `icons=[...]` sunucuda, araçlarda, kaynaklarda ve prompt'larda çalışır; istemciler bunları eşleşen nesnelerde bulur.

View file

@ -1,6 +1,6 @@
---
translation:
sections: [d65c098f37f5b6c3, dd0c2724d6f2877e, 6835bb3570c6714c, ffe823cb0fedd488, f33651add1b59094]
sections: [d65c098f37f5b6c3, dd0c2724d6f2877e, 6835bb3570c6714c, d30d3c20168b88b2, f5ef38dad59d6f76, 6e38a699ba57fbdf, 2b984a3bf37a0ddd]
tool: 1
---
# Prompt'lar {#prompts}
@ -139,10 +139,55 @@ Sonuncusuna dikkat edin. Bir `assistant` turunu önceden doldurmak, yönlendirme
```
!!! info
**[Araçlar](tools.md)** sayfasını okuduysanız bu sayfadaki her şeyi zaten biliyorsunuz. Aynı dekoratör,
**[Araçlar](tools.md)** sayfasını okuduysanız buraya kadarki her şeyi zaten biliyorsunuz. Aynı dekoratör,
açıklama olarak aynı docstring, aynı `Annotated`/`Field`. Değişen tek şey onu kimin
tetiklediği (kullanıcı) ve sonucun nereye gittiğidir (konuşmaya).
## Metinden fazlası {#more-than-text}
`UserMessage` ve `AssistantMessage`, `str` kabul ettikleri her yerde bir içerik bloğunu ya da bir `Image` / `Audio` yardımcısını da kabul eder. Prompt'larda iki durum öne çıkar: bir belge eklemek ve bir resim eklemek.
### Dosya gömme {#embedding-a-file}
```python title="server.py" hl_lines="5 12 21 23"
--8<-- "docs_src/prompts/tutorial004.py"
```
* Stil kılavuzu `style://python` adresindeki bir kaynaktır (bunları **[Kaynaklar](resources.md)** sayfası anlatır) ve `server.py` dosyasının yanındaki `style-guide.md` dosyasından okunur. Oraya herhangi bir Markdown dosyası koyun.
* Her ikisi de `mcp.types` modülünden gelen `EmbeddedResource(resource=TextResourceContents(...))`, dosyayı URI'si ve MIME türüyle birlikte ilk mesaj olarak taşır; ona atıfta bulunan istek düz metin olarak ardından gelir.
* Kılavuzu f-string'e yapıştırmak yerine gömmek, istemcinin onu bir ek olarak göstermesini ve `style://python` kaynağını daha sonra yeniden açabilmesini sağlar; model de dosyayı olduğu gibi alır. İkili bir dosya için base64 `blob` içeren `BlobResourceContents` kullanın.
İşlendiğinde ilk mesajın `content` alanı bir `resource` bloğudur:
```json
{"type": "resource", "resource": {"uri": "style://python", "mimeType": "text/markdown", "text": "* Prefer early returns.\n..."}}
```
### Görsel ekleme {#attaching-an-image}
```python title="server.py" hl_lines="4 15"
--8<-- "docs_src/prompts/tutorial005.py"
```
* `Image`, **[Görseller, ses ve simgeler](media.md)** sayfasındaki yardımcıdır. Prompt işlendiğinde `UserMessage` onu bir `ImageContent` bloğuna dönüştürür (dosya base64 ile kodlanır, MIME türü `.png` uzantısından tahmin edilir); `Audio` da aynı şekilde bir `AudioContent` olur.
* `server.py` dosyasının yanına `architecture.png` adında herhangi bir PNG koyun. Prompt argümanları dizedir, bu yüzden resim her zaman sunucudan gelir; `component` yalnızca sözcükleri sağlar.
```json
{"type": "image", "data": "iVBORw0KGgoAAAANSUhEUg...", "mimeType": "image/png"}
```
## Listeyi çalışma zamanında değiştirme {#changing-the-list-at-runtime}
İstemciler bağlıyken prompt eklenebilir; örneğin bir kullanıcının bir talimatı kendine ait bir menü girdisi olarak kaydetmesine izin vermek için. Prompt'u kaydedin, ardından bildirin:
```python title="server.py" hl_lines="5 23-27"
--8<-- "docs_src/prompts/tutorial006.py"
```
* `mcp.add_prompt(Prompt.from_function(fn, name=..., description=...))` bir fonksiyonu tıpkı `@mcp.prompt()`'un yapacağı gibi kaydeder; `mcp.remove_prompt(name)` ise bunun tersidir. `add_prompt` aynı ada sahip mevcut bir girdinin üzerine yazmak yerine onu korur; bu yüzden araç, kaydetmenin değiştirme anlamına gelmesi için önce varsa eskisini kaldırır. `prompts/list` değişikliği hemen yansıtır.
* `await ctx.notify_prompts_changed()`, bir `subscriptions/listen` akışını dinleyen her `2026-07-28` istemcisine `notifications/prompts/list_changed` gönderir (**[Abonelikler](../handlers/subscriptions.md)**). `await ctx.session.send_prompt_list_changed()` ise çağıran istemci 2026 öncesiyse bildirimi ona gönderir (**[Eski nesil istemcilere hizmet verme](../run/legacy-clients.md)**). İkisini de çağırın; haber verecek kimse yoksa her biri hiçbir şey yapmaz.
* Bildirimi alan bir istemci `prompts/list`'i yeniden çağırır. Python `Client`'ında bu, bir `PromptsListChanged` olayı üreten `async with client.listen(prompts_list_changed=True) as sub:` biçimindedir.
## Özet {#recap}
* Bir fonksiyonun üzerindeki `@mcp.prompt()` onu bir prompt yapar. Ad fonksiyondan, açıklama docstring'den gelir.
@ -151,5 +196,7 @@ Sonuncusuna dikkat edin. Bir `assistant` turunu önceden doldurmak, yönlendirme
* Bir `str` döndürün, tek bir kullanıcı mesajına dönüşür. Çok turlu bir konuşmanın temelini atmak için `UserMessage` / `AssistantMessage` listesi döndürün.
* `title=` ve `Field(description=...)`, bir istemcinin arayüzüne koyduğu şeylerdir.
* Eksik bir zorunlu argüman isteğin tamamını başarısız kılar. Prompt'a özgü bir hata sonucu yoktur.
* Bir belge veya resim eklemek için bir `EmbeddedResource` ya da `Image` nesnesini `UserMessage` içine sarın.
* Çalışma zamanında `mcp.add_prompt(...)` / `mcp.remove_prompt(...)` ile prompt ekleyin veya kaldırın, ardından `await ctx.notify_prompts_changed()` ve `await ctx.session.send_prompt_list_changed()` çağırın.
Bir prompt'un (veya bir kaynak şablonunun) argümanları için sunucu tarafı otomatik tamamlama **[Tamamlamalar](completions.md)** sayfasındadır.

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
---
# Yapılandırılmış çıktı {#structured-output}
@ -105,7 +105,7 @@ Her biçim bir sınıfı hak etmez. Bir `TypedDict` aynı şemayı üretir:
--8<-- "docs_src/structured_output/tutorial003.py"
```
`TypedDict` çalışma zamanında düz bir `dict`'tir; siz de onu oluşturup döndürürsünüz. Şema, doğrulama ve `structured_content`, `BaseModel` sürümüyle birebir aynıdır (`TypedDict`'te yeri olmayan açıklamalar hariç).
`TypedDict` çalışma zamanında düz bir `dict`'tir; siz de onu oluşturup döndürürsünüz. Şema, doğrulama ve `structured_content`, `BaseModel` sürümüyle aynı kurallara uyar: bir sınıf docstring'i ya da `Annotated[..., Field(description=...)]` ekleyin, bunlar şemadaki tanımlar (description) olur; dict'in dışında bıraktığınız bir `NotRequired` anahtar da `structured_content`'in dışında kalır.
## Bir dataclass {#a-dataclass}
@ -188,17 +188,18 @@ Açıklama `WeatherData` vaat ediyor. Üst servisin yanıtı `humidity` gönderm
!!! check
`get_weather`'ı çağırdığınızda istemciye sessizce yarı boş bir nesne vermez. Çağrı başarısız
olur ve hatanın ilk satırları alanın adını verir:
olur: istemci `Error executing tool get_weather` iletisiyle birlikte `is_error=True` alır; böylece
model, var olmayan bir hava durumunu kendinden emin biçimde okumak yerine çağrının başarısız
olduğunu bilir. Alanın adı ise sizin için, sunucu log'unda `ERROR` düzeyinde:
```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]
```
Bu metin, `is_error=True` ile araç sonucu olarak geri döner; böylece model, var olmayan bir hava
durumunu kendinden emin biçimde okumak yerine çağrının başarısız olduğunu bilir.
Bu arada, `-> WeatherData` bir araçtan düz bir `dict` döndürmek sorun değil. `json.loads`'un ürettiği tam olarak buydu. Doğrulama Python türüne değil, değere uygulanır.
## Devre dışı bırakma {#opting-out}
@ -213,6 +214,10 @@ Bazen dönüş açıklaması protokol için değil, tür denetleyiciniz içindir
Tersi olan `structured_output=True`, otomatik algılamayı bir zorunluluğa çevirir: dönüş türü şema üretemeyen bir araç, metne geri düşmek yerine içe aktarma anında istisna fırlatır.
## İçerik blokları ve medya {#content-blocks-and-media}
İçerik blokları ve medya (`TextContent`, `EmbeddedResource`, `Image`, `Audio` ve benzerleri; tek başlarına, bir `list`, `tuple` ya da `Sequence`'in öğeleri olarak veya bir union'ın kolları olarak) sizin yerinize devre dışı bırakılır: bunlar modelin okuması içindir, bu yüzden otomatik algılama onlardan şema türetmez (`Image` ve `Audio`'yu **[Görseller, ses ve simgeler](media.md)** sayfası anlatır). `structured_output=True`, içerik bloğu sınıfları için yine de bir şemayı zorunlu kılar.
## Tür ipucu olmayan bir sınıf {#a-class-without-type-hints}
İstemeden yapılandırılmamış sonuca varmanın bir yolu vardır: **gövdesinde hiç açıklama olmayan** bir sınıf döndürmek.
@ -245,6 +250,6 @@ Tersi olan `structured_output=True`, otomatik algılamayı bir zorunluluğa çev
* Skalerler, listeler, tuple'lar ve union'lar `{"result": ...}` içine sarılır. Modeller, `TypedDict`'ler, dataclass'lar, açıklamalı sınıflar ve `dict[str, ...]` zaten nesnedir ve oldukları gibi kalırlar.
* Her sonuç hem `content` (metin, model için) **hem de** `structured_content` (veri, uygulama için) taşır.
* Döndürdüğünüz şey şemaya göre doğrulanır. Uyuşmazlık bozuk bir sonuç değil, bir araç hatasıdır.
* `structured_output=False` bir aracı devre dışı bırakır. Tür ipucu olmayan bir sınıf sessizce devre dışı kalır; buna dikkat edin.
* `structured_output=False` bir aracı devre dışı bırakır. İçerik blokları, `Image` ve `Audio` varsayılan olarak devre dışıdır; tür ipucu olmayan bir sınıf sessizce devre dışı kalır, buna dikkat edin.
Artık bir aracın geri söyleyebileceği her şeye hâkimsiniz. Sırada ikinci ilkel yapı var: **[Kaynaklar](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
---
# Araçlar {#tools}
@ -39,6 +39,8 @@ SDK bu tür ipuçlarından bir JSON Schema üretir ve `tools/list` sırasında i
Hiçbirinin varsayılan değeri olmadığı için iki argüman da `required` içinde. Bunu birazdan düzelteceksiniz. (`title` anahtarları Pydantic'in ürettiği kalıntılardır; sözleşmeyi oluşturan şey özellikler, türleri ve `required`'dır.)
`$schema` anahtarı da yok: MCP, bu anahtarı taşımayan bir şemayı **JSON Schema 2020-12** olarak kabul eder; Pydantic'in ürettiği de budur. Bu yüzden **[alt düzey Server](../advanced/low-level-server.md#the-dialect-is-json-schema-2020-12)** üzerinde şemaları elle yazana kadar seçmeniz gereken bir şey yoktur.
!!! tip
Tür ipuçları burada dokümantasyon değildir. **Sözleşmenin ta kendisidir**. Bir istemci `"limit": "ten"`
gönderirse SDK bunu, fonksiyonunuz daha çalışmadan reddeder.

View file

@ -1,6 +1,6 @@
---
translation:
sections: [4a7033e1ed8ad602, 55dcbfff0c6271bf, 101ef9d14bf4ec46, 4b6c4a845438abc7, f98b46bafbee4acd]
sections: [4a7033e1ed8ad602, 55dcbfff0c6271bf, 317f4256a650cab6, 4b6c4a845438abc7, f98b46bafbee4acd]
tool: 1
---
# URI şablonları ve yol güvenliği {#uri-templates-and-path-safety}
@ -169,7 +169,7 @@ Yerleşik denetimler yaygın durumları durdurur ama sizin sandbox sınırınız
bilemez. Dosya sistemi erişimi için yolu çözümlemek ve temel dizininizin
içinde kaldığını doğrulamak üzere `safe_join` kullanın:
```python title="server.py" hl_lines="4 14"
```python title="server.py" hl_lines="5 15"
--8<-- "docs_src/uri_templates/tutorial002.py"
```
@ -209,10 +209,11 @@ Bu denetimler sezgisel bir ön süzgeçtir; dosya sistemi erişimi için
kapsama sınırı `safe_join` olmaya devam eder.
!!! tip
İşleyiciniz isteği karşılayamıyorsa (dosya yok, kimlik bilinmiyor) bir
istisna fırlatın. SDK bunu bir hata yanıtına dönüştürür. Protokol hatası
ile araç hatası arasındaki fark için **[Hataları ele alma](handling-errors.md)**
sayfasına bakın.
İşleyiciniz isteği karşılayamıyorsa (dosya yok, kimlik bilinmiyor), yukarıda
`read_manual`'ın yaptığı gibi `ResourceNotFoundError` fırlatın. İstemci,
mesajınız ve URI ile birlikte `-32602` alır. Beklenmedik bir istisna ise
bunun yerine genel bir `-32603` olur. Bkz.
**[Hataları ele alma](handling-errors.md#a-resource-that-doesnt-exist)**.
## Düşük seviyeli Server üzerinde kaynaklar {#resources-on-the-low-level-server}

View file

@ -1,6 +1,6 @@
---
translation:
sections: [2efaecdef109a5c5, fcacd3e66b8635a4, 25323d737dcf0261, 4835ed1772f1d113, 137454d469c867f5, 6392596bd6df54f0, 41126fa9c4fe432f, 480b6d7897e30ab4, d83bb682e708dde0, ebbed3449c499db4, 323ef84f6b4bebde, 30fd31be74169d9a, 656943c6cb567218, c2dc3b1007d2e987, 7cf5386b997d04e9, 0b59feed8384456e, 0cba47bae78d04eb, 954dc21efdb532a3]
sections: [2efaecdef109a5c5, fcacd3e66b8635a4, 25323d737dcf0261, 8a6e351ec756904d, 137454d469c867f5, 6392596bd6df54f0, 41126fa9c4fe432f, 480b6d7897e30ab4, d83bb682e708dde0, ebbed3449c499db4, 323ef84f6b4bebde, 30fd31be74169d9a, 656943c6cb567218, c2dc3b1007d2e987, 7cf5386b997d04e9, 0b59feed8384456e, 0cba47bae78d04eb, e4355f4c7cf4fb2e]
tool: 1
---
# Sorun giderme {#troubleshooting}
@ -81,11 +81,11 @@ async def main() -> None:
`__aexit__` ise bağlantının kesilmesidir; unutulacak bir `client.close()` olmamasının nedeni de budur. **[Test etme](get-started/testing.md)** tam olarak bu kalıp üzerine kuruludur.
## `Error executing tool <name>: <message>` ve `Unknown tool: <name>` {#error-executing-tool-name-message-and-unknown-tool-name}
## `Error executing tool <name>: <message>`, `Error executing tool <name>` ve `Unknown tool: <name>` {#error-executing-tool-name-message-error-executing-tool-name-and-unknown-tool-name}
Okuduğunuz şey bir istisna değil, bir **sonuç**. `call_tool` istisna fırlatmadı ve başarısız olan bir araç için hiçbir zaman fırlatmaz.
`forecast`'i sunucunun tanımadığı bir şehir için çağırın; fırlattığı istisna, istek *başarılı* olarak işaretlenmiş halde geri döner:
`forecast`'i sunucunun tanımadığı bir şehir için çağırın; fırlattığı `ToolError`, istek *başarılı* olarak işaretlenmiş halde geri döner:
```python
result.is_error # True
@ -97,6 +97,8 @@ result.structured_content # None
Çözüm istemcinizde: **`result.is_error`'ı kontrol edin**. `call_tool` etrafındaki bir `try/except` bunların hiçbirini yakalamaz, çünkü yakalanacak bir şey yoktur. Bu kasıtlıdır ve bu sayfada içselleştirilecek en yararlı tek şeydir: çağrıyı *model* seçti, bu yüzden mesajı ve yeniden deneme şansını da model alır. Ayrıntıların tamamı, *gerçekten* istisna fırlatan `MCPError` yolu dahil, **[Hataları ele alma](servers/handling-errors.md)** sayfasında.
Yalın biçim, yani mesajsız `Error executing tool <name>`, aracın **çöktüğü** anlamına gelir: öngörmediği bir istisna ondan kaçmıştır (ya da dönüş değeri çıktı şemasını geçememiştir) ve o istisnanın metni ağ üzerinden gönderilmez. Traceback, `ERROR` düzeyinde, `Tool '<name>' raised an unexpected exception` olarak **sunucunun log'undadır**.
## `TypeError: The @tool decorator was used incorrectly. Did you forget to call it? Use @tool() instead of @tool` {#typeerror-the-tool-decorator-was-used-incorrectly-did-you-forget-to-call-it-use-tool-instead-of-tool}
`@mcp.tool()` yerine `@mcp.tool` yazdınız. `tool()` bir dekoratör *fabrikasıdır*: parantezler olmadan Python, fonksiyonunuzu onun `name=` parametresine verir.
@ -410,7 +412,7 @@ mcp = MCPServer("Weather", request_state_security=RequestStateSecurity(keys=[key
## Özet {#recap}
* `ExceptionGroup: unhandled errors in a TaskGroup` hiçbir zaman asıl hata değildir. **Son satırı** okuyun; `MCPError`'ı `async with Client(...)` bloğunun *içinde* yakalamak sarmalamayı tamamen atlar.
* `call_tool` başarısız olan bir araç için istisna fırlatmaz. `Error executing tool ...` ve `Unknown tool: ...` birer sonuçtur: `result.is_error`'ı kontrol edin.
* `call_tool` başarısız olan bir araç için istisna fırlatmaz. `Error executing tool ...` ve `Unknown tool: ...` birer sonuçtur: `result.is_error`'ı kontrol edin. Araç adından sonra mesaj yoksa araç çökmüş demektir ve traceback sunucu log'undadır.
* `Client must be used within an async context manager` -> `async with` kullanın. `Use @tool() instead of @tool` -> parantezleri ekleyin.
* Sunucu log'undaki `Tool already exists:`, aynı adlı iki aracın teke indiğinin tek işaretidir.
* Tek 421, üç yazım: `Server returned an error response` (python `Client`), `421 Misdirected Request` / `Invalid Host header` (geri kalan her şey), `Invalid Host header: <host>` (sunucu log'u). Çözüm: `transport_security=TransportSecuritySettings(allowed_hosts=[...])`.

View file

@ -1,6 +1,6 @@
---
translation:
sections: [cfe01c0c5863dfa2, 11d93f1fa09eadf5, a7392996acf1ad8f, 875eb2889263424e]
sections: [cfe01c0c5863dfa2, 1c58c5cfcc37d455, a7392996acf1ad8f, 875eb2889263424e]
tool: 1
---
# v2'deki yenilikler {#whats-new-in-v2}
@ -46,9 +46,9 @@ v1 size iç içe üç katman veriyordu: ham akışlar üreten bir aktarım bağl
--8<-- "docs_src/client/tutorial001.py"
```
`Client` bir sunucu nesnesi (bellek içi, aktarım yok: test senaryosu), bir URL (Streamable HTTP) ya da `stdio_client(...)` gibi herhangi bir aktarım bağlam yöneticisi alır. `async with` bloğuna girmek bağlantıyı kurar ve sunucu hangi nesli konuşuyorsa ona göre protokol sürümünde anlaşır; ardından `client.server_capabilities` ve `client.protocol_version` hazırdır, sunucu kendini tanıttığında `client.server_info` da öyle (artık `Implementation | None` türünde, çünkü 2026 neslinde kimlik isteğe bağlı). v1'de kaydettiğiniz örnekleme ve elicitation callback'leri hâlâ çalışır (gövdeleri, bu sayfadaki her şey gibi aynı snake_case öznitelik yeniden adlandırmasını görür); artık 2026 tarzı sonuç-içinde-isteklere de (aşağıda) yanıt verirler ve teker teker değil eşzamanlı çalışırlar. Düşük düzey yüzeyi isteyenler için `ClientSession` hâlâ altta duruyor ve `client.session` onu size verir; o da taşındı (yeni dispatcher motoru üzerinde çalışır ve kendi imzalarından bazıları değişti), bu yüzden aşağı inmeden önce **[Geçiş kılavuzu](migration.md#clientsession-now-runs-on-jsonrpcdispatcher-basesession-removed)** sayfasını okuyun.
`Client` bir sunucu nesnesi (bellek içi, aktarım yok: test senaryosu), bir URL (Streamable HTTP), bir `StdioServerParameters` (bir stdio alt süreci) ya da `sse_client(...)` gibi başka herhangi bir aktarım bağlam yöneticisi alır. `async with` bloğuna girmek bağlantıyı kurar ve sunucu hangi nesli konuşuyorsa ona göre protokol sürümünde anlaşır; ardından `client.server_capabilities` ve `client.protocol_version` hazırdır, sunucu kendini tanıttığında `client.server_info` da öyle (artık `Implementation | None` türünde, çünkü 2026 neslinde kimlik isteğe bağlı). v1'de kaydettiğiniz örnekleme ve elicitation callback'leri hâlâ çalışır (gövdeleri, bu sayfadaki her şey gibi aynı snake_case öznitelik yeniden adlandırmasını görür); artık 2026 tarzı sonuç-içinde-isteklere de (aşağıda) yanıt verirler ve teker teker değil eşzamanlı çalışırlar. Düşük düzey yüzeyi isteyenler için `ClientSession` hâlâ altta duruyor ve `client.session` onu size verir; o da taşındı (yeni dispatcher motoru üzerinde çalışır ve kendi imzalarından bazıları değişti), bu yüzden aşağı inmeden önce **[Geçiş kılavuzu](migration.md#clientsession-now-runs-on-jsonrpcdispatcher-basesession-removed)** sayfasını okuyun.
**[Client](client/index.md)** sayfası onu tanıtır, **[İstemci aktarımları](client/transports.md)** üç bağlantı biçimini anlatır, **[İstemci callback'leri](client/callbacks.md)** callback'lerin kendisini ele alır ve **[Test etme](get-started/testing.md)** v1'in `create_connected_server_and_client_session()` yardımcısının yerini alan bellek içi kalıbı gösterir.
**[Client](client/index.md)** sayfası onu tanıtır, **[İstemci aktarımları](client/transports.md)** dört bağlantı biçimini anlatır, **[İstemci callback'leri](client/callbacks.md)** callback'lerin kendisini ele alır ve **[Test etme](get-started/testing.md)** v1'in `create_connected_server_and_client_session()` yardımcısının yerini alan bellek içi kalıbı gösterir.
### Düşük düzey `Server` yeniden adlandırılmadı, yeniden inşa edildi {#the-low-level-server-was-rebuilt-not-renamed}
@ -134,7 +134,7 @@ Seçenekleri **[Sunucunuzu çalıştırma](run/index.md)**, bağlamayı **[Mevcu
Yeniden adlandırmalar kendini belli eder. Bunlar etmez:
* **Senkron fonksiyonlar bir işçi iş parçacığında çalışır.** Bir `def` aracı (ya da kaynağı, prompt'u veya çözümleyicisi) artık olay döngüsünü engellemez; bunun bedeli, gövdesinin artık olay döngüsü iş parçacığının *üzerinde* çalışmamasıdır ve bu, iş parçacığına bağlı kod için önemlidir. `async def` işleyicilere dokunulmadı. **[Geçiş kılavuzu](migration.md#sync-handler-functions-now-run-on-a-worker-thread)**.
* **Bir aracın içinde fırlatılan `MCPError` (v1'deki `McpError`) artık bir protokol hatasıdır.** Model onu asla görmez. Diğer her istisna hâlâ modelin okuyup tepki verebileceği `is_error=True` bir sonuca dönüşür. Ayrım **[Hataları ele alma](servers/handling-errors.md)** sayfasında.
* **Bir aracın içinde fırlatılan `MCPError` (v1'deki `McpError`) artık bir protokol hatasıdır.** Model onu asla görmez. Diğer her istisna hâlâ `is_error=True` bir sonuca dönüşür, ancak modele yalnızca bir `ToolError`'ın mesajı ulaşır: başka herhangi bir istisna artık `Error executing tool <name>` olarak okunur, traceback ise sunucu log'unuzda kalır. Ayrım **[Hataları ele alma](servers/handling-errors.md)** sayfasında.
* **Sonuçlar çıkmadan önce doğrulanır.** `input_schema`'sı `{}` olan elle kurulmuş bir `Tool` artık `tools/list` çağrısında başarısız olur (spesifikasyon `"type": "object"` gerektirir). `@mcp.tool()` üzerine kurulu sunucular bunu asla görmez; şemalarını SDK yazar.
* **İstemciniz aldığını doğrular.** `list_tools()` ve `call_tool()` sunucunun yanıtını üzerinde anlaşılan protokol sürümüne göre denetler; bu yüzden v1'in hoşgörülü ayrıştırmasının idare ettiği tam geçerli olmayan bir sunucu artık `pydantic.ValidationError` fırlatır. Kontrol etmediğiniz sunuculara bağlanıyorsanız onları bulan kişi olmayı bekleyin; ayrıntılar **[Geçiş kılavuzu](migration.md#client-validates-inbound-traffic-against-the-protocol-schema)** sayfasında.
* **URI şablonları artık gerçek RFC 6570.** `{+path}`, `{?query}` ve benzerleri çalışır, eşleştirme regex gevşekliğinde değil birebirdir ve çıkarılan değerlerdeki yol geçişi (path traversal) varsayılan olarak reddedilir. Daha sıkı şablonlar ilk istekte değil, dekoratör uygulanırken başarısız olur. **[URI şablonları](servers/uri-templates.md)**.