Challenge 3.4: MCP
Wie verbindest Du Dein LLM mit externen Diensten — ohne für jeden eine eigene Integration zu bauen? Was wäre, wenn es ein standardisiertes Protokoll gaebe, das jeder Tool-Server spricht?
OVERVIEW
Abschnitt betitelt „OVERVIEW“MCP (Model Context Protocol) ist ein offenes Protokoll, das die Kommunikation zwischen AI-Anwendungen und Tool-Servern standardisiert. Ein MCP Client in Deiner App verbindet sich mit beliebig vielen MCP Servern — jeder Server stellt Tools bereit, die Dein LLM nutzen kann.
Ohne MCP: Für jeden externen Dienst baust Du eine eigene Integration. Eigene tool()-Definition, eigene API-Anbindung, eigene Fehlerbehandlung. Bei 10 Diensten hast Du 10 verschiedene Integrationen zu pflegen. Nicht standardisiert, nicht austauschbar.
Mit MCP: Ein Protokoll für alle Tools. Du verbindest Dich mit einem MCP Server und bekommst automatisch alle seine Tools — mit Beschreibungen, Schemas, fertig zur Nutzung. Server wechseln? Transport ändern? Ein Konfigurationswechsel, kein Code-Umbau.
WALKTHROUGH
Abschnitt betitelt „WALKTHROUGH“Setup für diese Challenge
Abschnitt betitelt „Setup für diese Challenge“MCP erfordert zwei zusaetzliche Pakete:
npm install @ai-sdk/mcp @modelcontextprotocol/sdkSchicht 1: MCP Client erstellen
Abschnitt betitelt „Schicht 1: MCP Client erstellen“Der MCP Client ist die Bruecke zwischen Deiner App und einem MCP Server. Du erstellst ihn mit createMCPClient:
import { createMCPClient } from '@ai-sdk/mcp';
const client = await createMCPClient({ transport: { type: 'http', // ← Transport-Typ url: 'https://my-mcp-server.com/mcp', // ← Server-URL },});createMCPClient ist async — es stellt die Verbindung zum Server her und handelt die Capabilities aus. Der Client weiss danach, welche Tools der Server anbietet.
Schicht 2: Transport-Optionen
Abschnitt betitelt „Schicht 2: Transport-Optionen“MCP unterstuetzt verschiedene Transports für verschiedene Szenarien:
| Transport | Einsatz | Beispiel |
|---|---|---|
| HTTP (Streamable) | Remote Server, Production | Cloud-gehosteter MCP Server |
| SSE | Alternative zu HTTP | Server-Sent Events basiert |
| stdio | Lokale Server, Development | Lokaler Prozess (Node.js, Python) |
HTTP — für Remote-Server in Production:
const client = await createMCPClient({ transport: { type: 'http', url: 'https://my-mcp-server.com/mcp', headers: { // ← Optional: Auth-Header Authorization: 'Bearer my-api-key', }, },});stdio — für lokale Server waehrend der Entwicklung:
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
const client = await createMCPClient({ transport: new StdioClientTransport({ command: 'node', // ← Befehl zum Starten des Servers args: ['my-mcp-server.js'], // ← Argumente }),});stdio startet den MCP Server als lokalen Kindprozess. Kommunikation laeuft über stdin/stdout. Ideal für Development und Testen.
Schicht 3: MCP Tools laden und nutzen
Abschnitt betitelt „Schicht 3: MCP Tools laden und nutzen“client.tools() gibt Dir alle Tools des Servers als Objekt zurück — fertig für generateText:
import { createMCPClient } from '@ai-sdk/mcp';import { generateText } from 'ai';import { anthropic } from '@ai-sdk/anthropic';
const client = await createMCPClient({ transport: { type: 'http', url: 'https://my-mcp-server.com/mcp', },});
// Alle Tools des Servers ladenconst tools = await client.tools(); // ← Gibt { toolName: tool, ... } zurück
console.log('Verfuegbare Tools:', Object.keys(tools));
// Tools direkt mit generateText nutzenconst result = await generateText({ model: anthropic('claude-sonnet-4-5-20250514'), tools, // ← MCP Tools wie lokale Tools nutzen prompt: 'Wie ist das Wetter in Berlin?',});
console.log(result.text);
// Wichtig: Client am Ende schliessenawait client.close();client.tools() gibt ein Objekt zurück, das genau das Format hat, das generateText erwartet. Du kannst MCP Tools und lokale Tools auch mischen:
const mcpTools = await client.tools();const allTools = { ...mcpTools, // ← MCP Tools calculator: calculatorTool, // ← Lokales Tool};Schicht 4: Typisierte Tools mit Schemas
Abschnitt betitelt „Schicht 4: Typisierte Tools mit Schemas“Standardmaessig sind MCP Tools untypisiert — die Schemas kommen vom Server. Du kannst aber eigene Zod-Schemas angeben für volle TypeScript-Typsicherheit:
import { z } from 'zod';
const tools = await client.tools({ schemas: { 'get-weather': { // ← Tool-Name vom Server inputSchema: z.object({ location: z.string(), }), outputSchema: z.object({ // ← Optional: Typisiertes Output temperature: z.number(), condition: z.string(), }), }, },});
// Jetzt sind Input und Output typisiertDie Schemas ueberschreiben die Server-Schemas nicht — sie fuegen TypeScript-Typen hinzu. Wenn der Server ein anderes Schema hat, bekommst Du zur Laufzeit einen Fehler.
Schicht 5: Client Lifecycle
Abschnitt betitelt „Schicht 5: Client Lifecycle“Der MCP Client haelt eine Verbindung offen. Du musst ihn am Ende schliessen:
const client = await createMCPClient({ transport: { type: 'http', url: 'https://server.com/mcp' },});
try { const tools = await client.tools(); const result = await generateText({ model: anthropic('claude-sonnet-4-5-20250514'), tools, prompt: 'Hallo!', }); console.log(result.text);} finally { await client.close(); // ← Immer schliessen!}Alternativ in onFinish beim Streaming:
const result = streamText({ model: anthropic('claude-sonnet-4-5-20250514'), tools: await client.tools(), prompt: 'Hallo!', onFinish: async () => { await client.close(); // ← Nach Stream-Ende schliessen },});Datei: challenge-3-4.ts
Aufgabe: Erstelle einen MCP Client mit stdio Transport, lade die verfügbaren Tools und nutze sie mit generateText.
import { createMCPClient } from '@ai-sdk/mcp';import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';import { generateText } from 'ai';import { anthropic } from '@ai-sdk/anthropic';
// TODO 1: Erstelle einen MCP Client mit stdio Transport// - command: 'npx'// - args: ['-y', '@modelcontextprotocol/server-everything']// (ein Demo-Server der verschiedene Test-Tools bereitstellt)
// TODO 2: Lade die verfügbaren Tools mit client.tools()// TODO 3: Logge die Tool-Namen: Object.keys(tools)
// TODO 4: Nutze die Tools mit generateText// - model: anthropic('claude-sonnet-4-5-20250514')// - tools: die geladenen MCP Tools// - prompt: Eine Frage die zu den verfügbaren Tools passt
// TODO 5: Logge result.text und result.toolCalls// TODO 6: Schliesse den Client mit client.close()Checkliste:
- MCP Client mit stdio Transport erstellt
-
client.tools()aufgerufen - Verfuegbare Tool-Namen geloggt
- Tools mit
generateTextgenutzt - Client am Ende geschlossen
Lösung anzeigen
import { createMCPClient } from '@ai-sdk/mcp';import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';import { generateText } from 'ai';import { anthropic } from '@ai-sdk/anthropic';
const client = await createMCPClient({ transport: new StdioClientTransport({ command: 'npx', args: ['-y', '@modelcontextprotocol/server-everything'], }),});
try { const tools = await client.tools(); console.log('Verfuegbare Tools:', Object.keys(tools));
const result = await generateText({ model: anthropic('claude-sonnet-4-5-20250514'), tools, prompt: 'Use the echo tool to say "Hello from MCP!"', });
console.log('\nAntwort:', result.text); console.log('Tool Calls:', result.toolCalls);} finally { await client.close();}Erklärung: Der @modelcontextprotocol/server-everything ist ein offizieller Demo-Server, der verschiedene Test-Tools bereitstellt (echo, add, etc.). Der stdio Transport startet ihn als lokalen Kindprozess. client.tools() laedt automatisch alle verfügbaren Tools mit ihren Beschreibungen und Schemas. Nach der Nutzung wird der Client — und damit der Kindprozess — sauber geschlossen.
Hinweis:
npx -ylaedt und startet den Demo-Server automatisch — Du musst ihn nicht vorher installieren.
Ausfuehren: npx tsx challenge-3-4.ts
Erwarteter Output (ungefaehr):
Verfuegbare Tools: [ 'echo', 'add', 'longRunningOperation', ... ]
Antwort: Hello from MCP!Tool Calls: [{ toolName: 'echo', args: { message: 'Hello from MCP!' } }]COMBINE
Abschnitt betitelt „COMBINE“Uebung: Kombiniere MCP Tools mit dem Agentic Loop aus Challenge 3.3. Nutze MCP Tools als Teil eines Multi-Step Agent.
- Erstelle einen MCP Client (stdio mit dem Demo-Server)
- Lade die MCP Tools
- Fuege ein lokales
calculatorToolhinzu (aus Challenge 3.1) - Nutze
generateTextmitstopWhen: stepCountIs(3)und allen Tools - Prompt: “Use the echo tool to repeat ‘Hello’, then calculate 42 * 17.”
- Logge den Agent-Verlauf: Welche Tools (MCP vs. lokal) wurden in welchem Schritt genutzt?
- Schliesse den Client am Ende
Optional Stretch Goal: Erstelle zwei MCP Clients (z.B. zwei verschiedene Server oder den gleichen Server zweimal) und merge ihre Tools in ein gemeinsames Tool-Objekt. Teste, ob der Agent Tools von beiden Servern nutzen kann.