Einleitung
Das Model Context Protocol (MCP) ist ein offener Standard, der definiert, wie KI-Modelle mit externen Tools, Diensten und Datenquellen kommunizieren. Es ersetzt individuelle Integrationen durch ein einziges, klar definiertes JSON-RPC-2.0-Protokoll und macht es einfach, jeden MCP-kompatiblen KI-Client mit jedem MCP-Server zu verbinden.
Mit Spring AI 2.0 ist das Erstellen eines MCP-Servers so einfach wie das Annotieren einer Spring-Bean-Methode — kein manuelles Schreiben von Schemas, kein Boilerplate-Code für den Transport. Dieser Artikel zeigt ein vollständiges Beispiel: eine Spring Boot 4-Anwendung, die MCP-Tools und -Resources bereitstellt, sowie einen begleitenden Client, der diese interaktiv über die Kommandozeile aufruft.
Der vollständige Quellcode ist auf GitHub verfügbar.
MCP-Dienste
Ein MCP-Server stellt drei Arten von Primitiven bereit:
| Primitive | Beschreibung |
|---|---|
| Tools | Aufrufbare Funktionen mit strukturierten Parametern und Rückgabewerten |
| Resources | Schreibgeschützte, URI-adressierbare Inhalte (Dateien, Datensätze, Live-Daten) |
| Prompts | Wiederverwendbare Prompt-Vorlagen mit benannten Parametern |
Dieser Artikel behandelt Tools und Resources. Als Transport wird Streamable HTTP verwendet: ein einzelner POST /mcp-Endpunkt, der JSON-RPC spricht, was das Testen mit curl oder einem Tool wie dem MCP Inspector leicht macht.
Projektaufbau
Das Projekt ist ein Multi-Modul-Maven-Build mit zwei Modulen:
ai/
├── pom.xml ← Parent POM
├── mcp-server/ ← Spring Boot App, Port 8080
└── mcp-client/ ← Spring Boot App, interaktive REPL
Parent POM (relevante Auszüge):
1<parent> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-parent</artifactId> 4 <version>4.0.6</version> 5</parent> 6 7<properties> 8 <java.version>21</java.version> 9 <spring-ai.version>2.0.0-M5</spring-ai.version> 10</properties> 11 12<dependencyManagement> 13 <dependencies> 14 <dependency> 15 <groupId>org.springframework.ai</groupId> 16 <artifactId>spring-ai-bom</artifactId> 17 <version>${spring-ai.version}</version> 18 <type>pom</type> 19 <scope>import</scope> 20 </dependency> 21 </dependencies> 22</dependencyManagement>
Der MCP-Server
Das Server-Modul benötigt folgenden Starter:
1<dependency> 2 <groupId>org.springframework.ai</groupId> 3 <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId> 4</dependency>
Transport konfigurieren
1# mcp-server/src/main/resources/application.yml 2spring: 3 ai: 4 mcp: 5 server: 6 name: ai-mcp-server 7 version: 1.0.0-SNAPSHOT 8 type: SYNC 9 protocol: STREAMABLE 10server: 11 port: 8080
protocol: STREAMABLE wählt den Streamable-HTTP-Transport aus. Spring AI richtet den POST /mcp-Endpunkt automatisch ein — kein Controller-Code nötig.
Tools bereitstellen mit @McpTool
Tools sind gewöhnliche Spring Beans. Eine Methode wird mit @McpTool annotiert und Spring AI generiert das JSON-Schema für die Parameter automatisch:
1@Component
2public class PolicyNumberTools {
3
4 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
5
6 @McpTool(description = "Creates a new policy number")
7 public String createPolicyNumber(
8 @McpToolParam(description = "Id of the LOB (line of business)", required = true)
9 String lobId) {
10 String timestamp = LocalDateTime.now().format(FORMATTER);
11 String randomPart = RandomStringUtils.randomAlphanumeric(5);
12 return (lobId + timestamp + randomPart).toUpperCase();
13 }
14
15}
Beim Start protokolliert Spring AI Registered tools: 1 — mehr ist nicht nötig.
Resources bereitstellen mit @McpResource
Resources werden über eine URI identifiziert und geben ihren Inhalt als String zurück. Die Annotation funktioniert genauso wie @McpTool:
1@Component
2public class DemoResource {
3
4 @McpResource(
5 uri = "file:///demo.txt",
6 name = "demo-text",
7 description = "Demo text resource loaded from the classpath"
8 )
9 public String demoText() {
10 try {
11 return new ClassPathResource("demo.txt")
12 .getContentAsString(StandardCharsets.UTF_8);
13 } catch (IOException e) {
14 throw new RuntimeException("Failed to read demo.txt", e);
15 }
16 }
17}
Das uri-Attribut ist der Protokoll-Bezeichner, der Clients in resources/list zurückgegeben wird. Das Schema (file:///, db:// usw.) ist frei wählbar — es hat keine technische Bedeutung für den Dateizugriff; ClassPathResource übernimmt das eigentliche Lesen.
Testen mit dem MCP Inspector
Der MCP Inspector ist eine einfache Möglichkeit, unseren MCP-Server auszuprobieren‚ ohne eigenen Client-Code schreiben zu müssen:
1npx @modelcontextprotocol/inspector http://localhost:8080/mcp
Als Transporttyp Streamable HTTP auswählen. Die Oberfläche zeigt alle registrierten Tools und Resources an und ermöglicht deren direkten Aufruf im Browser.
Einen eigenen MCP-Client bauen
Spring AI macht es auch sehr leicht, eigene MCP-Clients zu entwickeln. Das Client-Modul benötigt folgende Abhängigkeit:
1<dependency> 2 <groupId>org.springframework.ai</groupId> 3 <artifactId>spring-ai-starter-mcp-client</artifactId> 4</dependency>
Client-Konfiguration
1# mcp-client/src/main/resources/application.yml 2spring: 3 main: 4 web-application-type: none 5 ai: 6 mcp: 7 client: 8 enabled: true 9 type: SYNC 10 request-timeout: 30s 11 streamable-http: 12 connections: 13 demo: 14 url: http://localhost:8080 15 endpoint: /mcp
Den Server aufrufen
Spring AI konfiguriert automatisch eine List<McpSyncClient>-Bean. Diese wird injiziert und der erste (und einzige) Client verwendet:
1@Service
2public class McpClientService {
3
4 private final McpSyncClient mcpClient;
5
6 public McpClientService(List<McpSyncClient> mcpClients) {
7 this.mcpClient = mcpClients.getFirst();
8 }
9
10 public List<McpSchema.Tool> listTools() {
11 return mcpClient.listTools().tools();
12 }
13
14 public List<McpSchema.Resource> listResources() {
15 return mcpClient.listResources().resources();
16 }
17
18 public String callTool(String toolName, Map<String, Object> arguments) {
19 McpSchema.CallToolResult result = mcpClient.callTool(
20 new McpSchema.CallToolRequest(toolName, arguments));
21 return result.content().stream()
22 .filter(c -> c instanceof McpSchema.TextContent)
23 .map(c -> ((McpSchema.TextContent) c).text())
24 .findFirst()
25 .orElse("");
26 }
27}
Interaktive REPL
Ein CommandLineRunner kapselt eine einfache Scanner-Schleife, sodass der Client ohne zusätzliches Framework als Kommandozeilen-Tool nutzbar ist:
mcp-client> list-tools
createPolicyNumber Creates a new policy number
mcp-client> create-policy-number HR
HR20260511103235X0WJT
mcp-client> list-resources
file:///demo.txt Demo text resource loaded from the classpath
Agent Smith — jetzt sind Sie dran
In Zeiten, in denen immer mehr Agenten in Ihrer IT-Landschaft auftauchen, wird MCP das Protokoll sein, um diese in Ihre bestehenden Anwendungen zu integrieren. Wenn ein wesentlicher Teil Ihrer Anwendungen das Spring-(Boot-)Ökosystem nutzt, ist Spring AI das Mittel der Wahl.
Aus architektonischer Sicht gibt es mindestens zwei grundlegende Muster, um MCP-Fähigkeit einzuführen. Entweder erstellt man eine dünne Schicht in bestehenden Business-Services, um zusätzliche MCP-Endpunkte bereitzustellen ...
... oder man fügt eine separate Adapter-/Gateway-Anwendung dazwischen ein:
Weiterführende Lektüre
Falls Sie sich allgemein für MCP interessieren, sind vielleicht diese Blogbeiträge einen Blick wert:
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Blog-Autor*in
Tobias Trelle
Software-Architekt
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.