So erstellen Sie Ihren ersten MCP-Server mit Novita AI

Erstellen Sie Ihren ersten MCP-Server

Das Model Context Protocol (MCP) entwickelt sich schnell zu einem der meistdiskutierten Konzepte in der Welt der KI. Obwohl es relativ neu ist, hat es bereits die Aufmerksamkeit von Entwicklern und großen Technologieunternehmen gleichermaßen auf sich gezogen. 

MCP wurde von Anthropic entwickelt und ist ein offenes Standardprotokoll, ähnlich wie andere Protokolle wie HTTP. Während HTTP jedoch dazu dient, Benutzer über einen Server und einen Webbrowser (oder HTTP-Client) mit Ressourcen zu verbinden, ist MCP für die Verbindung großer Sprachmodelle (LLMs) auf externe Tools und Daten.

Angenommen, Sie haben einen Chatbot und möchten, dass dieser auf GitHub zugreifen kann. Ihre Benutzer sollen den Chatbot nutzen, um Probleme zu erstellen, Probleme zu schließen, Kommentare hinzuzufügen oder bestehende Pull Requests anzuzeigen. Damit Ihr Chatbot all diese Aktionen ausführen kann, benötigt er Zugriff auf Tools.

Hier kommt ein MCP-Server ins Spiel. 

Der MCP-Server hostet mehrere Tools, die der Chatbot über seine internen LLM um Zugriff auf diese Funktionen zu erhalten. Im Fall von GitHub können wir den offiziellen GitHub MCP-Server verwenden, um alle oben genannten Aufgaben auszuführen. 

In diesem Artikel erstellen wir ein MCP-Server mit dem Novita API. Mit diesem MCP-Server kann jede Anwendung, die das MCP-Protokoll unterstützt, auf alle LLMs auf Novita verfügbar, generieren Sie Bilder, erstellen Sie Videos und führen Sie Sprachsynthese durch.

Die MCP-Architektur verstehen

Die MCP-Architektur
Die MCP-Architektur [Quelle]

Die MCP-Architektur ähnelt einem typischen Client-Server-Setup. Sie besteht aus vier wichtigen Komponenten:

  • MCP-Client
  • MCP-Server
  • MCP-Transporte
  • MCP-Host

MCP-Client

Der MCP-Client dient als Kommunikationsgateway zwischen der KI-Anwendung und einem MCP-Server. Sobald die Kommunikation hergestellt ist, kann die Anwendung auf alle Tools und Ressourcen des Servers zugreifen.

MCP-Server

Der MCP-Server hostet alle Tools und Daten, die der Client der KI-Anwendung bereitstellen kann. Er hostet Folgendes:

  • Zubehör
  • Ressourcen 
  • Eingabeaufforderungen

Zubehör

Tools bieten externe Funktionen für LLMFunktionen, die sie normalerweise nicht hätten, wie etwa die Möglichkeit, die Uhrzeit anzuzeigen, eine Datenbank zu aktualisieren und zu lesen, das Wetter abzurufen usw. Bei diesen Tools handelt es sich im Wesentlichen um vom Programmierer definierte Funktionen, die aufgerufen werden können.

Ein MCP-Server kann mehrere Tools hosten. Diese Tools ermöglichen die LLM aufgrund der Aktionen, die es ausführen kann, als Agent zu fungieren.

Die Tools werden vom Agenten verwaltet und können während der Nutzung optional menschliche Überwachung erfordern. Sie ähneln POST-Anfragen im HTTP-Protokoll, da sie Nebeneffekte ausführen.

Ressourcen

Ressourcen sind schreibgeschützte Informationen, die der KI-Anwendung Daten bereitstellen. Sie entsprechen HTTP-GET-Anfragen, da sie keine Nebenwirkungen verursachen sollen. Ressourcen werden von der Anwendung verwaltet, die entscheidet, wie Benutzer oder Agenten mit ihnen interagieren. Beispiele für Ressourcen sind Dateiinhalte, API-Antworten und Datensätze aus Datenbanken.

Eingabeaufforderungen

MCP-Server können Eingabeaufforderungsvorlagen hosten. Diese Eingabeaufforderungen ermöglichen es dem Benutzer, Eingabeaufforderungen vom MCP-Server abzurufen, die dann in der KI-Anwendung verwendet werden können. Die Eingabeaufforderungen werden vom Benutzer verwaltet, der entscheidet, welche Eingabeaufforderungen dem Agenten bereitgestellt werden.

