docs: refresh translations for recent English changes (#3379)
This commit is contained in:
parent
d8b638304e
commit
c5d7d0b6d0
2 changed files with 3149 additions and 1047 deletions
|
|
@ -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
|
||||
---
|
||||
# Der Client {#the-client}
|
||||
|
|
@ -27,9 +27,10 @@ Der Server oben ist nur da, damit du etwas hast, womit du dich verbinden kannst.
|
|||
|
||||
* Eine Instanz von `MCPServer` (oder des Low-Level-`Server`): Verbindung **im selben Prozess**.
|
||||
* Ein URL-String (`Client("http://localhost:8000/mcp")`): Streamable HTTP, der Weg für die Produktion.
|
||||
* Ein **Transport**: alles, was sich mit `async with ... as (read, write)` verwenden lässt, etwa `stdio_client(...)` um einen Subprozess herum.
|
||||
* Ein `StdioServerParameters`: der Befehl, der als **Subprozess** gestartet wird und mit dem über dessen stdin und stdout gesprochen wird.
|
||||
* Ein **Transport**: alles, was sich mit `async with ... as (read, write)` verwenden lässt, etwa `streamable_http_client(url, http_client=...)` um deinen eigenen HTTP-Client herum.
|
||||
|
||||
Alles Übrige auf dieser Seite ist in allen drei Fällen identisch. Header, Subprozesse, Timeouts und das `Transport`-Protokoll haben ihre eigene Seite: **[Client-Transporte](transports.md)**.
|
||||
Alles Übrige auf dieser Seite ist in allen vier Fällen identisch. Header, Subprozesse, Timeouts und das `Transport`-Protokoll haben ihre eigene Seite: **[Client-Transporte](transports.md)**.
|
||||
|
||||
### Was ein verbundener Client mitbringt {#whats-on-a-connected-client}
|
||||
|
||||
|
|
@ -85,7 +86,7 @@ Dieses Schema ist alles, was eine UI braucht, um ein Argumentformular zu rendern
|
|||
|
||||
`call_tool(name, arguments)` führt das Tool aus und gibt dir ein `CallToolResult` zurück.
|
||||
|
||||
```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 @@ Ein Tool, das eine Exception auslöst, löst in deinem Client **keine** aus. Es
|
|||
|
||||
!!! check
|
||||
Frag `lookup_book` nach `"Solaris"` (einem Titel, der nicht im Katalog steht), und die Funktion löst
|
||||
`ValueError` aus. Der Aufruf kehrt trotzdem normal zurück:
|
||||
`ToolError` aus. Der Aufruf kehrt trotzdem normal zurück:
|
||||
|
||||
```python
|
||||
result.is_error # True
|
||||
|
|
@ -125,9 +126,10 @@ Ein Tool, das eine Exception auslöst, löst in deinem Client **keine** aus. Es
|
|||
result.structured_content # None
|
||||
```
|
||||
|
||||
Die Meldung der Exception ist in `content` gelandet, wo das **Modell** sie lesen und es erneut versuchen kann. Das
|
||||
ist Absicht: Ein Tool-Fehler ist Teil des Gesprächs, kein Absturz. Sieh dir immer `is_error` an,
|
||||
bevor du `structured_content` vertraust.
|
||||
Die Meldung des `ToolError` ist in `content` gelandet, wo das **Modell** sie lesen und es erneut versuchen kann. Das
|
||||
ist Absicht: Ein Tool-Fehler ist Teil des Gesprächs, kein Absturz. (Wäre das Tool mit einer
|
||||
anderen Exception abgestürzt, stünde in `content` nur `Error executing tool lookup_book`.) Sieh dir immer
|
||||
`is_error` an, bevor du `structured_content` vertraust.
|
||||
|
||||
!!! warning
|
||||
`is_error=True` deckt mehr ab als dein eigenes `raise`. Frag nach einem Tool, das der Server gar nicht hat
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
translation:
|
||||
sections: [9cac816674181eb0, 0700f337babcd4dd, 2bde0dd58cdf00f5, ff7401df479af877, 3d0832f39b0d7059, d4bf7e4479637768, 05e20c0a798860e7]
|
||||
sections: [9cac816674181eb0, 0700f337babcd4dd, 2bde0dd58cdf00f5, 40b4916d82eaf1d4, 3d0832f39b0d7059, dfa4446556badef0, 5bd93be2ab2ecb9c]
|
||||
tool: 1
|
||||
---
|
||||
# Client-Transporte {#client-transports}
|
||||
|
|
@ -87,15 +87,15 @@ oder übergibst deinem `httpx2.AsyncClient` ein explizites `verify=ssl_context`
|
|||
|
||||
Ein **stdio**-Server ist ein Subprozess. Der Client startet ihn, schreibt JSON-RPC in seine stdin und liest JSON-RPC aus seiner stdout. So betreibt ein Desktop-Host einen Server auf deinem Rechner: Ein Host *ist* dieser Code plus eine UI, und **[Mit einem echten Host verbinden](../get-started/real-host.md)** zeigt dieselbe Beziehung von der Seite des Hosts, als Konfigurationsdatei.
|
||||
|
||||
Beschreibe den Prozess mit `StdioServerParameters`, mach daraus mit `stdio_client` einen Transport und übergib *den* an `Client`:
|
||||
Beschreibe den Prozess mit `StdioServerParameters` und übergib das Objekt an `Client`:
|
||||
|
||||
```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` akzeptiert das Parameter-Objekt allein nicht. `StdioServerParameters` ist Konfiguration; `stdio_client(server)` ist der Transport, der weiß, wie er daraus einen Prozess startet. Immer einpacken.
|
||||
Beim Eintreten in den Block wird der Prozess gestartet. Beim Verlassen wird der Subprozess beendet: stdin schließen, warten, abschießen, falls er hängen bleibt. Du räumst ihn nie selbst auf.
|
||||
|
||||
Beim Verlassen des `async with`-Blocks wird auch der Subprozess beendet: stdin schließen, warten, abschießen, falls er hängen bleibt. Du räumst ihn nie selbst auf.
|
||||
Die stderr des Kindprozesses landet in deiner. Um sie woandershin zu leiten, baust du den Transport selbst mit `stdio_client` (aus `mcp`) und übergibst stattdessen diesen: `Client(stdio_client(server, errlog=log_file))`.
|
||||
|
||||
!!! warning
|
||||
Der Kindprozess erbt **nicht** deine Umgebung. Er bekommt eine minimale Allow-List (`HOME`, `LOGNAME`,
|
||||
|
|
@ -113,16 +113,16 @@ Beim Verlassen des `async with`-Blocks wird auch der Subprozess beendet: stdin s
|
|||
|
||||
Für `Client` ist alles oben Genannte dasselbe.
|
||||
|
||||
Ein **Transport** ist ein beliebiger asynchroner Kontextmanager, der ein `(read, write)`-Paar von Nachrichten-Streams liefert: formal das `Transport`-Protokoll in `mcp.client`. `Client` löst sein Argument nach Typ auf: Ein Server-Objekt verbindet im Prozess, ein `str` wird zu `streamable_http_client(url)`, und alles andere wird direkt als Transport betreten. Diese letzte Regel ist der Grund, warum `stdio_client(...)`, `streamable_http_client(...)` und `sse_client(...)` alle in denselben Platz passen – und warum du deinen eigenen schreiben kannst.
|
||||
Ein **Transport** ist ein beliebiger asynchroner Kontextmanager, der ein `(read, write)`-Paar von Nachrichten-Streams liefert: formal das `Transport`-Protokoll in `mcp.client`. `Client` löst sein Argument nach Typ auf: Ein Server-Objekt verbindet im Prozess, ein `str` wird zu `streamable_http_client(url)`, ein `StdioServerParameters` wird zu `stdio_client(params)`, und alles andere wird direkt als Transport betreten. Diese letzte Regel ist der Grund, warum `stdio_client(...)`, `streamable_http_client(...)` und `sse_client(...)` alle in denselben Platz passen – und warum du deinen eigenen schreiben kannst.
|
||||
|
||||
## Zusammenfassung {#recap}
|
||||
|
||||
* `Client(mcp)` (das Server-Objekt) verbindet im Speicher. Nutze es für Tests und zum Einbetten.
|
||||
* `Client("http://.../mcp")` (eine URL) verbindet über Streamable HTTP, den Produktions-Transport.
|
||||
* Header, Auth, Proxys und Timeouts gehören auf einen `httpx2.AsyncClient`, den du an `streamable_http_client(url, http_client=...)` übergibst. Es gibt kein Keyword `headers=`.
|
||||
* stdio ist `Client(stdio_client(StdioServerParameters(...)))`, nie das Parameter-Objekt allein.
|
||||
* stdio ist `Client(StdioServerParameters(...))`. Pack es nur dann selbst in `stdio_client(...)` ein, wenn du die stderr des Kindprozesses umleiten willst.
|
||||
* Der Subprozess bekommt eine Umgebung per Allow-List, nicht deine; `env=` ergänzt sie.
|
||||
* Ein Transport ist alles, womit du `async with x as (read, write)` schreiben kannst. Alles, was weder Server-Objekt noch URL ist, reicht `Client` direkt an dieses Protokoll weiter.
|
||||
* Ein Transport ist alles, womit du `async with x as (read, write)` schreiben kannst. Alles, was weder Server-Objekt noch URL noch `StdioServerParameters` ist, reicht `Client` direkt an dieses Protokoll weiter.
|
||||
* Das Erzeugen eines `Client` wählt den Transport. `async with` öffnet ihn.
|
||||
|
||||
Sobald der Transport offen ist, müssen sich beide Seiten auf eine Protokollversion einigen. Normalerweise denkst du nie darüber nach; wenn doch, ist **[Protokollversionen](../protocol-versions.md)** die richtige Seite.
|
||||
|
|
|
|||
Loading…
Reference in a new issue