Zum Inhalt springen
EN DE

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?

AI App verbindet sich über MCP Client und Protocol mit drei MCP Servern für Dateien, Datenbank und Web API

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.

MCP erfordert zwei zusaetzliche Pakete:

Terminal-Fenster
npm install @ai-sdk/mcp @modelcontextprotocol/sdk

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.

MCP unterstuetzt verschiedene Transports für verschiedene Szenarien:

TransportEinsatzBeispiel
HTTP (Streamable)Remote Server, ProductionCloud-gehosteter MCP Server
SSEAlternative zu HTTPServer-Sent Events basiert
stdioLokale Server, DevelopmentLokaler 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.

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 laden
const tools = await client.tools(); // ← Gibt { toolName: tool, ... } zurück
console.log('Verfuegbare Tools:', Object.keys(tools));
// Tools direkt mit generateText nutzen
const 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 schliessen
await 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
};

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 typisiert

Die Schemas ueberschreiben die Server-Schemas nicht — sie fuegen TypeScript-Typen hinzu. Wenn der Server ein anderes Schema hat, bekommst Du zur Laufzeit einen Fehler.

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 generateText genutzt
  • 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 -y laedt 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!' } }]
Prompt fliesst in generateText, Tool Loop waehlt zwischen MCP Client und lokalem Tool, MCP verbindet zu Server

Uebung: Kombiniere MCP Tools mit dem Agentic Loop aus Challenge 3.3. Nutze MCP Tools als Teil eines Multi-Step Agent.

  1. Erstelle einen MCP Client (stdio mit dem Demo-Server)
  2. Lade die MCP Tools
  3. Fuege ein lokales calculatorTool hinzu (aus Challenge 3.1)
  4. Nutze generateText mit stopWhen: stepCountIs(3) und allen Tools
  5. Prompt: “Use the echo tool to repeat ‘Hello’, then calculate 42 * 17.”
  6. Logge den Agent-Verlauf: Welche Tools (MCP vs. lokal) wurden in welchem Schritt genutzt?
  7. 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.

Part of AI Learning — free courses from prompt to production. Jan on LinkedIn