All diese Komponenten bilden den MCP-Server. In diesem Artikel werden wir nur Tools implementieren, da diese der am häufigsten verwendete Teil des MCP-Servers sind.

MCP-Transport

MCP-Transport bezeichnet die Methode, mit der der MCP-Client mit dem MCP-Server kommuniziert. Diese Kommunikation kann lokal erfolgen, wenn Client und Server auf demselben Rechner laufen, oder remote, wenn sie sich auf getrennten Geräten befinden. MCP unterstützt derzeit zwei Haupttransportmechanismen:

  • STADION: In diesem Modus laufen der MCP-Server und der Client auf derselben Maschine und kommunizieren über Standard-Eingabe und -Ausgabe.
  • SSE: In diesem Modus läuft der MCP-Server über HTTP. HTTP POST wird verwendet, um Nachrichten an den Server zu senden, während Server-Sent Events verwendet werden, um Nachrichten vom Server an den Client zu senden.
  • Streambares HTTP: Dieser Modus verwendet ebenfalls HTTP, basiert jedoch auf HTTP-GET- und POST-Anfragen. Nur wenn mehrere Nachrichten vom Server an den Client gestreamt werden müssen, wird auf SSE zurückgegriffen.

Standard-Eingabe/Ausgabe

Transport mit STDIO
MCP-Transport mit STDIO [Quelle]

Beschriftung: MCP-Transport mit STDIO [Quelle]

MCP-Client und -Server kommunizieren über Standard Input and Output (STDIO). Bei Verwendung von STDIO laufen Client und Server auf demselben Rechner. Der Client schreibt alle Anfragen auf stdin, während der Server die Antwort auf stdout schreibt.

Streambares HTTP

MCP-Transport mit streambarem HTTP
MCP-Transport mit streambarem HTTP [Quelle]

Streamable HTTP ermöglicht MCP-Client und -Server die Kommunikation über HTTP. Es verwendet die HTTP-POST-Methode, um Anfragen vom Client zu senden und Antworten vom Server zu empfangen. Bei Bedarf kann optional auf Server-Sent Events (SSE) umgeschaltet werden, um Nachrichten vom Server an den Client zu streamen.

Streamable HTTP eignet sich gut für die Remote-Kommunikation zwischen Client und Server und dient als Ersatz für den veralteten MCP SSE-Transport.

MCP-Host

MCP unterscheidet sich von einer typischen Client-Server-Architektur in der Rolle des Hosts. Die MCP-Spezifikation definiert es als Client-Host-Server-Architektur. Dies liegt daran, dass Client und Host das Frontend der Architektur bilden. Der MCP-Host besteht aus zwei wichtigen Komponenten:

  • Der/Die MCP-Client(s)
  • Ein großes Sprachmodell

Die Aufgabe des MCP-Clients besteht darin, Werkzeuge, Ressourcen und Eingabeaufforderungen abzurufen, die der LLM vom Server benötigt. Sobald die Ressourcen erfasst wurden, werden sie in den Kontext des Modells eingefügt. Ein einzelner MCP-Host kann mehrere Clients haben, die jeweils mit einem eigenen MCP-Server verbunden sind.

Der MCP-Host kann auch als die Anwendung betrachtet werden, mit der der Benutzer arbeitet und die möglicherweise andere Funktionen erfüllt. Beispielsweise ist Claude Desktop ein MCP-Host, der als Chatbot fungiert, Cursor ist ein MCP-Host, der auch als IDE dient, und Claude Code ist ein MCP-Host, der als KI-Codierungsagent konzipiert ist.

Arbeiten mit einem MCP-Server

Bevor wir mit dem Aufbau unseres MCP-Servers beginnen, sehen wir uns an, wie wir mit einem vorhandenen MCP-Server arbeiten können. Wir verwenden die Python MCP SDK mit dem interagieren Novita-MCP-Server.

Zum Zeitpunkt der Erstellung dieses Artikels stellt der Novita-MCP-Server die folgenden Tools bereit:

  • Ein Tool zum Auflisten aller Novita-Cluster
  • Ein Tool zum Auflisten der Novita GPU Instanzprodukte
  • Ein Tool zum Auflisten aller laufenden GPU Instanzen
  • Ein Werkzeug zum Erstellen neuer GPU Instanzen

