Ein MCP Server ist nur die halbe Miete. Die andere Hälfte ist der Client, der sich mit dem Server verbindet, verfügbare Tools entdeckt und sie dem AI-Modell zur Verfügung stellt.
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
const transport = new StdioClientTransport({
command: "node",
args: ["./my-mcp-server/build/index.js"]
});
const client = new Client({
name: "my-app",
version: "1.0.0"
});
await client.connect(transport);
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
server_params = StdioServerParameters(
command="python",
args=["my_mcp_server.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
Nach der Verbindung entdeckt der Client automatisch die verfügbaren Tools:
// Alle verfügbaren Tools auflisten
const { tools } = await client.listTools();
for (const tool of tools) {
console.log(`Tool: ${tool.name}`);
console.log(`Beschreibung: ${tool.description}`);
console.log(`Schema: ${JSON.stringify(tool.inputSchema)}`);
}
Client Server
│ │
│── initialize ────────────────▶│
│◀── capabilities ─────────────│
│ │
│── tools/list ────────────────▶│
│◀── tool definitions ─────────│
│ │
│── tools/call (get_weather) ──▶│
│◀── result ───────────────────│
Beim Verbindungsaufbau tauschen Client und Server ihre Fähigkeiten aus:
const capabilities = await client.getServerCapabilities();
// Prüfen, welche Features der Server unterstützt
if (capabilities.tools) {
// Server bietet Tools an
const tools = await client.listTools();
}
if (capabilities.resources) {
// Server bietet Resources an
const resources = await client.listResources();
}
if (capabilities.prompts) {
// Server bietet Prompts an
const prompts = await client.listPrompts();
}
Der eigentliche Wert entsteht, wenn MCP Tools dem AI-Modell zur Verfügung stehen:
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic();
// MCP Tools in Anthropic-Format konvertieren
const mcpTools = await client.listTools();
const anthropicTools = mcpTools.tools.map(tool => ({
name: tool.name,
description: tool.description,
input_schema: tool.inputSchema
}));
// AI-Modell mit Tools aufrufen
const response = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
messages: [{ role: "user", content: "Wie ist das Wetter in Berlin?" }],
tools: anthropicTools
});
// Tool-Calls über MCP ausführen
for (const block of response.content) {
if (block.type === "tool_use") {
const result = await client.callTool({
name: block.name,
arguments: block.input
});
}
}
try {
await client.connect(transport);
} catch (error) {
if (error.code === "CONNECTION_REFUSED") {
console.error("MCP Server nicht erreichbar");
}
// Fallback ohne MCP Tools
}
try {
const result = await client.callTool({ name: "get_weather", arguments: { city: "Berlin" } });
} catch (error) {
// Fehlermeldung an das LLM zurückgeben
return { content: [{ type: "text", text: `Fehler: ${error.message}` }] };
}
Praxis-Tipp: Implementieren Sie immer Fallback-Logik für den Fall, dass ein MCP Server nicht erreichbar ist. Ihre Anwendung sollte ohne MCP Tools degraded, aber funktionsfähig bleiben — nicht komplett abstürzen.