MCP (Model Context Protocol) wird zum Standard für Tool-Integration

1. Übersicht

Große Sprachmodelle (LLMs) sind nur wirklich nützlich, wenn sie echte Daten lesen und echte Systeme aufrufen können: Bestellungen abfragen, Tickets lesen, Queries ausführen. Früher schrieb jede KI-Anwendung ihre eigene Integrationsmethode für jedes Tool. Das Model Context Protocol (MCP) wurde entwickelt, um diese Verbindung zu standardisieren.

Der Artikel erklärt, was MCP ist und warum es gerade viel Aufmerksamkeit bekommt. Danach schreibst du einen kleinen MCP-Server mit Spring Boot, konfigurierst den Client, um ihn aufzurufen, und erfährst, wann du MCP nicht verwenden solltest.

2. Was ist MCP?

MCP ist ein offenes Protokoll. Es definiert, wie eine KI-Anwendung externe Fähigkeiten erkennt und aufruft: Tools, Daten und Prompt-Vorlagen. Du kannst dir MCP wie einen “USB-Port” für KI vorstellen. Jedes Gerät, das dem Standard entspricht, funktioniert mit jedem Host, der den Standard unterstützt.

2.1. Drei Hauptrollen

  • Host: die Anwendung, mit der der Benutzer interagiert, z. B. ein KI-Assistent auf dem Desktop, eine IDE oder ein interner Chatbot.
  • Client: eine Komponente im Host. Jeder Client unterhält eine Eins-zu-eins-Verbindung mit einem Server.
  • Server: ein Programm, das Fähigkeiten für die KI bereitstellt, z. B. ein Server, der eine Bestellungsdatenbank ausliest, oder ein Server, der auf das Dateisystem zugreift.

2.2. Drei Arten von Server-Primitiven

  • Tools: Funktionen, die das Modell aufrufen kann, wenn es entscheidet, z. B. findOrder oder cancelOrder.
  • Resources: schreibgeschützte Daten wie Dateiinhalte oder Konfigurationsdatensätze, die in den Kontext aufgenommen werden.
  • Prompts: vordefinierte Prompt-Vorlagen, die der Benutzer auswählen und verwenden kann.

2.3. Zugrunde liegendes Protokoll

MCP verwendet JSON-RPC 2.0. Die beiden häufigsten Transport-Typen sind stdio, wenn der Host den Server als untergeordneten Prozess startet, und HTTP, wenn der Server remote läuft. Ein Tool-Aufruf sieht so aus:

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "findOrder",
    "arguments": { "orderId": "ORD-1001" }
  }
}

Der grundlegende Arbeitsablauf hat drei Schritte:

  1. Der Client sendet initialize, damit beide Seiten die Protokollversion und unterstützte Fähigkeiten austauschen.
  2. Der Client ruft tools/list auf, um eine Liste von Tools mit Beschreibungen und JSON-Schemas der Parameter zu erhalten.
  3. Wenn sich das Modell für die Verwendung eines Tools entscheidet, sendet der Client tools/call wie im Beispiel oben und gibt das Ergebnis an das Modell zurück.

Wichtig: Das Modell ruft den Server nicht direkt auf. Der Host steht dazwischen, sodass der Host den Benutzer fragen kann, bevor er ein sensibles Tool ausführt.

3. Warum wird MCP gerade so viel beachtet?

3.1. Das N × M Problem

Angenommen, es gibt N KI-Anwendungen und M Systeme, die verbunden werden sollen. Ohne einen gemeinsamen Standard musst du N × M Integrationen schreiben. Mit einem gemeinsamen Protokoll braucht jede Anwendung nur MCP einmal zu unterstützen, und jedes System braucht nur einen MCP-Server. Das Problem ist dann N + M.

3.2. Trennung der Verantwortung

Das Team, das das Bestellsystem besitzt, schreibt und betreibt seinen eigenen MCP-Server. Das Team, das den Chatbot macht, muss nur auf diesen Server verweisen. Die Business-Logik, Zugriffskontrolle und Audit-Logs bleiben an der richtigen Stelle und werden nicht in jeden Prompt oder jede Anwendung dupliziert.