Bestätigen wir dies, indem wir ein einfaches Skript schreiben, das über STDIO eine Verbindung zum MCP-Server herstellt und alle auf dem Server verfügbaren Tools auflistet.

Installieren wir zunächst das MCP SDK: pip install „mcp[cli]“

Nachdem wir das SDK installiert haben, können wir eine Datei namens client.py erstellen. Anschließend führen wir alle notwendigen Importe durch:

von mcp importiere ClientSession, StdioServerParameters von mcp.client.stdio importiere stdio_client importiere os

Anschließend verwenden wir die StdioServerParameters, um die Parameter für den Start unseres MCP-Servers über stdio festzulegen. Der Novita-MCP-Server ist in Node.js implementiert. Um ihn zu verwenden, müssen wir ihn mit dem Befehl npx ausführen. Außerdem müssen wir unseren Novita-API-Schlüssel in der Umgebungsvariable NOVITA_API_KEY speichern.

# Serverparameter für die Stdio-Verbindung erstellen server_params = StdioServerParameters( command="npx", args=["-y", "@novitalabs/novita-mcp-server"], env={"NOVITA_API_KEY": os.environ["NOVITA_API_KEY"]}, )

Als Nächstes erstellen wir eine asynchrone Funktion. Innerhalb der Funktion übergeben wir die Serverparameter an die Funktion stdio_client. Diese erstellt einen Kontext, der Lese- und Schreibströme zurückgibt. Diese Ströme ermöglichen das Lesen von bzw. Schreiben in stdio.

async def run(): async mit stdio_client(server_params) als (Lesen, Schreiben): async mit ClientSession(Lesen, Schreiben) als Sitzung: # Verbindung initialisieren await session.initialize() # Verfügbare Tools auflisten tools = await session.list_tools() print("Verfügbare Tools:", tools)

Diese Streams werden dann verwendet, um eine Sitzung mit der Klasse ClientSession zu erstellen. Sobald wir unsere Sitzung erstellt haben, können wir sie initialisieren und anschließend alle Tools auf dem Server auflisten.

Um dieses Programm auszuführen, müssen wir lediglich die Run-Funktion der asyncio-Bibliothek aufrufen. Hier ist der vollständige Code:

von mcp importiere ClientSession, StdioServerParameters von mcp.client.stdio importiere stdio_client importiere os # Serverparameter für Stdio-Verbindung erstellen server_params = StdioServerParameters( command="npx", args=["-y", "@novitalabs/novita-mcp-server"], env={"NOVITA_API_KEY": os.environ["NOVITA_API_KEY"]}, ) async def run(): async mit stdio_client(server_params) als (Lesen, Schreiben): async mit ClientSession(Lesen, Schreiben) als Sitzung: # Verbindung initialisieren await session.initialize() # Verfügbare Tools auflisten tools = await session.list_tools() print("Verfügbare Tools:", Tools) if __name__ == "__main__": importiere asyncio asyncio.run(run())

Durch Ausführen des Skripts können wir alle Tools auf dem Novita MCP-Server sehen.

Dieses Beispiel zeigt, wie Sie den MCP-Client verwenden können. Wir könnten hinzufügen: LLM zu diesem Beispiel und wandeln es effektiv in einen Host um, aber das ist nicht der Schwerpunkt dieses Tutorials. Der Fokus liegt auf dem Aufbau eines MCP-Servers.

Erstellen eines MCP-Servers mit FastMCP

Im Python MCP SDK gibt es zwei Möglichkeiten, MCP-Server zu erstellen. Eine Methode ist die Verwendung des Low-Level-Servers, die andere die Verwendung von FastMCP. FastMCP ist eine Klasse im MCP Python SDK, die von FastAPI inspiriert ist, um die Erstellung von MCP-Servern zu vereinfachen.

Wir verwenden FastMCP, um unseren MCP-Server zu erstellen. Bevor wir beginnen, betrachten wir die Funktionalitäten unseres MCP-Servers. Der aktuelle Novita MCP-Server implementiert nur Tools, die GPU Management. Versuchen wir, einen Server rund um die Novita API zu bauen, der über GPU Management.

