Neuigkeiten von trion.
Immer gut informiert.

Spring AI MCP-Server: Spring-Dokumentation für LLMs bereitstellen

Spring AI

Wer Claude, Codex und Co. bei der Entwicklung von Spring-Anwendungen einsetzt, musste vielleicht auch schon feststellen, dass gerade neue Features des Frameworks nicht optimal verwendet werden. Aufgrund fehlender oder veralteter Trainingsdaten erzeugen die Sprachmodelle zwar korrekten, aber nicht optimalen Code. Sie definieren Beans, obwohl diese mittlerweile aus einer Autoconfiguration kommen, nutzen veraltete Klassen (z. B. JdbcTemplate statt JdbcClient) oder entpacken munter JARs, um den aktuellen Quellcode von Spring zu lesen.

In diesem Beitrag zeige ich, wie man mit Spring AI einen Model-Context-Protocol-Server (MCP-Server) für LLMs bereitstellt, der hier Abhilfe schafft. Der Server gibt Agents Zugriff auf die Spring-Dokumentation, die für das aktuelle Projekt relevant ist.

Spring AI ist ein offizielles Spring-Projekt, das generative KI mit dem Spring-Ökosystem verbindet. Es unterstützt zahlreiche KI-Modellanbieter und Modelltypen: neben Chat-Modellen (LLMs) auch Text-to-Image, Text-to-Speech und Audio-Transkription. Mit Tools, Memory und RAG-Funktionen deckt Spring AI auch Enterprise-Use-Cases ab.

Mit Spring AI lassen sich aber auch MCP-Server entwickeln. Das MCP stellt externe Tools auf standardisierte Art für LLMs bereit.

Wie gewohnt stellt Spring AI dafür Starter bereit. Auf Transportebene kann das MCP auf mehreren Protokollen aufsetzen. Für unseren Anwendungsfall passt ein zustandsloses Setup auf der Basis von Spring WebMVC. Entsprechend wählen wir folgenden Starter:

pom.xml mit Spring AI. Hinweis: Spring AI wird nicht von Spring Boot verwaltet. Daher die Version manuell angeben.
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
    <version>2.0.0</version>
</dependency>

Zusätzlich setzen wir folgende Property: spring.ai.mcp.server.protocol=STATELESS.

Unser Beispiel-Server soll LLMs die Spring-Dokumentation durchsuchen lassen. Dafür ist keine Session notwendig. Auch muss unser MCP-Server selbst kein LLM verwenden oder auf Daten des Clients zugreifen. Somit reicht ein einfacher, zustandsloser Request-Response-Flow.

application.yml
spring:
  ai:
    mcp:
      server:
        protocol: STATELESS
        name: spring-doc-search-mcp
        instructions: Version-pinned reference documentation for the Spring portfolio.

Die Instructions werden in der Regel an das LLM weitergegeben, damit es entscheiden kann, wann es den Server nutzt.

Beispiel: MCP-Server für Doku-Suche

Die Funktionen, die ein MCP-Server bereitstellt, heißen Tools. Ein Tool wird per Annotation definiert. Die Beschreibungen müssen einem LLM genug Kontext geben, um die Tools zu bedienen.

Tool definition für einen Suche
@Component
class SearchTool {

    private final DocService docService;

    SearchTool(DocService docService) {
        this.docService = docService;
    }

    @McpTool(
        name = "search_spring_docs",
        description = "Durchsucht die Spring-Referenzdokumentation nach einem Stichwort",
        annotations = @McpTool.McpAnnotations(
            title = "Search Spring reference docs" /* Weitere Argumente ausgelassen... */)
    )
    SearchResponse search(
            @McpToolParam(description = "Keyword query for searching the official Spring documentation")
            String query
    ) {
        return docService.search(query);
    }
}

Spring AI generiert die API, sodass der MCP-Client (z. B. Claude Code) die Tools automatisch erkennt und gezielt an ein LLM (z. B. Claude Opus 5) vermittelt. Das LLM kann den Client dann bitten, ein Tool aufzurufen, wenn es für die aktuelle Aufgabe relevant erscheint.

Mehr ist nicht nötig. Starten wir jetzt unsere Spring-Anwendung, können wir sie als MCP-Server anbinden.

Was genau unser Server über sich preisgibt, lässt sich mit einem JSON-RPC-Request auf /mcp prüfen. Dank des zustandslosen Protokolls genügt dafür ein einzelner POST ohne vorherigen Handshake:

Tool-Liste abfragen
curl -X POST http://localhost:8080/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Das Schema ist standardisiert und wird von jedem MCP-Client verstanden.