3.3. Nicht an einen Anbieter von Modellen gebunden

Function Calling hat bei jedem LLM-Anbieter ein anderes Format. MCP liegt auf einer Ebene oberhalb dieses Formats. Der Server, den du heute schreibst, funktioniert immer noch, wenn du das Modell oder den Host wechselst.

3.4. Das Ökosystem wächst

Immer mehr KI-Assistenten, IDEs und Frameworks unterstützen MCP. Es gibt SDKs für viele Sprachen, und Java hat ein offizielles SDK, wobei Spring AI es bereits integriert hat. Das ist der Grund, warum viele MCP als einen vielversprechenden Kandidaten für einen Tool-Verbindungsstandard betrachten. Allerdings ist das Protokoll noch in der Entwicklung, daher solltest du die Spezifikation verfolgen, wenn du es längerfristig einsetzen möchtest.

4. Einen MCP-Server mit Spring Boot schreiben

Du wirst einen Server bauen, der zwei Tools bereitstellt: eines zum Nachschlagen und eines zum Stornieren von Bestellungen, das über stdio läuft.

4.1. Abhängigkeiten

Spring AI bietet einen Starter für MCP-Server. Importiere die BOM von Spring AI und verwende die neueste Version, die mit deinem Spring Boot 3.x kompatibel ist:

<properties>
    <java.version>21</java.version>
    <spring-ai.version><!-- aktuelle Spring AI Version --></spring-ai.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>${spring-ai.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-mcp-server</artifactId>
    </dependency>
</dependencies>

Der Starter spring-ai-starter-mcp-server unterstützt stdio-Transport. Wenn du den Server über HTTP ausführen möchtest, hat Spring AI separate Starters für Web MVC und WebFlux.

Hinweis: Der Artifact-Name von Spring AI hat sich zwischen den Milestone-Versionen geändert. Bitte prüfe die Dokumentation für die Version, die du wählst.

4.2. Domain und Tool

public record Order(String id, String customerName, double total, String status) {}
@Service
public class OrderTools {

    private final Map<String, Order> orders = new ConcurrentHashMap<>(Map.of(
            "ORD-1001", new Order("ORD-1001", "Nguyen Van An", 350_000, "SHIPPING"),
            "ORD-1002", new Order("ORD-1002", "Tran Thi Binh", 120_000, "PENDING")
    ));

    @Tool(description = "Bestellung nach Nummer durchsuchen und Kunde, Gesamtbetrag und Status zurückgeben")
    public Order findOrder(@ToolParam(description = "Bestellnummer, z. B. ORD-1001") String orderId) {
        Order order = orders.get(orderId);
        if (order == null) {
            throw new IllegalArgumentException("Bestellung nicht gefunden: " + orderId);
        }
        return order;
    }

    @Tool(description = "Bestellung stornieren. Nur Bestellungen im Status PENDING können storniert werden")
    public String cancelOrder(@ToolParam(description = "Zu stornierende Bestellnummer") String orderId) {
        Order order = findOrder(orderId);
        if (!"PENDING".equals(order.status())) {
            return "Kann nicht stornieren: Bestellung hat Status " + order.status();
        }
        orders.put(orderId, new Order(order.id(), order.customerName(), order.total(), "CANCELLED"));
        return "Bestellung " + orderId + " storniert";
    }
}

Zwei Annotationen spielen eine Hauptrolle:

  • @Tool (Paket org.springframework.ai.tool.annotation) markiert eine Methode als Tool. Der Teil description ist das, was das Modell liest, um zu entscheiden, ob es das Tool aufrufen soll. Je klarer die Beschreibung, desto besser wählt das Modell aus.
  • @ToolParam beschreibt jeden Parameter. Spring AI erzeugt ein JSON-Schema aus dem Parametertyp und dieser Beschreibung.

Beachte, dass cancelOrder eine Nachricht zurückgibt, statt eine Exception zu werfen, wenn eine Geschäftsregel verletzt wird. Das Modell liest diese Nachricht und erklärt sie dem Benutzer auf natürliche Weise.

4.3. Tools beim MCP-Server registrieren

@SpringBootApplication
public class OrderMcpServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderMcpServerApplication.class, args);
    }

    @Bean
    ToolCallbackProvider orderToolProvider(OrderTools orderTools) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(orderTools)
                .build();
    }
}

