[!NOTE] Automatische Übersetzung Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.
MCP Server-Tutorial mit uv und FastMCP: Erstellung eines FeatureStoreLite-Servers
Dieses Tutorial zum MCP-Server erstellt einen kleinen Feature-Store-Server mithilfe von FastMCP, startet ihn mit uv und integriert ihn in Claude Desktop.
TL;DR: Ein kleiner FastMCP-Server reicht aus, um ein nützliches lokales Tool für einen Agent bereitzustellen. Verwenden Sie uv für eine wiederholbare Einrichtung, halten Sie die Grenzen des Servers eng, überprüfen Sie die Eingaben mithilfe typisierter Schemata und testen Sie das MCP-Tool vor dem Anschluss an einen Model.
Was ist ein MCP-Server?
Das Model Context Protocol (MCP) ist ein offener Standard zur Verbindung von AI Assistenten mit externen Datenquellen und Tools. Er ersetzt eine individuelle, maßgeschneiderte Integration für jedes Tool durch ein einheitliches Konventionswerkzeug.
In diesem Tutorial werden wir einen Server von FeatureStoreLite MCP erstellen. Er befindet sich zwischen einem LLM und einem Feature-Store – also einer Datenbank mit vorberechneten ML Features – und stellt Werkzeuge zur Abfrage sowie zum Schreiben von Feature-Vektoren bereit, die nach Benutzer, Produkt oder Dokument geordnet sind.
Warum wird das gebaut?
Sie sind ein ML-Entwickler, der einen Pipeline debuggt. Anstatt direkt in SQL einzudringen oder einen schnellen Script zu schreiben, um die Werte der Features zu überprüfen, fragen Sie Claude direkt: „Wie sieht der Feature-Vektor für user_123 aus?“ oder „Zeigen Sie mir die Metadaten für product_abc.“ Der MCP-Server macht das möglich.
Warum verwenden uv?
Wir werden es verwenden. UV um Pakete zu installieren, Abhängigkeiten zu lösen und die virtuelle Umgebung zu verwalten. Später, uv run --with mcp[cli] ... Es ermöglicht zudem, dass die Konfiguration von Claude Desktop ihre Abhängigkeit direkt deklariert. Dadurch entfällt eine separate Umgebung, die aus dem Gleichgewicht geraten könnte.
Übersicht zur Architektur
Die vier Komponenten und ihre gegenseitige Verknüpfung:
- Der Benutzer stellt eine Frage in natürlicher Sprache.
- Claude Desktop ist der MCP-Client. Er wählt auf Basis der Frage ein passendes Tool aus und ruft dieses auf.
- Unsere
FastMCPder Server stellt bereitget_featureundstore_featureals MCP-Tools. - SQLite dient als zugrundeliegende Datenbank für die Feature-Vektoren.
2. Einrichtung und Installation
2.1. Installation uv
Wenn Sie noch keinen solchen Agenten besitzen uvInstallieren Sie es. Der Rest des Tutorials geht davon aus, dass es auf Ihrem System vorhanden ist. PATH.
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or via Homebrew
brew install uv
2.2. Projekt initialisieren
Erstellen Sie einen neuen Verzeichnis und initialisieren Sie ein Python-Projekt. uv init erstellt einen pyproject.toml für Sie.
# Create project directory
mkdir mcp-featurestore
cd mcp-featurestore
# Initialize Python project
uv init
# Add the MCP SDK with CLI tools
uv add "mcp[cli]"
3. Aufbau des Servers
Zwei Dateien, nach Aufgabenbereich getrennt:
database.pyverarbeitet SQLite-Operationen.featurestore_server.pydefiniert den MCP-Server.
3.1. Die Datenbankschicht (database.py)
Dieses Modul verwaltet die SQLite-Verbindung sowie einige Hilfsfunktionen. Es wird mit zwei Beispieldatenzeilen initialisiert, damit der Server bei der ersten Abfrage etwas zurückgeben kann.
erstellen database.py:
# database.py
import json
import os
import sqlite3
def get_db_path() -> str:
"""Get the database path - always in the script's directory"""
script_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(script_dir, "features.db")
def init_db() -> None:
"""Initialize the feature store database with table and sample data"""
conn = sqlite3.connect(get_db_path())
conn.execute("""
CREATE TABLE IF NOT EXISTS features (
key TEXT PRIMARY KEY,
vector TEXT NOT NULL,
metadata TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
# Sample data for experimentation
example_features = [
(
"user_123",
"[0.1, 0.2, -0.5, 0.8, 0.3, -0.1, 0.9, -0.4]",
json.dumps({"type": "user", "id": 123, "segment": "premium"}),
),
(
"product_abc",
"[0.7, -0.3, 0.4, 0.1, -0.8, 0.6, 0.2, -0.5]",
json.dumps({"type": "product", "id": "abc", "category": "electronics"}),
),
]
# Insert if not exists
for key, vector, metadata in example_features:
try:
conn.execute(
"INSERT INTO features (key, vector, metadata) VALUES (?, ?, ?)",
(key, vector, metadata),
)
except sqlite3.IntegrityError:
pass # Already exists
conn.commit()
conn.close()
def get_db_connection() -> sqlite3.Connection:
"""Get a database connection"""
return sqlite3.connect(get_db_path())
if __name__ == "__main__":
init_db()
print("✅ Database initialized successfully!")
Datenbank initialisieren:
uv run python database.py
3.2. Der MCP-Server (featurestore_server.py)
FastMCP erledigt den größten Teil der Arbeit. Wenn man eine einfache Python-Funktion annotiert, wird sie als MCP-Tool oder -Ressource registriert. Die Dokumentation dient dabei als Beschreibung, die vom LLM abgerufen wird; daher sollte sie für LLM verfasst werden und nicht nur für Menschen.
erstellen featurestore_server.py:
# featurestore_server.py
import json
from mcp.server.fastmcp import FastMCP
from database import get_db_connection, init_db
# Initialize the MCP Server
mcp = FastMCP("FeatureStoreLite")
# Ensure DB is ready when server starts
init_db()
@mcp.resource("schema://main")
def get_schema() -> str:
"""
Resource: Provide the database schema.
Resources are passive data that LLMs can read like files.
"""
conn = get_db_connection()
try:
schema = conn.execute(
"SELECT sql FROM sqlite_master WHERE type='table'"
).fetchall()
return "\n".join(sql[0] for sql in schema if sql[0]) or "No tables found."
finally:
conn.close()
@mcp.tool()
def store_feature(key: str, vector: str, metadata: str | None = None) -> str:
"""
Tool: Store a feature vector.
Tools are executable functions that LLMs can call to perform actions.
"""
conn = get_db_connection()
try:
# Validate that vector is valid JSON
json.loads(vector)
conn.execute(
"INSERT OR REPLACE INTO features (key, vector, metadata) VALUES (?, ?, ?)",
(key, vector, metadata),
)
conn.commit()
return f"Successfully stored feature '{key}'"
except json.JSONDecodeError:
return "Error: Vector must be a valid JSON array string (e.g., '[0.1, 0.2]')"
except Exception as e:
return f"Error: {str(e)}"
finally:
conn.close()
@mcp.tool()
def get_feature(key: str) -> str:
"""
Tool: Retrieve a feature vector by key.
"""
conn = get_db_connection()
try:
row = conn.execute(
"SELECT vector, metadata FROM features WHERE key = ?", (key,)
).fetchone()
if row:
return json.dumps(
{
"key": key,
"vector": json.loads(row[0]),
"metadata": json.loads(row[1]) if row[1] else None,
},
indent=2,
)
return f"Feature '{key}' not found."
finally:
conn.close()
@mcp.tool()
def list_features() -> str:
"""
Tool: List all available feature keys.
"""
conn = get_db_connection()
try:
rows = conn.execute("SELECT key FROM features").fetchall()
return json.dumps([row[0] for row in rows])
finally:
conn.close()
if __name__ == "__main__":
mcp.run()
4. Testing mit dem MCP Inspector
Bevor Sie dies in Claude anschließen, überprüfen Sie den Server mit dem MCP Inspector auf Funktionalität. Es handelt sich dabei um eine kleine Web-Oberfläche, über die Tools aufgerufen sowie Ressourcen direkt abgerufen werden können.
uv run mcp dev featurestore_server.py
Der Befehl startet den Server und öffnet den Inspector in Ihrem Browser (in der Regel unter http://localhost:5173).
{width=“600”}
aufrufen get_feature mit key="user_123". Wenn für die Seed-Zeile der JSON zurückgegeben wird, funktioniert der Server einwandfrei.
5. Anbindung an Claude Desktop
Sobald der Inspektor bestätigt hat, dass der Server funktioniert, registrieren Sie ihn in Claude Desktop.
5.1. Claude konfigurieren
Bearbeiten Sie die Konfigurationsdatei von Claude Desktop:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%/Claude/claude_desktop_config.json
Fügen Sie Ihren Server hinzu zu mcpServers Objekt:
{
"mcpServers": {
"featurestore": {
"command": "uv",
"args": [
"run",
"--with",
"mcp[cli]",
"mcp",
"run",
"/ABSOLUTE/PATH/TO/mcp-featurestore/featurestore_server.py"
]
}
}
}
Wichtig: Der Pfad zu
featurestore_server.pyEs muss ein absoluter Pfad sein. Ein relativer Pfad führt zu einem stillen Fehler, da Claude Desktop aus einem anderen Arbeitsverzeichnis ausgeführt wird.
5.2. Wie die Interaktion funktioniert
Hier ist der Ablauf vom Anfang bis zum Ende, wenn Claude nach einer Funktionsbeschreibung suchen muss:
- Claude erkennt die verfügbaren Tools.
get_feature,list_features, und so weiter). - Es entscheidet, dass für die Beantwortung der Frage Daten aus dem Feature Store benötigt werden.
- Es erstellt einen Tool Call und sendet diesen an Ihren Server.
- Der Server führt die Python-Funktion aus und gibt das Ergebnis zurück.
- Claude verwendet dieses Ergebnis, um die endgültige Antwort zu formulieren.
5.3. Beispielfragen
Starten Sie Claude Desktop erneut und testen Sie einige Prompts:
-
„Listen Sie alle verfügbaren Funktionen auf.“
{width=“600”} -
„Erstellen Sie den Eigenschaftsvektor für user_123.“
{width=“600”} -
„Speichern Sie eine neue Eigenschaft für ‚new_item‘ mit dem Vektor [0.5, 0.5] sowie den Metadaten {‘type’: ‘test’}.“
6. Fehlerbehebung
Einige Ausfallmuster, die man kennen sollte:
-
„Verbindung zum Server fehlgeschlagen“:
- Überprüfen Sie die Protokolle unter
~/Library/Logs/Claude/mcp.logauf macOS. - Stellen Sie sicher, dass die Konfiguration einen absoluten Pfad verwendet und nicht einen relativen.
- Stellen Sie fest
uvin der Claude Desktop-Version enthaltenPATH. Falls dem nicht so ist, geben Sie den vollständigen Binärpfad an.which uv>wird Ihnen mitteilen, wo es sich befindet.)
- Überprüfen Sie die Protokolle unter
-
„Fehler bei der Ausführung des Tools“:
- Replizieren Sie ihn im Inspektor mit
uv run mcp dev featurestore_server.pyDer Inspektor zeigt den rohen Fehler an, den Claude Desktop in der Regel verschluckt. – Überprüfen Sie, obfeatures.dbwird nebenan erstelltdatabase.py. Wenn sich Ihr Arbeitsverzeichnis verschiebt, ändert sich der relativ zum Skript angegebene Pfad.get_db_path()Das ist es, was Sie rettet.
- Replizieren Sie ihn im Inspektor mit
7. Fazit
Das ist es also: ein FastMCP ein Server, ein SQLite-Backend-Speicher sowie eine Claude Desktop-Konfiguration, die auf einen … verweist uv run Befehl. Die gleiche Struktur gilt für alles, was in eine Python-Funktion eingebettet werden kann. Ersetzen Sie die SQLite-Aufrufe durch einen echten Feature-Store, ein internes API oder ein Model-Registry – dadurch bleibt der Server weiterhin kompakt.
Wichtige Erkenntnisse
- MCP stellt eine Abgrenzung zwischen Tools dar und nicht einen Grund, jede interne Funktion offenzulegen.
- Halten Sie Server-Tools klein, typisiert und leicht testbar – ohne die Verwendung eines LLM.
- Nutzen Sie uv, damit die Tutorial-Umgebung von Grund auf neu erstellt werden kann.
- Behandeln Sie den MCP-Server als Produktionscode, sobald ein Agent darauf zugreifen kann.