42 KiB
Erste Schritte mit MCP
Willkommen zu Ihren ersten Schritten mit dem Model Context Protocol (MCP)! Egal, ob Sie neu bei MCP sind oder Ihr Verständnis vertiefen möchten, diese Anleitung führt Sie durch den wesentlichen Einrichtungs- und Entwicklungsprozess. Sie werden entdecken, wie MCP eine nahtlose Integration zwischen KI-Modellen und Anwendungen ermöglicht und lernen, wie Sie Ihre Umgebung schnell für den Aufbau und das Testen von MCP-basierten Lösungen vorbereiten.
TLDR; Wenn Sie KI-Anwendungen entwickeln, wissen Sie, dass Sie Ihrem LLM (großes Sprachmodell) Werkzeuge und weitere Ressourcen hinzufügen können, um das LLM wissensreicher zu machen. Wenn Sie diese Werkzeuge und Ressourcen jedoch auf einem Server platzieren, können die Funktionen von App und Server von jedem Client mit/ohne LLM genutzt werden.
Übersicht
Diese Lektion bietet praktische Anleitungen zum Einrichten von MCP-Umgebungen und zum Erstellen Ihrer ersten MCP-Anwendungen. Sie lernen, wie Sie die notwendigen Werkzeuge und Frameworks einrichten, grundlegende MCP-Server bauen, Host-Anwendungen erstellen und Ihre Implementierungen testen.
Das Model Context Protocol (MCP) ist ein offenes Protokoll, das standardisiert, wie Anwendungen Kontext für LLMs bereitstellen. Denken Sie an MCP wie einen USB-C-Anschluss für KI-Anwendungen – es bietet eine standardisierte Möglichkeit, KI-Modelle mit verschiedenen Datenquellen und Werkzeugen zu verbinden.
Lernziele
Am Ende dieser Lektion sind Sie in der Lage:
- Entwicklungsumgebungen für MCP in C#, Java, Python, TypeScript und Rust einzurichten
- Grundlegende MCP-Server mit benutzerdefinierten Funktionen (Ressourcen, Prompts und Werkzeuge) zu bauen und bereitzustellen
- Host-Anwendungen zu erstellen, die sich mit MCP-Servern verbinden
- MCP-Implementierungen zu testen und zu debuggen
Einrichtung Ihrer MCP-Umgebung
Bevor Sie mit MCP arbeiten, ist es wichtig, Ihre Entwicklungsumgebung vorzubereiten und den grundlegenden Arbeitsablauf zu verstehen. Dieser Abschnitt führt Sie durch die ersten Schritte, um einen reibungslosen Start mit MCP zu gewährleisten.
Voraussetzungen
Bevor Sie mit der MCP-Entwicklung beginnen, stellen Sie sicher, dass Sie Folgendes haben:
- Entwicklungsumgebung: Für Ihre gewählte Sprache (C#, Java, Python, TypeScript oder Rust)
- IDE/Editor: Visual Studio, Visual Studio Code, IntelliJ, Eclipse, PyCharm oder ein moderner Code-Editor Ihrer Wahl
- Paketmanager: NuGet, Maven/Gradle, pip, npm/yarn oder Cargo
- API-Schlüssel: Für alle KI-Dienste, die Sie in Ihren Host-Anwendungen verwenden möchten
Grundstruktur eines MCP-Servers
Ein MCP-Server umfasst typischerweise:
- Serverkonfiguration: Einrichtung von Port, Authentifizierung und weiteren Einstellungen
- Ressourcen: Daten und Kontexte, die LLMs bereitgestellt werden
- Werkzeuge: Funktionalitäten, die Modelle aufrufen können
- Prompts: Vorlagen zur Generierung oder Strukturierung von Text
Hier ein vereinfachtes Beispiel in TypeScript:
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Erstellen Sie einen MCP-Server
const server = new McpServer({
name: "Demo",
version: "1.0.0"
});
// Fügen Sie ein Additionstool hinzu
server.tool("add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Fügen Sie eine dynamische Begrüßungsressource hinzu
server.resource(
"file",
// Der Parameter 'list' steuert, wie die Ressource verfügbare Dateien auflistet. Wenn er auf undefiniert gesetzt wird, wird die Auflistung für diese Ressource deaktiviert.
new ResourceTemplate("file://{path}", { list: undefined }),
async (uri, { path }) => ({
contents: [{
uri: uri.href,
text: `File, ${path}!`
}]
})
);
// Fügen Sie eine Dateiresource hinzu, die den Inhalt der Datei liest
server.resource(
"file",
new ResourceTemplate("file://{path}", { list: undefined }),
async (uri, { path }) => {
let text;
try {
text = await fs.readFile(path, "utf8");
} catch (err) {
text = `Error reading file: ${err.message}`;
}
return {
contents: [{
uri: uri.href,
text
}]
};
}
);
server.prompt(
"review-code",
{ code: z.string() },
({ code }) => ({
messages: [{
role: "user",
content: {
type: "text",
text: `Please review this code:\n\n${code}`
}
}]
})
);
// Beginnen Sie mit dem Empfangen von Nachrichten auf stdin und dem Senden von Nachrichten auf stdout
const transport = new StdioServerTransport();
await server.connect(transport);
Im obigen Code haben wir:
- Die notwendigen Klassen aus dem MCP TypeScript SDK importiert.
- Eine neue MCP-Serverinstanz erstellt und konfiguriert.
- Ein benutzerdefiniertes Werkzeug (
calculator) mit einer Handler-Funktion registriert. - Den Server gestartet, um eingehende MCP-Anfragen zu empfangen.
Testen und Debuggen
Bevor Sie Ihren MCP-Server testen, ist es wichtig, die verfügbaren Werkzeuge und bewährten Verfahren für das Debuggen zu verstehen. Effektives Testen stellt sicher, dass Ihr Server wie erwartet funktioniert und hilft Ihnen, Probleme schnell zu erkennen und zu beheben. Der folgende Abschnitt beschreibt empfohlene Ansätze zur Validierung Ihrer MCP-Implementierung.
MCP stellt Werkzeuge bereit, die Ihnen beim Testen und Debuggen Ihrer Server helfen:
- Inspector-Werkzeug, eine grafische Oberfläche, mit der Sie sich mit Ihrem Server verbinden und Ihre Werkzeuge, Prompts und Ressourcen testen können.
- curl, Sie können sich auch mit einem Kommandozeilenwerkzeug wie curl oder anderen Clients verbinden, die HTTP-Kommandos erstellen und ausführen können.
Verwendung des MCP Inspectors
Der MCP Inspector ist ein visuelles Testwerkzeug, das Ihnen hilft:
- Serverfunktionen erkennen: Automatische Erkennung verfügbarer Ressourcen, Werkzeuge und Prompts
- Werkzeugausführung testen: Verschiedene Parameter ausprobieren und Antworten in Echtzeit sehen
- Server-Metadaten anzeigen: Serverinformationen, Schemas und Konfigurationen prüfen
# ex TypeScript, MCP Inspektor installieren und ausführen
npx @modelcontextprotocol/inspector node build/index.js
Wenn Sie die oben genannten Befehle ausführen, startet der MCP Inspector eine lokale Weboberfläche in Ihrem Browser. Sie werden ein Dashboard sehen, das Ihre registrierten MCP-Server sowie deren verfügbare Werkzeuge, Ressourcen und Prompts anzeigt. Die Oberfläche erlaubt es Ihnen, Werkzeugausführungen interaktiv zu testen, Server-Metadaten zu inspizieren und Echtzeit-Antworten zu sehen, was die Validierung und das Debuggen Ihrer MCP-Server-Implementierungen erleichtert.
Hier ein Screenshot, wie das aussehen kann:
Häufige Einrichtungsprobleme und Lösungen
| Problem | Mögliche Lösung |
|---|---|
| Verbindung abgelehnt | Prüfen, ob der Server läuft und der Port korrekt ist |
| Fehler bei Werkzeugausführung | Parameterüberprüfung und Fehlerbehandlung überprüfen |
| Authentifizierungsfehler | API-Schlüssel und Berechtigungen verifizieren |
| Schema-Validierungsfehler | Sicherstellen, dass Parameter dem definierten Schema entsprechen |
| Server startet nicht | Port-Konflikte oder fehlende Abhängigkeiten prüfen |
| CORS-Fehler | Korrekte CORS-Header für Cross-Origin-Anfragen konfigurieren |
| Authentifizierungsprobleme | Gültigkeit von Token und Berechtigungen prüfen |
Lokale Entwicklung
Für die lokale Entwicklung und das Testen können Sie MCP-Server direkt auf Ihrem Rechner ausführen:
- Starten Sie den Serverprozess: Führen Sie Ihre MCP-Serveranwendung aus
- Konfigurieren Sie das Netzwerk: Stellen Sie sicher, dass der Server auf dem erwarteten Port erreichbar ist
- Verbinden Sie Clients: Verwenden Sie lokale Verbindungs-URLs wie
http://localhost:3000
# Beispiel: Ausführen eines TypeScript MCP-Servers lokal
npm run start
# Server läuft unter http://localhost:3000
Ihren ersten MCP-Server erstellen
Wir haben in einer vorherigen Lektion Kernkonzepte behandelt, jetzt ist es Zeit, dieses Wissen anzuwenden.
Was ein Server kann
Bevor wir mit dem Schreiben von Code beginnen, erinnern wir uns daran, was ein Server kann:
Ein MCP-Server kann zum Beispiel:
- Auf lokale Dateien und Datenbanken zugreifen
- Sich mit entfernten APIs verbinden
- Berechnungen durchführen
- Mit anderen Werkzeugen und Diensten integriert werden
- Eine Benutzeroberfläche für Interaktionen bereitstellen
Super, jetzt wo wir wissen, was wir damit machen können, fangen wir an zu programmieren.
Übung: Einen Server erstellen
Um einen Server zu erstellen, müssen Sie folgende Schritte befolgen:
- Installieren Sie das MCP SDK.
- Erstellen Sie ein Projekt und richten Sie die Projektstruktur ein.
- Schreiben Sie den Server-Code.
- Testen Sie den Server.
-1- Projekt erstellen
TypeScript
# Erstellen Sie das Projektverzeichnis und initialisieren Sie das npm-Projekt
mkdir calculator-server
cd calculator-server
npm init -y
Python
# Projektverzeichnis erstellen
mkdir calculator-server
cd calculator-server
# Öffnen Sie den Ordner in Visual Studio Code – Überspringen Sie dies, wenn Sie eine andere IDE verwenden
code .
.NET
dotnet new console -n McpCalculatorServer
cd McpCalculatorServer
Java
Für Java erstellen Sie ein Spring Boot-Projekt:
curl https://start.spring.io/starter.zip \
-d dependencies=web \
-d javaVersion=21 \
-d type=maven-project \
-d groupId=com.example \
-d artifactId=calculator-server \
-d name=McpServer \
-d packageName=com.microsoft.mcp.sample.server \
-o calculator-server.zip
Entpacken Sie die ZIP-Datei:
unzip calculator-server.zip -d calculator-server
cd calculator-server
# optional den ungenutzten Test entfernen
rm -rf src/test/java
Fügen Sie die folgende komplette Konfiguration in Ihre pom.xml-Datei ein:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Spring Boot parent for dependency management -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.0</version>
<relativePath />
</parent>
<!-- Project coordinates -->
<groupId>com.example</groupId>
<artifactId>calculator-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Calculator Server</name>
<description>Basic calculator MCP service for beginners</description>
<!-- Properties -->
<properties>
<java.version>21</java.version>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<!-- Spring AI BOM for version management -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Dependencies -->
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Build configuration -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>21</release>
</configuration>
</plugin>
</plugins>
</build>
<!-- Repositories for Spring AI snapshots -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>
</project>
Rust
mkdir calculator-server
cd calculator-server
cargo init
-2- Abhängigkeiten hinzufügen
Jetzt, wo Ihr Projekt erstellt wurde, fügen wir als nächstes die Abhängigkeiten hinzu:
TypeScript
# Falls noch nicht installiert, TypeScript global installieren
npm install typescript -g
# Installieren Sie das MCP SDK und Zod zur Schemavalidierung
npm install @modelcontextprotocol/sdk zod
npm install -D @types/node typescript
Python
# Erstellen Sie eine virtuelle Umgebung und installieren Sie die Abhängigkeiten
python -m venv venv
venv\Scripts\activate
pip install "mcp[cli]"
Java
cd calculator-server
./mvnw clean install -DskipTests
Rust
cargo add rmcp --features server,transport-io
cargo add serde
cargo add tokio --features rt-multi-thread
-3- Projektdateien erstellen
TypeScript
Öffnen Sie die package.json-Datei und ersetzen Sie den Inhalt folgendermaßen, um sicherzustellen, dass Sie den Server bauen und ausführen können:
{
"name": "calculator-server",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"build": "tsc",
"start": "npm run build && node ./build/index.js",
},
"keywords": [],
"author": "",
"license": "ISC",
"description": "A simple calculator server using Model Context Protocol",
"dependencies": {
"@modelcontextprotocol/sdk": "^1.16.0",
"zod": "^3.25.76"
},
"devDependencies": {
"@types/node": "^24.0.14",
"typescript": "^5.8.3"
}
}
Erstellen Sie eine tsconfig.json mit folgendem Inhalt:
{
"compilerOptions": {
"target": "ES2022",
"module": "Node16",
"moduleResolution": "Node16",
"outDir": "./build",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Erstellen Sie ein Verzeichnis für Ihren Quellcode:
mkdir src
touch src/index.ts
Python
Erstellen Sie eine Datei server.py
touch server.py
.NET
Installieren Sie die erforderlichen NuGet-Pakete:
dotnet add package ModelContextProtocol --prerelease
dotnet add package Microsoft.Extensions.Hosting
Java
Für Java Spring Boot-Projekte wird die Projektstruktur automatisch erstellt.
Rust
Bei Rust wird eine Datei src/main.rs standardmäßig beim Ausführen von cargo init erstellt. Öffnen Sie die Datei und löschen Sie den Standardcode.
-4- Server-Code erstellen
TypeScript
Erstellen Sie eine Datei index.ts und fügen Sie folgenden Code hinzu:
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Erstellen Sie einen MCP-Server
const server = new McpServer({
name: "Calculator MCP Server",
version: "1.0.0"
});
Nun haben Sie einen Server, aber er macht noch nicht viel, das wollen wir ändern.
Python
# server.py
from mcp.server.fastmcp import FastMCP
# Erstelle einen MCP-Server
mcp = FastMCP("Demo")
.NET
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
// add features
Java
Für Java erstellen Sie die Kernserver-Komponenten. Ändern Sie zuerst die Hauptanwendungsklasse:
src/main/java/com/microsoft/mcp/sample/server/McpServerApplication.java:
package com.microsoft.mcp.sample.server;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.microsoft.mcp.sample.server.service.CalculatorService;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider calculatorTools(CalculatorService calculator) {
return MethodToolCallbackProvider.builder().toolObjects(calculator).build();
}
}
Erstellen Sie den Rechner-Service src/main/java/com/microsoft/mcp/sample/server/service/CalculatorService.java:
package com.microsoft.mcp.sample.server.service;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
/**
* Service for basic calculator operations.
* This service provides simple calculator functionality through MCP.
*/
@Service
public class CalculatorService {
/**
* Add two numbers
* @param a The first number
* @param b The second number
* @return The sum of the two numbers
*/
@Tool(description = "Add two numbers together")
public String add(double a, double b) {
double result = a + b;
return formatResult(a, "+", b, result);
}
/**
* Subtract one number from another
* @param a The number to subtract from
* @param b The number to subtract
* @return The result of the subtraction
*/
@Tool(description = "Subtract the second number from the first number")
public String subtract(double a, double b) {
double result = a - b;
return formatResult(a, "-", b, result);
}
/**
* Multiply two numbers
* @param a The first number
* @param b The second number
* @return The product of the two numbers
*/
@Tool(description = "Multiply two numbers together")
public String multiply(double a, double b) {
double result = a * b;
return formatResult(a, "*", b, result);
}
/**
* Divide one number by another
* @param a The numerator
* @param b The denominator
* @return The result of the division
*/
@Tool(description = "Divide the first number by the second number")
public String divide(double a, double b) {
if (b == 0) {
return "Error: Cannot divide by zero";
}
double result = a / b;
return formatResult(a, "/", b, result);
}
/**
* Calculate the power of a number
* @param base The base number
* @param exponent The exponent
* @return The result of raising the base to the exponent
*/
@Tool(description = "Calculate the power of a number (base raised to an exponent)")
public String power(double base, double exponent) {
double result = Math.pow(base, exponent);
return formatResult(base, "^", exponent, result);
}
/**
* Calculate the square root of a number
* @param number The number to find the square root of
* @return The square root of the number
*/
@Tool(description = "Calculate the square root of a number")
public String squareRoot(double number) {
if (number < 0) {
return "Error: Cannot calculate square root of a negative number";
}
double result = Math.sqrt(number);
return String.format("√%.2f = %.2f", number, result);
}
/**
* Calculate the modulus (remainder) of division
* @param a The dividend
* @param b The divisor
* @return The remainder of the division
*/
@Tool(description = "Calculate the remainder when one number is divided by another")
public String modulus(double a, double b) {
if (b == 0) {
return "Error: Cannot divide by zero";
}
double result = a % b;
return formatResult(a, "%", b, result);
}
/**
* Calculate the absolute value of a number
* @param number The number to find the absolute value of
* @return The absolute value of the number
*/
@Tool(description = "Calculate the absolute value of a number")
public String absolute(double number) {
double result = Math.abs(number);
return String.format("|%.2f| = %.2f", number, result);
}
/**
* Get help about available calculator operations
* @return Information about available operations
*/
@Tool(description = "Get help about available calculator operations")
public String help() {
return "Basic Calculator MCP Service\n\n" +
"Available operations:\n" +
"1. add(a, b) - Adds two numbers\n" +
"2. subtract(a, b) - Subtracts the second number from the first\n" +
"3. multiply(a, b) - Multiplies two numbers\n" +
"4. divide(a, b) - Divides the first number by the second\n" +
"5. power(base, exponent) - Raises a number to a power\n" +
"6. squareRoot(number) - Calculates the square root\n" +
"7. modulus(a, b) - Calculates the remainder of division\n" +
"8. absolute(number) - Calculates the absolute value\n\n" +
"Example usage: add(5, 3) will return 5 + 3 = 8";
}
/**
* Format the result of a calculation
*/
private String formatResult(double a, String operator, double b, double result) {
return String.format("%.2f %s %.2f = %.2f", a, operator, b, result);
}
}
Optionale Komponenten für einen produktionsbereiten Service:
Erstellen Sie eine Startkonfiguration src/main/java/com/microsoft/mcp/sample/server/config/StartupConfig.java:
package com.microsoft.mcp.sample.server.config;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class StartupConfig {
@Bean
public CommandLineRunner startupInfo() {
return args -> {
System.out.println("\n" + "=".repeat(60));
System.out.println("Calculator MCP Server is starting...");
System.out.println("SSE endpoint: http://localhost:8080/sse");
System.out.println("Health check: http://localhost:8080/actuator/health");
System.out.println("=".repeat(60) + "\n");
};
}
}
Erstellen Sie einen Health-Controller src/main/java/com/microsoft/mcp/sample/server/controller/HealthController.java:
package com.microsoft.mcp.sample.server.controller;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HealthController {
@GetMapping("/health")
public ResponseEntity<Map<String, Object>> healthCheck() {
Map<String, Object> response = new HashMap<>();
response.put("status", "UP");
response.put("timestamp", LocalDateTime.now().toString());
response.put("service", "Calculator MCP Server");
return ResponseEntity.ok(response);
}
}
Erstellen Sie einen Ausnahme-Handler src/main/java/com/microsoft/mcp/sample/server/exception/GlobalExceptionHandler.java:
package com.microsoft.mcp.sample.server.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {
ErrorResponse error = new ErrorResponse(
"Invalid_Input",
"Invalid input parameter: " + ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
}
public static class ErrorResponse {
private String code;
private String message;
public ErrorResponse(String code, String message) {
this.code = code;
this.message = message;
}
// Getter
public String getCode() { return code; }
public String getMessage() { return message; }
}
}
Erstellen Sie ein benutzerdefiniertes Banner src/main/resources/banner.txt:
_____ _ _ _
/ ____| | | | | | |
| | __ _| | ___ _ _| | __ _| |_ ___ _ __
| | / _` | |/ __| | | | |/ _` | __/ _ \| '__|
| |___| (_| | | (__| |_| | | (_| | || (_) | |
\_____\__,_|_|\___|\__,_|_|\__,_|\__\___/|_|
Calculator MCP Server v1.0
Spring Boot MCP Application
Rust
Fügen Sie den folgenden Code oben in die Datei src/main.rs ein. Dieser importiert die notwendigen Bibliotheken und Module für Ihren MCP-Server.
use rmcp::{
handler::server::{router::tool::ToolRouter, tool::Parameters},
model::{ServerCapabilities, ServerInfo},
schemars, tool, tool_handler, tool_router,
transport::stdio,
ServerHandler, ServiceExt,
};
use std::error::Error;
Der Rechner-Server wird ein einfacher Server sein, der zwei Zahlen addieren kann. Erstellen wir eine Struktur, um die Rechner-Anfrage zu repräsentieren.
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CalculatorRequest {
pub a: f64,
pub b: f64,
}
Als Nächstes erstellen wir eine Struktur, die den Rechner-Server repräsentiert. Diese Struktur hält den Tool-Router, der zur Registrierung von Werkzeugen verwendet wird.
#[derive(Debug, Clone)]
pub struct Calculator {
tool_router: ToolRouter<Self>,
}
Nun können wir die Calculator-Struktur implementieren, um eine neue Serverinstanz zu erstellen und den Server-Handler zu implementieren, der Serverinformationen bereitstellt.
#[tool_router]
impl Calculator {
pub fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
}
#[tool_handler]
impl ServerHandler for Calculator {
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some("A simple calculator tool".into()),
capabilities: ServerCapabilities::builder().enable_tools().build(),
..Default::default()
}
}
}
Zum Schluss müssen wir die Hauptfunktion implementieren, die den Server startet. Diese Funktion erstellt eine Instanz der Calculator-Struktur und stellt diese über Standard-Ein- und Ausgabe bereit.
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let service = Calculator::new().serve(stdio()).await?;
service.waiting().await?;
Ok(())
}
Der Server ist jetzt eingerichtet, um grundlegende Informationen über sich selbst bereitzustellen. Als Nächstes fügen wir ein Werkzeug zur Addition hinzu.
-5- Werkzeug und Ressource hinzufügen
Fügen Sie ein Werkzeug und eine Ressource hinzu, indem Sie den folgenden Code ergänzen:
TypeScript
server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
server.resource(
"greeting",
new ResourceTemplate("greeting://{name}", { list: undefined }),
async (uri, { name }) => ({
contents: [{
uri: uri.href,
text: `Hello, ${name}!`
}]
})
);
Ihr Werkzeug nimmt die Parameter a und b entgegen und führt eine Funktion aus, die eine Antwort in folgender Form erzeugt:
{
contents: [{
type: "text", content: "some content"
}]
}
Ihre Ressource wird über den String "greeting" aufgerufen, nimmt den Parameter name entgegen und erzeugt eine ähnliche Antwort wie das Werkzeug:
{
uri: "<href>",
text: "a text"
}
Python
# Fügen Sie ein Additionswerkzeug hinzu
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Fügen Sie eine dynamische Begrüßungsquelle hinzu
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
Im obigen Code haben wir:
- Ein Werkzeug
adddefiniert, das die Parameteraundb(beide Ganzzahlen) entgegennimmt. - Eine Ressource namens
greetingerstellt, die den Parameternameerhält.
.NET
Fügen Sie dies zu Ihrer Datei Program.cs hinzu:
[McpServerToolType]
public static class CalculatorTool
{
[McpServerTool, Description("Adds two numbers")]
public static string Add(int a, int b) => $"Sum {a + b}";
}
Java
Die Werkzeuge wurden bereits im vorherigen Schritt erstellt.
Rust
Fügen Sie im Block impl Calculator ein neues Werkzeug hinzu:
#[tool(description = "Adds a and b")]
async fn add(
&self,
Parameters(CalculatorRequest { a, b }): Parameters<CalculatorRequest>,
) -> String {
(a + b).to_string()
}
-6- Finale Code
Fügen wir den letzten Code hinzu, den wir benötigen, damit der Server starten kann:
TypeScript
// Beginne mit dem Empfang von Nachrichten auf stdin und sende Nachrichten auf stdout
const transport = new StdioServerTransport();
await server.connect(transport);
Hier ist der vollständige Code:
// index.ts
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
// Erstellen Sie einen MCP-Server
const server = new McpServer({
name: "Calculator MCP Server",
version: "1.0.0"
});
// Fügen Sie ein Additionswerkzeug hinzu
server.tool(
"add",
{ a: z.number(), b: z.number() },
async ({ a, b }) => ({
content: [{ type: "text", text: String(a + b) }]
})
);
// Fügen Sie eine dynamische Begrüßungsressource hinzu
server.resource(
"greeting",
new ResourceTemplate("greeting://{name}", { list: undefined }),
async (uri, { name }) => ({
contents: [{
uri: uri.href,
text: `Hello, ${name}!`
}]
})
);
// Beginnen Sie, Nachrichten auf stdin zu empfangen und Nachrichten auf stdout zu senden
const transport = new StdioServerTransport();
server.connect(transport);
Python
# server.py
from mcp.server.fastmcp import FastMCP
# Erstellen Sie einen MCP-Server
mcp = FastMCP("Demo")
# Fügen Sie ein Additionstool hinzu
@mcp.tool()
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
# Fügen Sie eine dynamische Begrüßungsressource hinzu
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
"""Get a personalized greeting"""
return f"Hello, {name}!"
# Hauptausführungsblock - dies ist erforderlich, um den Server zu starten
if __name__ == "__main__":
mcp.run()
.NET
Erstellen Sie eine Program.cs-Datei mit folgendem Inhalt:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using ModelContextProtocol.Server;
using System.ComponentModel;
var builder = Host.CreateApplicationBuilder(args);
builder.Logging.AddConsole(consoleLogOptions =>
{
// Configure all logs to go to stderr
consoleLogOptions.LogToStandardErrorThreshold = LogLevel.Trace;
});
builder.Services
.AddMcpServer()
.WithStdioServerTransport()
.WithToolsFromAssembly();
await builder.Build().RunAsync();
[McpServerToolType]
public static class CalculatorTool
{
[McpServerTool, Description("Adds two numbers")]
public static string Add(int a, int b) => $"Sum {a + b}";
}
Java
Ihre komplette Hauptanwendungsklasse sollte so aussehen:
// McpServerApplication.java
package com.microsoft.mcp.sample.server;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import com.microsoft.mcp.sample.server.service.CalculatorService;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider calculatorTools(CalculatorService calculator) {
return MethodToolCallbackProvider.builder().toolObjects(calculator).build();
}
}
Rust
Der finale Code für den Rust-Server sollte so aussehen:
use rmcp::{
ServerHandler, ServiceExt,
handler::server::{router::tool::ToolRouter, tool::Parameters},
model::{ServerCapabilities, ServerInfo},
schemars, tool, tool_handler, tool_router,
transport::stdio,
};
use std::error::Error;
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CalculatorRequest {
pub a: f64,
pub b: f64,
}
#[derive(Debug, Clone)]
pub struct Calculator {
tool_router: ToolRouter<Self>,
}
#[tool_router]
impl Calculator {
pub fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
#[tool(description = "Adds a and b")]
async fn add(
&self,
Parameters(CalculatorRequest { a, b }): Parameters<CalculatorRequest>,
) -> String {
(a + b).to_string()
}
}
#[tool_handler]
impl ServerHandler for Calculator {
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some("A simple calculator tool".into()),
capabilities: ServerCapabilities::builder().enable_tools().build(),
..Default::default()
}
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let service = Calculator::new().serve(stdio()).await?;
service.waiting().await?;
Ok(())
}
-7- Server testen
Starten Sie den Server mit folgendem Befehl:
TypeScript
npm run build
Python
mcp run server.py
Um den MCP Inspector zu verwenden, nutzen Sie
mcp dev server.py, welches automatisch den Inspector startet und das erforderliche Proxy-Sitzungstoken bereitstellt. Bei Verwendung vonmcp run server.pymüssen Sie den Inspector manuell starten und die Verbindung konfigurieren.
.NET
Stellen Sie sicher, dass Sie sich im Verzeichnis Ihres Projekts befinden:
cd McpCalculatorServer
dotnet run
Java
./mvnw clean install -DskipTests
java -jar target/calculator-server-0.0.1-SNAPSHOT.jar
Rust
Führen Sie die folgenden Befehle aus, um den Code zu formatieren und den Server zu starten:
cargo fmt
cargo run
-8- Nutzung mit dem Inspector
Der Inspector ist ein großartiges Werkzeug, das Ihren Server startet und Ihnen ermöglicht, mit ihm zu interagieren, damit Sie testen können, ob alles funktioniert. Starten wir ihn:
Note
Im Feld "Befehl" kann es anders aussehen, da dort der Befehl zum Ausführen eines Servers mit Ihrer spezifischen Laufzeitumgebung enthalten ist.
TypeScript
npx @modelcontextprotocol/inspector node build/index.js
Oder fügen Sie es in Ihre package.json so ein: "inspector": "npx @modelcontextprotocol/inspector node build/index.js" und führen Sie dann npm run inspector aus.
Python
Python nutzt ein Node.js-Werkzeug namens Inspector. Es ist möglich, dieses Werkzeug folgendermaßen aufzurufen:
mcp dev server.py
Allerdings implementiert es nicht alle Methoden, die das Werkzeug bietet, daher wird empfohlen, das Node.js-Werkzeug direkt wie unten auszuführen:
npx @modelcontextprotocol/inspector mcp run server.py
Wenn Sie ein Werkzeug oder eine IDE verwenden, die Kommandos und Argumente für das Ausführen von Skripten konfigurieren kann,
Stellen Sie sicher, dass Sie python im Feld Command und server.py als Arguments einstellen. Dadurch wird sichergestellt, dass das Skript korrekt ausgeführt wird.
.NET
Stellen Sie sicher, dass Sie sich im Verzeichnis Ihres Projekts befinden:
cd McpCalculatorServer
npx @modelcontextprotocol/inspector dotnet run
Java
Stellen Sie sicher, dass Ihr Rechner-Server läuft
Führen Sie dann den Inspector aus:
npx @modelcontextprotocol/inspector
Im Webinterface des Inspectors:
- Wählen Sie "SSE" als Transporttyp
- Setzen Sie die URL auf:
http://localhost:8080/sse - Klicken Sie auf "Connect"
Sie sind jetzt mit dem Server verbunden
Der Testabschnitt für den Java-Server ist nun abgeschlossen
Der nächste Abschnitt behandelt die Interaktion mit dem Server.
Sie sollten die folgende Benutzeroberfläche sehen:
-
Verbinden Sie sich mit dem Server, indem Sie auf die Schaltfläche Connect klicken
Sobald Sie mit dem Server verbunden sind, sollten Sie Folgendes sehen: -
Wählen Sie "Tools" und "listTools", Sie sollten "Add" sehen, wählen Sie "Add" und füllen Sie die Parameterwerte aus.
Sie sollten die folgende Antwort sehen, also ein Ergebnis vom Tool "add":
Herzlichen Glückwunsch, Sie haben es geschafft, Ihren ersten Server zu erstellen und auszuführen!
Rust
Um den Rust-Server mit dem MCP Inspector CLI auszuführen, verwenden Sie den folgenden Befehl:
npx @modelcontextprotocol/inspector cargo run --cli --method tools/call --tool-name add --tool-arg a=1 b=2
Offizielle SDKs
MCP stellt offizielle SDKs für mehrere Sprachen bereit:
- C# SDK - Wird in Zusammenarbeit mit Microsoft gepflegt
- Java SDK - Wird in Zusammenarbeit mit Spring AI gepflegt
- TypeScript SDK - Die offizielle TypeScript-Implementierung
- Python SDK - Die offizielle Python-Implementierung
- Kotlin SDK - Die offizielle Kotlin-Implementierung
- Swift SDK - Wird in Zusammenarbeit mit Loopwork AI gepflegt
- Rust SDK - Die offizielle Rust-Implementierung
Wichtigste Erkenntnisse
- Die Einrichtung einer MCP-Entwicklungsumgebung ist mit sprachspezifischen SDKs unkompliziert
- Der Aufbau von MCP-Servern beinhaltet das Erstellen und Registrieren von Tools mit klaren Schemata
- Testen und Debuggen sind für verlässliche MCP-Implementierungen unerlässlich
Beispiele
Aufgabe
Erstellen Sie einen einfachen MCP-Server mit einem Tool Ihrer Wahl:
- Implementieren Sie das Tool in Ihrer bevorzugten Sprache (.NET, Java, Python, TypeScript oder Rust).
- Definieren Sie Eingabeparameter und Rückgabewerte.
- Führen Sie das Inspector-Tool aus, um sicherzustellen, dass der Server wie beabsichtigt funktioniert.
- Testen Sie die Implementierung mit verschiedenen Eingaben.
Lösung
Zusätzliche Ressourcen
- Erstellen von Agents mit Model Context Protocol auf Azure
- Remote MCP mit Azure Container Apps (Node.js/TypeScript/JavaScript)
- .NET OpenAI MCP Agent
Was kommt als Nächstes
Weiter: Erste Schritte mit MCP Clients
Haftungsausschluss:
Dieses Dokument wurde mit dem KI-Übersetzungsdienst Co-op Translator übersetzt. Obwohl wir auf Genauigkeit achten, beachten Sie bitte, dass automatische Übersetzungen Fehler oder Ungenauigkeiten enthalten können. Das Originaldokument in seiner Originalsprache sollte als maßgebliche Quelle betrachtet werden. Für wichtige Informationen wird eine professionelle menschliche Übersetzung empfohlen. Wir übernehmen keine Haftung für Missverständnisse oder Fehlinterpretationen, die aus der Nutzung dieser Übersetzung entstehen.