Stattdessen erstellen wir einen MCP-Server, der Zugriff auf die Modelle der Novita-Plattform bietet. Unser MCP-Server verfügt lediglich über Tools, ohne Ressourcen oder Eingabeaufforderungen. Hier ist eine Liste der Tools, die der Server bereitstellen wird:

  • Liste_Modelle: Dieses Tool listet alle großen Sprachmodelle auf der Novita-Plattform auf.
  • Modell abrufen: Dieses Tool ruft ein bestimmtes großes Sprachmodell ab und verwendet es.
  • text2image: Dieses Tool generiert Bilder aus einer gegebenen Eingabeaufforderung.
  • Aufgabenergebnis: Dieses Tool wird verwendet, um den Status einer laufenden Aufgabe über ihre ID abzurufen.
  • Text-zu-Sprache: Dieses Tool wandelt den bereitgestellten Text in Sprache um.
  • Video generieren: Dieses Tool generiert aus einer gegebenen Eingabeaufforderung ein Video.

Nachdem wir nun die Tools kennen, die wir erstellen werden, können wir mit der Erstellung unseres Servers beginnen. Erstellen Sie zunächst eine Datei namens server.py und fügen Sie den folgenden Code hinzu:

importiere os, importiere sys von mcp.server.fastmcp, importiere FastMCP, importiere Anfragen, importiere uvicorn von starlette.applications, importiere Starlette von starlette.routing, importiere Mount base_url = "https://api.novita.ai/v3" Header = { "Inhaltstyp": "Anwendung/json", "Autorisierung": f"Träger {os.environ['NOVITA_API_KEY']}" } mcp = FastMCP("Novita_API")

Damit haben wir die notwendigen Module importiert, unsere Basis-URL und Header für die API definiert und eine Instanz der FastMCP-Klasse erstellt. Fahren wir mit der Erstellung unserer Tools fort.

Modelle auflisten

Um ein Tool in FastMCP zu erstellen, müssen wir eine Funktion mit der Tool-Methode der FastMCP-Instanz dekorieren. Die Funktion list_models ruft die Endpunkt für Listenmodelle um die Liste der Modelle zu erhalten. Die Antwort wird dann richtig formatiert, sodass sie an den LLM das hat es genannt.

@mcp.tool() def list_models() -> str: """ Listet alle verfügbaren Modelle aus der Novita-API auf. """ url = base_url + "/openai/models" response = requests.request("GET", url, headers=headers) data = response.json()["data"] text = "" für i, Modell in Aufzählung (Daten, Start=1): Text += f"Modell-ID: {model['id']}\n" Text += f"Modellbeschreibung: {model['description']}\n" Text += f"Modelltyp: {model['model_type']}\n\n" Text zurückgeben

Der Docstring im Tool dient dazu, die Funktionalität des Tools zu beschreiben, sodass die LLM verstehen kann, wofür das Werkzeug verwendet wird.

Modelle abrufen

Dieses Tool dient zum Zugriff auf die bereitgestellten LLMs auf Novita. Es nimmt die Modell-ID und die Eingabeaufforderung für das Modell entgegen. Es verwendet die Novita Chat-Abschluss-API-Endpunkt.

@mcp.tool() def get_model(model_id: str, message): """ Geben Sie eine Modell-ID und eine Nachricht an, um eine Antwort von der Novita-API zu erhalten. """ url = base_url + "/openai/chat/completions" payload = { "model": model_id, "messages": [ { "content": message, "role": "user", } ], "max_tokens": 200, "response_format": { "type": "text", }, } response = requests.request("POST", url, json=payload, headers=headers) content = response.json()["choices"][0]["message"]["content"] return content

Text2Image

Dieses Tool generiert Bilder aus einer Eingabeaufforderung. Es verwendet die Novita Text-zu-Bild-Endpunkt unter der Haube. Dieser Endpunkt ist asynchron, gibt also das Bild nicht sofort zurück, sondern eine Task-ID.

@mcp.tool() def text2Image(prompt): """ Erstellen Sie mithilfe der Novita-API ein Bild aus einer Textaufforderung. """ url = base_url + "/async/txt2img" payload = { "request": { "model_name": "sd_xl_base_1.0.safetensors", "prompt": prompt, "width": 1024, "height": 1024, "image_num": 1, "steps": 20, "clip_skip": 1, "sampler_name": "Euler a", "guidance_scale": 7.5, }, "extra": { "response_image_type": "jpeg" } } response = requests.request("POST", url, json=payload, headers=headers) return response.json()["task_id"]