Antwort auf tools/list (gekürzt)
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "search_spring_docs",
        "title": "Search Spring reference docs",
        "description": "Durchsucht die Spring-Referenzdokumentation nach einem Stichwort",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "Keyword query for searching the official Spring documentation"
            }
          },
          "required": ["query"]
        }
        // annotations (readOnlyHint, ...) und weitere Felder ausgelassen
      }
      // ... weitere Tools
    ]
  }
}

Für meinen Anwendungsfall möchte ich den Server in Claude Code einbinden. Dazu genügt folgender Befehl:

claude mcp add --transport http spring-doc-mcp-local http://localhost:8080/mcp

Anschließend wird der MCP-Server als spring-doc-mcp-local in Claude Code aufgeführt.

Claude Code Dialog: Spring-doc-mcp-local MCP Server, Status connected, ein Tool verfügbar
Der eingerichtete MCP-Server in Claude Code (Ansicht über /mcp)

Für andere Clients gilt ein anderer Befehl. Alternativ lässt sich eine generische MCP-Konfiguration (z. B. .mcp.json) verwenden:

Generische MCP-Server-Konfiguration
{
  "mcpServers": {
    "spring-ai": {
      "type": "http",
      "url": "http://localhost:8080/mcp"
    }
  }
}

Prompt Engineering

Ob und wann ein LLM den MCP-Server anfragt, hängt stark von der Formulierung der Instructions und Tool-Beschreibungen ab. Starken Modellen genügt eine knappe, präzise Beschreibung. Schwache Modelle interpretieren sehr wörtlich und brauchen mehr Hilfestellung, etwa eine klare Anweisung wie "Nutze dafür den MCP-Server" im Prompt. Es lohnt sich daher zu testen, ob die Tools auch ohne explizite Aufforderung genutzt werden.

Context Pollution und Progressive Disclosure

Beim Arbeiten mit LLMs sollte man deren Kontext im Blick behalten. Untersuchungen zeigen, dass die Antwortqualität mit zunehmend gefülltem Kontextfenster merklich sinkt, lange bevor es voll ist. Tools von MCP-Servern belegen einen Teil dieses Kontexts. Das ist notwendig, damit das LLM überhaupt "weiß", welche Tools es gibt.

Claude Code Kontext-Anzeige: MCP-Tools stehen unter Available nur mit Namen, ohne geladene Beschreibung
Kontext-Verbrauch vor der ersten Tool-Nutzung: die MCP-Tools sind nur mit ihrem Namen bekannt

Am Beispiel von Claude Code sieht man, dass MCP-Tools jedoch lazy geladen werden. Das LLM kennt zunächst nur die Server-Instructions (bei uns aus der application.yml) und die Namen der Tools.

Erst wenn das LLM ein Tool für hilfreich hält, wird dessen Beschreibung geladen. Dieses Muster nennt man Progressive Disclosure (schrittweise Offenlegung). Die Umsetzung unterscheidet sich jedoch je nach Client.

Claude Code Kontext-Anzeige nach einem Tool-Aufruf: search_spring_docs ist mit 148 Tokens geladen
Nach der Tool-Nutzung: die Beschreibung des Tools belegt 148 Tokens im Kontext

Beim Einsatz von MCP-Servern sollte man daher prüfen, wie viel Kontext wann an das LLM geht, um Context Pollution zu vermeiden.

Durchsuchen der Spring-Dokumentation

Ein Tool mit Spring AI anzubieten ist schnell gemacht. Bisher haben wir uns jedoch nur um den MCP-Server selbst gekümmert. Die konkrete Implementierung des DocService ist noch offen. Dahinter steckt "normaler" Java-Code, der die Spring-Dokumentation lädt, indexiert, durchsucht, rankt und aufbereitet.

Intern hat sich das Tool bereits mehrfach bewährt, weshalb wir es hier veröffentlicht haben: sprig-mcp.de Sprig ist dabei kein Typo, sondern steht, passend zu Spring, für einen Zweig.

Der Sprig MCP-Server bietet zwei Tools: eine Suche, die eine Vorschau liefert, und ein Fetch, mit dem das LLM selbstständig vollständige Abschnitte zu relevanten Treffern nachschlagen kann. Beide Tools lassen sich hier live ausprobieren: sprig-mcp.de/app. Weitere Tools für Arbeit im Spring-Ökosystem, wie das Nachschlagen von Methodensignaturen und JavaDoc aus dem Framework sind für die Zukunft geplant.

Bei der Integration von KI-Funktionen in eigene Anwendungen unterstützt unsere KI-Beratung. Zu Spring AI und Spring Boot bieten wir außerdem passende Schulungen an:

Feedback oder Fragen zu einem Artikel - per E-Mail an [email protected] oder über das Kontaktformular. Wir freuen uns auf eine Kontaktaufnahme!

Suche

Los geht's!

Bitte teilen Sie uns mit, wie wir Sie am besten erreichen können.