MethodToolCallbackProvider scannt Methoden mit @Tool in orderTools. Die Auto-Konfiguration des MCP-Servers findet alle ToolCallbackProvider-Beans und veröffentlicht sie über tools/list.

4.4. Konfiguration für stdio

spring.ai.mcp.server.name=order-mcp-server
spring.ai.mcp.server.version=0.0.1
spring.ai.mcp.server.stdio=true

spring.main.web-application-type=none
spring.main.banner-mode=off
logging.pattern.console=
logging.file.name=./logs/order-mcp-server.log

Bei stdio ist stdout der JSON-RPC-Transport-Kanal. Alles andere, das auf stdout gedruckt wird, kann das Protokoll beschädigen, einschließlich Banner und Log-Ausgaben. Daher deaktiviert die obige Konfiguration das Banner, schaltet die Console-Protokollierung aus und leitet Logs in eine Datei um.

Hinweis: Das ist der häufigste Fehler, wenn man neu mit MCP-Servern über stdio anfängt. Selbst eine System.out.println-Zeile zum Debuggen kann dazu führen, dass der Client Parse-Fehler meldet oder die Verbindung abbricht. Verwende einen Logger, der in eine Datei schreibt.

Baue eine JAR-Datei:

./mvnw clean package -DskipTests

5. Verbindung vom Client

Viele Hosts konfigurieren Server über eine JSON-Datei mit dem Schlüssel mcpServers. Der Dateiname und Speicherort hängen vom jeweiligen Host ab:

{
  "mcpServers": {
    "orders": {
      "command": "java",
      "args": ["-jar", "/opt/mcp/order-mcp-server.jar"]
    }
  }
}

Beim Start führt der Host den Befehl java -jar ... als untergeordneten Prozess aus, sendet initialize und dann tools/list. Du fragst: „Kann ich Bestellung ORD-1002 noch stornieren? Wenn ja, storniere sie bitte für mich.” Das Modell wird dann findOrder und dann cancelOrder aufrufen. Das Ergebnis des zweiten Aufrufs sieht so aus:

{"content":[{"type":"text","text":"Bestellung ORD-1002 storniert"}],"isError":false}

Normalerweise zeigt der Host ein Bestätigungsdialog an, bevor ein Tool ausgeführt wird. Du solltest dieses Verhalten bei Tools mit Nebenwirkungen wie cancelOrder beibehalten.

Wenn du möchtest, dass deine Spring-Anwendung die Rolle eines Client spielt, hat Spring AI auch einen MCP-Client-Starter. Dieser Starter verwandelt Tools von externen Servern in Tools, die mit ChatClient verwendet werden können.

6. Verhalten von Tools testen

Tools sind nur normale Java-Methoden, daher kannst du sie ohne MCP-Startup testen:

class OrderToolsTest {

    private final OrderTools tools = new OrderTools();

    @Test
    void shouldCancelPendingOrder() {
        String result = tools.cancelOrder("ORD-1002");

        assertThat(result).isEqualTo("Bestellung ORD-1002 storniert");
        assertThat(tools.findOrder("ORD-1002").status()).isEqualTo("CANCELLED");
    }

    @Test
    void shouldRefuseToCancelShippingOrder() {
        assertThat(tools.cancelOrder("ORD-1001"))
                .contains("Kann nicht stornieren")
                .contains("SHIPPING");
    }

    @Test
    void shouldFailWhenOrderNotFound() {
        assertThatThrownBy(() -> tools.findOrder("ORD-9999"))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("ORD-9999");
    }
}

Die drei Tests decken den Happy Path, Geschäftsregeln und den Fall „Bestellung nicht gefunden” ab. Der SDK kümmert sich um die Protokoll-Details. Das Wichtigste ist, dass deine Business-Logik das richtige Ergebnis zurückgibt und verständliche Nachrichten für das Modell liefert.