Aufgabenergebnis

Dieses Tool dient dazu, den Status einer laufenden Aufgabe in der Novita-API abzurufen. Es erfasst nur die Aufgaben-ID. Beispielsweise generiert das Image-Tool asynchron ein Bild und gibt eine Aufgaben-ID an den Host zurück. Der Benutzer kann den Host dann bitten, das Ergebnis dieser Aufgabe mithilfe des Task-Ergebnis-Tools abzurufen.

@mcp.tool() def task_result(task_id: str): """ Ruft den aktuellen Status einer laufenden Aufgabe mithilfe ihrer Aufgaben-ID ab """ url = base_url + f'/async/task-result?task_id={task_id}' response = requests.request("GET", url, headers=headers) return response.json()

Video generieren

Dieses Tool generiert Videos mithilfe der Novita API's Kling AI V1.6 Text-zu-Video-Endpunkt. Genau wie das Image-Tool generiert es asynchron Videos und gibt eine Task-ID zurück.

@mcp.tool() def generateVideo(prompt: str): """ Erzeugen Sie ein Bild mit einer Eingabeaufforderung """ url = base_url + "/async/kling-v1.6-t2v" payload = { "mode": "Standard", "prompt": prompt, "negative_prompt": "niedrige Qualität", "guidance_scale": 0.6 } response = requests.post(url, json=payload, headers=headers) return response.json()

Text zu Sprache

Dieses Tool generiert Sprache mithilfe der Novita-API Text-to-Speech-Endpunkt. Da es sich auch um einen asynchronen Endpunkt handelt, gibt es auch eine Task-ID zurück.

@mcp.tool() def textToSpeech(text, voice_id) -> str: """ Sprache mithilfe von Text und Sprach-ID generieren. Es wird die Task-ID der generierten Sprache zurückgegeben. Die verfügbaren Sprach-IDs sind: - Emily - James - Olivia - Michael - Sarah - John """ url = base_url + "/async/txt2speech" payload = { "request": { "voice_id": voice_id, "language": "en-US", "texts": [text] } } response = requests.post(url, json=payload, headers=headers) return response.json()["task_id"]

Nachdem alle Tools definiert sind, können wir unseren Transportmechanismus einrichten. Wir verwenden stdio.

if __name__ == "__main__": # Ausführen mit stdio-Transport mcp.run(transport="stdio")

Wir können jetzt den gesamten Code zusammenfügen:

novita.ai/v3" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}" } mcp = FastMCP("Novita_API") @mcp.tool() def list_models() -> str: """ Listet alle verfügbaren Modelle der Novita-API auf.
   """ url = base_url + "/openai/models" response = requests.request("GET", url, headers=headers) data = response.json()["data"] text = "" for i, model in enumerate(data, start=1): text += f"Model id: {model['id']}\n" text += f"Model description: {model['description']}\n" text += f"Model type: {model['model_type']}\n\n" return text @mcp.tool() def get_model(model_id: str, message) -> str: """ Geben Sie eine Modell-ID und eine Nachricht an, um eine Antwort von der Novita-API zu erhalten.
   """ url = base_url + "/openai/chat/completions" payload = { "model": model_id, "messages": [ { "content": message, "role": "user", } ], "max_tokens": 200, "response_format": { "type": "text", }, } response = requests.request("POST", url, json=payload, headers=headers) content = response.json()["choices"][0]["message"]["content"] return content @mcp.tool() def text2Image(prompt: str) -> str: """ Generieren Sie mithilfe der Novita-API ein Bild aus einer Textaufforderung.
   """ url = base_url + "/async/txt2img" payload = { "request": { "model_name": "sd_xl_base_1.0.safetensors", "prompt": prompt, "width": 1024, "height": 1024, "image_num": 1, "steps": 20, "clip_skip": 1, "sampler_name": "Euler a", "guidance_scale": 7.5, }, "extra": { "response_image_type": "jpeg" } } response = requests.request("POST", url, json=payload, headers=headers) return response.json()["task_id"] @mcp.tool() def task_result(task_id: str) -> str: """ Aktuellen Status einer laufenden Task über die Task-ID abrufen """ url = base_url + f'/async/task-result?task_id={task_id}' response = requests.request("GET", url, headers=headers) return response.json() @mcp.tool() def generateVideo(prompt: str) -> str: """ Ein Bild mithilfe einer Eingabeaufforderung generieren """ url = base_url + "/async/kling-v1.6-t2v" payload = { "mode": "Standard", "prompt": prompt, "negative_prompt": "low quality", "guidance_scale": 0.6 } response = requests.post(url, json=payload, headers=headers) return response.json()["task_id"] @mcp.tool() def textToSpeech(text, voice_id) -> str: """ Sprache mithilfe von Text und Sprach-ID generieren.
   Es gibt die Task-ID der generierten Sprache zurück.
  
   Die verfügbaren Sprach-IDs sind: - Emily - James - Olivia - Michael - Sarah - John """ url = base_url + "/async/txt2speech" payload = { "request": { "voice_id": voice_id, "language": "en-US", "texts": [text] } } response = requests.post(url, json=payload, headers=headers) return response.json()["task_id"] if __name__ == "__main__": # Run using stdio transport mcp.run(transport="stdio")

Wir können unseren MCP-Server auf jedem MCP-Host wie Claude Desktop, Cursor oder VS Code mit dem folgenden Setup testen:

{ "Befehl": "Python", "Argumente": [ "Pfad/zum/Server.py" ], "Umgebung": { "NOVITA_API_KEY": "sk_..." } }

Wir können auch das zuvor entwickelte Client-Skript verwenden, um unseren Server zu testen.

Verwenden des MCP Low-Level-Servers

Der Server, den wir im vorherigen Abschnitt erstellt haben, verwendet die FastMCP-Klasse, die eine High-Level-Schnittstelle zum Erstellen von MCP-Servern bietet. Sie können MCP-Server auch mit dem Low-Level-Server erstellen, der Ihnen detaillierte Kontrolle über das MCP-Protokoll gibt. Sehen wir uns an, wie wir den Server aus dem vorherigen Abschnitt anpassen können, um den Low-Level-Server zu verwenden.

Werkzeugverwaltung

FastMCP verwaltet unter anderem die von Ihnen definierten Tools. Wenn Sie eine Funktion mit dem Tool-Dekorator der FastMCP-Klasse dekorieren, fügt FastMCP das Tool einer Liste hinzu. Wenn der Agent das Tool anfordert, ruft FastMCP es ab, ruft es auf und sendet das Ergebnis an den Agenten zurück.

Mit dem Low-Level-Server können wir diesen Prozess mithilfe des Call_tool-Decorators selbst verwalten.

@app.call_tool() async def manage_tool(name: str, arguments: dict ) -> list[types.TextContent]: wenn name == "list_models": return warte auf list_models_tool() wenn name == "get_model": return warte auf get_model_tool(arguments) sonst: raise ValueError(f"Unbekanntes Tool: {name}")

Der obige Code zeigt eine Funktion, die mit der Methode call_tool dekoriert wurde. Wenn der Agent ein Tool aufruft, übergibt er dessen Namen und alle erwarteten Argumente. Anhand des Funktionsnamens können wir dann bestimmen, welches Tool der Agent aufrufen und ausführen möchte.

Wir können auch die Auflistung der Tools mithilfe des Low-Level-Servers verwalten, im Gegensatz zu FastMCP, das dies automatisch tut, wenn eine Funktion mit der Tool-Methode dekoriert wurde.

@app.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="list_models", description="Listet alle verfügbaren Modelle der Novita-API auf.", inputSchema={"type": "object", "properties": {}}, ), types.Tool( name="get_model", description="Geben Sie eine Modell-ID und eine Nachricht an, um eine Antwort von der Novita-API zu erhalten.", inputSchema={ "type": "object", "required": ["model_id", "message"], "properties": { "model_id": { "type": "string", "description": "Die ID des zu verwendenden Modells.", }, "message": { "type": "string", "description": "Die zu sendende Eingabenachricht.", }, }, }, ), ]

Hier ist der vollständige Low-Level-Servercode. Er enthält zwei Tools und kann über Standard-Ein- und -Ausgabe mit dem Client kommunizieren.