Für End-to-End-Tests kannst du MCP-Inspector-Tools verwenden. Sie ermöglichen es dir, Tools aufzulisten und manuell zu testen.

7. Praktische Anwendung: Was du beachten solltest

  • Gestalte Tools nach Geschäftslogik, nicht nach Datenbanktabellen. findOrder ist besser als ein universelles executeSql-Tool. Enge Tools sind leichter zu kontrollieren und helfen dem Modell, richtig zu wählen.
  • Minimale Berechtigungen. Der Server sollte ein Konto mit nur den erforderlichen Berechtigungen verwenden. Trenne Read- und Write-Tools und erwäge, Write-Tools nur in bestimmten Umgebungen zu aktivieren.
  • Vorsicht vor Prompt Injection. Daten, die Tools zurückgeben, z. B. vom Benutzer eingegebene Notizen, können Anweisungen zur Beeinflussung des Modells enthalten. Lass nicht zu, dass Tool-Ergebnisse automatisch gefährliche Aktionen auslösen, ohne Benutzerbestätigung.
  • Nutze nur vertrauenswürdige Server. Ein Third-Party-MCP-Server, der über stdio läuft, ist ein Prozess auf deinem Computer mit deinen Berechtigungen. Tool-Beschreibungen könnten auch bösartige Inhalte enthalten. Lese den Quellcode oder verwende nur Quellen, denen du vertraust.
  • Authentifizierung für Remote-Server. Wenn über HTTP läuft, platziere den Server hinter einer geeigneten Authentifizierung und protokolliere alle Tool-Aufrufe im Audit-Log.
  • Halten die Anzahl der Tools angemessen. Jedes Tool verbraucht Kontext für seine Beschreibung. Zu viele Tools können dazu führen, dass das Modell das falsche auswählt.

8. Wann man MCP NICHT verwenden sollte

  • Kleine Anwendungen mit nur einem Modell und wenigen Funktionen. Das direkte Function Calling des Frameworks, z. B. @Tool direkt mit ChatClient, ist einfacher. Du brauchst keinen zusätzlichen Prozess und keine zusätzliche Protokoll-Schicht.
  • Feste Verarbeitungsabläufe, bei denen das Modell nicht entscheiden muss. Wenn Schritt 1 immer API A aufruft und Schritt 2 immer API B aufruft, schreib normalen Code. Gib dem LLM nicht eine Aufgabe, die ein if besser macht.
  • Anforderungen für extrem niedrige Latenz oder hohe Determinismus. Jede Runde Modell → Client → Server fügt Latenz hinzu. Das Ergebnis des Modells ist auch nicht vollständig deterministisch.
  • Nicht umkehrbare Operationen ohne Überprüfung. Geldtransfers oder Massenlöschungen sollten nicht als automatisches Tool verfügbar sein. Wenn nötig, muss es immer einen Bestätigungsschritt geben.
  • Du brauchst eine API für andere Systeme zum Aufrufen. MCP wurde für KI entwickelt. Zwischen Services sind REST, gRPC oder Messaging immer noch die richtige Wahl.

9. Fazit

MCP löst ein praktisches Problem: KI mit Tools und Daten auf standardisierte Weise zu verbinden, statt dass jede Anwendung ihre eigene Methode schreibt. Dank des Host-Client-Server-Modells, der drei Primitiven Tools/Resources/Prompts und JSON-RPC kann ein Server, den du schreibst, auf vielen verschiedenen Hosts wiederverwendet werden.

Mit Spring AI brauchst du nur ein paar @Tool-Annotationen, ein ToolCallbackProvider-Bean und die richtige Konfiguration für stdio, um einen MCP-Server zu schreiben. Die schwierige Arbeit liegt woanders: enge und klare Tools entwerfen, strenge Berechtigungen einführen, Prompt Injection vermeiden. Du musst auch realistisch bleiben und erkennen, wenn normaler Code immer noch die bessere Lösung ist.

mcpaispring-aispring-boottech-trends