importiere os, importiere asyncio, importiere Anfragen von mcp.server.lowlevel, importiere Server von mcp.server.stdio, importiere stdio_server, importiere mcp.types als Typen, base_url = "https://api.novita.ai/v3" headers = { "Content-Type": "application/json", "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}" } app = Server("Novita_API") async def list_models_tool(): """ Listet alle verfügbaren Modelle der Novita-API auf. """ URL = Basis-URL + "/openai/models" Antwort = Anfragen.get(URL, Header=Header) Daten = Antwort.json()["Daten"] Text = "" für i, Modell in Aufzählung(Daten, Start=1): Text += f"Modell-ID: {Modell['ID']}\n" Text += f"Modellbeschreibung: {Modell['Beschreibung']}\n" Text += f"Modelltyp: {Modell['Modelltyp']}\n\n" Rückgabe [Typen.TextContent(Typ="Text", Text=Text)] asynchron def get_model_tool(Argumente: Diktat): """ Bei einer gegebenen Modell-ID und einer Benutzernachricht eine Antwort von der Novita-API abrufen. """ model_id = arguments.get("model_id") message = arguments.get("message") wenn nicht model_id oder nicht message: raise ValueError("Sowohl 'model_id' als auch 'message' sind erforderlich.") url = base_url + "/openai/chat/completions" payload = { "model": model_id, "messages": [ { "content": message, "role": "user", } ], "max_tokens": 200, "response_format": { "type": "text", }, } response = requests.post(url, json=payload, headers=headers) content = response.json()["choices"][0]["message"]["content"] return [types.TextContent(type="text", text=content)] @app.call_tool() async def manage_tool(name: str, arguments: dict ) -> list[types.TextContent]: if name == "list_models": return await list_models_tool() if name == "get_model": return await get_model_tool(arguments) else: raise ValueError(f"Unknown tool: {name}") @app.list_tools() async def list_tools() -> list[types.Tool]: return [ types.Tool( name="list_models", description="Listet alle verfügbaren Modelle der Novita-API auf.", inputSchema={"type": "object", "properties": {}}, ), types.Tool( name="get_model", description="Geben Sie eine Modell-ID und eine Nachricht an, um eine Antwort von der Novita-API zu erhalten.", inputSchema={ "type": "object", "required": ["model_id", "message"], "properties": { "model_id": { "type": "string", "description": "Die ID des zu verwendenden Modells.", }, "message": { "type": "string", "description": "Die zu sendende Eingabenachricht.", }, }, }, ), ] async def main(): async mit stdio_server() als Streams: warte auf app.run(streams[0], streams[1], app.create_initialization_options()) if __name__ == "__main__": asyncio.run(main())

Der Low-Level-Server bietet Ihnen nicht nur eine detaillierte Kontrolle über die Toolverwaltung, sondern auch eine Low-Level-Kontrolle über Ressourcen, Eingabeaufforderungen und andere Teile des MCP-Protokolls, wie beispielsweise das Lebenszyklusmanagement.

Fazit

In diesem Tutorial haben wir einen MCP-Server erstellt, der die Novita-API nutzt, um die Funktionen jedes MCP-Hosts zu erweitern. Sie haben die Grundlagen zur Erstellung eines MCP-Servers gelernt, einschließlich der Definition und Bereitstellung von Tools.

Mit dieser Grundlage können Sie sich mit fortgeschritteneren Themen wie Authentifizierung, Bereitstellung von Remote-MCP-Servern und direkter Arbeit mit der Low-Level-Python-Implementierung befassen.

Wir haben auch die Novita-API selbst untersucht und ihre Möglichkeiten kennengelernt, von einer Vielzahl von Sprachmodellen bis hin zu Generierungstools für Video, Audio und Bilder. Besuchen Sie die Ankündigungen LLM Spielplatz um andere APIs auszuprobieren, die wir nicht so gut behandeln konnten, wie etwa die Endpunkte des Bild- und Gesichtseditors.

Novita AI ist eine KI-Cloud-Plattform, die Entwicklern eine einfache Möglichkeit bietet, KI-Modelle mithilfe unserer einfachen API bereitzustellen und gleichzeitig die kostengünstige und zuverlässige GPU Cloud zum Erstellen und Skalieren.


Entdecken Sie mehr von Novita

Abonnieren Sie, um die neuesten Beiträge per E-Mail zu erhalten.

Hinterlasse einen Kommentar

Nach oben scrollen

Entdecken Sie mehr von Novita

Abonnieren Sie jetzt, um weiterzulesen und Zugriff auf das vollständige Archiv zu erhalten.

Weiterlesen