Skip to main content
Glama

Baue deinen eigenen MCP-Server (und stelle ihn bereit)

Ein vollständiger, funktionierender MCP-Server, der eine LLM-API in MCP-Tools verwandelt – gebaut, um gelehrt zu werden. Er läuft lokal über stdio für Claude Desktop / Claude Code und remote über HTTP, sobald du ihn bereitstellst.

Unterstützt durch Groq – schnelle Inferenz, OpenAI-kompatible API, kostenloser Tarif, der einem Raum voller Studenten standhält, die während eines Workshops darauf einhämmern.

Alles befindet sich in einer Datei: server.py. ~170 Zeilen inklusive Kommentare.


Teil 0 – Was ist MCP, in einer Minute

MCP (Model Context Protocol) ist ein Standardweg, um einem KI-Client neue Fähigkeiten zu geben. Du schreibst einen Server; jeder MCP-Client kann ihn nutzen.

Ein Server kann drei Dinge bereitstellen:

Primitive

Was es ist

Wer kontrolliert es

Tool

Eine Funktion, die das Modell aufrufen kann

Das Modell entscheidet

Resource

Schreibgeschützte Daten, die der Client einbinden kann

Der Client/die App entscheidet

Prompt

Eine wiederverwendbare Prompt-Vorlage

Der Benutzer wählt sie aus

Zwei Transporte:

  • stdio – der Client startet deinen Server als Unterprozess und kommuniziert über stdin/stdout. Nur lokal. Kein Netzwerk. So laufen 90% der MCP-Server.

  • streamable HTTP – dein Server ist ein Webdienst unter einer URL. Das stellst du bereit, damit andere (oder gehostete Clients) ihn nutzen können.

Derselbe server.py macht beides. Das ist der ganze Trick.


Teil 1 – Was wir bauen

llm-toolkit: ein MCP-Server, der jedem MCP-Client vier LLM-gestützte Tools bietet.

Tool

Macht

ask_llm

Stelle eine Frage, wähle prägnant / detailliert / eli5

summarize

Text → N Aufzählungspunkte

translate

Übersetze, unter Beibehaltung von Markdown und Codeblöcken

extract_json

Unstrukturierter Text → strukturiertes JSON

Plus eine Resource (config://server-info) und einen Prompt (code_review), damit Studenten alle drei Primitive sehen.


Teil 2 – Lokal ausführen

Einrichtung

python -m venv .venv

Windows: .venv\Scripts\activate – macOS/Linux: source .venv/bin/activate

pip install -r requirements.txt

Hole dir einen kostenlosen Schlüssel unter console.groq.com → API Keys. Kopiere dann .env.example nach .env und füge ihn ein:

cp .env.example .env

.env ist in gitignored. Der Server lädt es automatisch aus seinem eigenen Verzeichnis, also funktioniert es, egal von wo der Client ihn startet.

Überprüfe ihn, bevor du ihn anschließt

Der MCP Inspector ist das beste Lehrmittel überhaupt – er zeigt die Tool-Liste und lässt dich Tools von Hand aufrufen, ohne KI-Client.

npx @modelcontextprotocol/inspector python server.py

Öffne die gedruckte URL, klicke auf Connect, dann List Tools. Du siehst alle vier.


Teil 3 – Verbinde ihn mit einem Client

Claude Code

claude mcp add llm-toolkit -e GROQ_API_KEY=gsk_... -- python /absolute/path/to/server.py

Oder committe eine .mcp.json in deinem Projektstammverzeichnis, damit das ganze Team sie bekommt – siehe .mcp.json.example.

Claude Desktop

Bearbeite claude_desktop_config.json:

  • macOS – ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows – %APPDATA%\Claude\claude_desktop_config.json

Füge den mcpServers-Block aus .mcp.json.example ein, dann beende und öffne Claude Desktop vollständig neu. Die Tools erscheinen unter dem Tools-Symbol.

Nur absolute Pfade. Der häufigste Grund, warum ein lokaler MCP-Server „nicht angezeigt wird“, ist ein relativer Pfad – das Arbeitsverzeichnis des Clients ist nicht deines. Verwende den vollständigen Pfad sowohl zur Python-Binärdatei (.venv/bin/python) als auch zu server.py.


Teil 4 – Bereitstellen

Wechsle mit einem Flag in den HTTP-Modus:

python server.py --http

Server ist jetzt unter http://localhost:8000/mcp. Versende denselben Befehl in einem Container.

Option A – Render, ohne Docker (empfohlen)

Render hat eine native Python-Laufzeitumgebung. Kein Dockerfile, kein Container-Build. Es installiert requirements.txt und führt deinen Startbefehl direkt aus. Das ist der schnellste Weg vom Laptop zur öffentlichen URL.

Schritt 1 – Code auf GitHub bringen.

git init && git add -A && git commit -m "MCP server"

Erstelle ein leeres Repository unter github.com/new, dann:

git remote add origin https://github.com/<you>/llm-toolkit-mcp.git && git push -u origin main

Schritt 2 – Dienst erstellen.

Render-Dashboard → New → Web Service → Repository verbinden. Render liest render.yaml und konfiguriert sich selbst:

Einstellung

Wert

Runtime

Python (nicht Docker)

Build-Befehl

pip install -r requirements.txt

Start-Befehl

python server.py --http

Schritt 3 – Schlüssel setzen. Dashboard → EnvironmentGROQ_API_KEY hinzufügen. Es ist als sync: false in render.yaml markiert, lebt also nur im Dashboard, niemals in Git.

Schritt 4 – Bereitstellen. Dein öffentlicher Endpunkt ist https://<deine-app>.onrender.com/mcp.

Kein Health-Check absichtlich. GET /mcp öffnet einen SSE-Stream, der absichtlich offen bleibt. Ein darauf gerichteter Health-Check hängt, und Render interpretiert das Timeout als toten Dienst und startet ihn in einer Schleife neu. Wenn healthCheckPath weggelassen wird, überprüft Render nur, ob der Prozess $PORT bindet – die korrekte Prüfung für diesen Server.

Instanzen im kostenlosen Tarif schlafen nach ~15 Minuten Inaktivität ein. Der erste Aufruf nach einem Schlaf dauert ~30–50s, während er aufwacht. Einige MCP-Clients timeouten davor und melden den Server als defekt. Wärme ihn mit einem curl auf, bevor der Unterricht beginnt.

Option B – Andere Hosts ohne Docker

Host

Wie

Railway

Repository verbinden. Nixpacks erkennt Python automatisch. Startbefehl auf python server.py --http setzen.

Hugging Face Spaces

Kostenlos, kein Schlaf. Docker Space oder Gradio Space mit einem benutzerdefinierten app.py-Shim.

Google Cloud Run

gcloud run deploy --source . – baut aus dem Quellcode, kein Dockerfile nötig.

Beliebiger VPS

pip install -r requirements.txt, dann unter systemd oder tmux ausführen.

Option C – Fly.io

fly launch --no-deploy
fly secrets set GROQ_API_KEY=gsk_...
fly deploy

Endpunkt: https://<deine-app>.fly.dev/mcp

Option D – Beliebiger Container-Host

Das Dockerfile wird für Hosts bereitgehalten, die einen Container möchten. Funktioniert auf Railway, Cloud Run, ECS, einem VPS:

docker build -t llm-toolkit-mcp .
docker run -p 8000:8000 -e GROQ_API_KEY=gsk_... llm-toolkit-mcp

Bereitstellung überprüfen

Ein curl beweist, dass der Server lebt und MCP spricht:

curl -X POST https://your-app.onrender.com/mcp -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'

Du solltest einen serverInfo-Block mit dem Namen llm-toolkit zurückbekommen.

Einen Client mit dem bereitgestellten Server verbinden

claude mcp add --transport http llm-toolkit https://your-app.onrender.com/mcp

Studenten fügen diese eine Zeile ein und haben sofort deine vier Tools. Das ist der Moment der Erkenntnis im gesamten Workshop – keine Installation, kein Schlüssel, kein Python auf ihrem Rechner.

Öffentlich teilen – lies dies zuerst

Ein bereitgestellter MCP-Server ohne Authentifizierung ist für das gesamte Internet offen. Jeder, der die URL erfährt, kann deine Tools aufrufen, und jeder Aufruf verbraucht dein Groq-Kontingent.

Für einen Workshop ist das normalerweise in Ordnung, und Groqs kostenloser Tarif macht es möglich: Wenn das Kontingent aufgebraucht ist, erhältst du HTTP-429-Fehler, keine Rechnung. Der Fehlermodus ist „Tools antworten nicht mehr“, nicht „Überraschungsrechnung“.

Es ist nicht mehr in Ordnung, sobald du einen kostenpflichtigen Schlüssel dahinter setzt. Füge dann Authentifizierung hinzu, bevor du die URL teilst – den auth-Parameter des MCP-SDKs oder ein API-Gateway davor.

Zwei Gewohnheiten, die sich trotzdem lohnen:

  • Behandle die URL als halbgeheim. Teile sie im Unterricht, poste sie nicht öffentlich.

  • Rotiere den Schlüssel nach dem Workshop. Es ist ein Klick im Dashboard.

Teil 5 – Dinge, die es wert sind, explizit gelehrt zu werden

Der Docstring ist die API. Das Modell wählt Tools aus, indem es den Docstring und die Typannotationen liest. Ein vager Docstring bedeutet ein Tool, das nie aufgerufen wird. Das ist die einzige Sache mit der größten Hebelwirkung in der gesamten Datei.

Eine Funktion besitzt den Provider. Jedes Tool ruft call_llm() auf. Groq gegen OpenAI, Anthropic oder ein lokales Ollama auszutauschen bedeutet, diese eine Funktion zu bearbeiten – die vier Tools ändern sich nie. Demonstriere das live; es kommt gut an.

Fehler als Strings zurückgeben, nicht auslösen. call_llm fängt GroqError ab und gibt die Nachricht als Text zurück. Der Client zeigt dem Benutzer einen echten Fehler an, statt eines toten Tool-Aufrufs.

stateless_http=True bedeutet keine klebrigen Sitzungen, sodass der Server hinter einem Load-Balancer skaliert. Schalte es nur aus, wenn du Sitzungszustand hinzufügst.

Den Schlüssel niemals committen. .env ist in gitignored, render.yaml verwendet sync: false, Fly verwendet fly secrets.

Öffentliche HTTP-Server sind standardmäßig offen. Dieser hat keine Authentifizierung – in Ordnung für eine Demo, nicht für die Produktion. Echte Bereitstellungen fügen OAuth über den auth-Parameter des SDKs hinzu oder sitzen hinter einem API-Gateway.

Versionsdrift ist real. MCP Python SDK 2.0 hat FastMCP in MCPServer umbenannt. Die meisten Tutorials online zeigen immer noch FastMCP und werden bei einer frischen Installation fehlschlagen. Guter Moment, um zu lehren, die installierte Paketdokumentation zu lesen, anstatt einem Blogbeitrag zu vertrauen.


Teil 6 – Übungen für die Klasse

  1. Füge ein sentiment(text)-Tool hinzu. (Kopiere summarize, ändere den System-Prompt.)

  2. Lasse ask_llm ein max_tokens-Argument akzeptieren und beobachte, wie das Schema automatisch im Inspector aktualisiert wird.

  3. Richte call_llm auf einen anderen Provider, ohne ein Tool zu berühren.

  4. Füge eine Resource config://usage hinzu, die meldet, wie viele Tool-Aufrufe der Prozess bedient hat. (Tipp: ein Modulzähler.)

  5. Zerstöre absichtlich einen Docstring und bitte dann das Modell, dieses Tool zu verwenden. Beobachte, wie es das Tool nicht auswählt. Das ist die Lektion.


Teil 7 – Andere dazu bringen, es zu nutzen

Die Tools an jemand anderen weiterzugeben, sind drei separate Probleme: erreichbar, verbindbar, auffindbar. Löse sie in dieser Reihenfolge.

1. Erreichbar. Ein Server auf localhost ist für genau eine Person nutzbar. Stelle ihn bereit (Teil 4) und du hast eine öffentliche URL. Nichts unten funktioniert, bis dies erledigt ist.

2. Verbindbar. Gib den Leuten USING-IT.md – eine eigenständige Seite mit Copy-Paste-Konfiguration für Claude Code, Claude Desktop und Cursor, plus einer Fehlerbehebungstabelle. Für einen Workshop ist der Remote-Weg der richtige: Studenten fügen eine Zeile ein und haben funktionierende Tools ohne Python, ohne Repository und ohne eigenen API-Schlüssel.

3. Auffindbar. Nur wenn du möchtest, dass Fremde es finden, nicht nur deine Klasse:

Kanal

Was es dir bringt

GitHub-Themen mcp, mcp-server, model-context-protocol

Kostenloser Suchverkehr

Das offizielle MCP-Registry

In Client-„Server durchsuchen“-UIs aufgelistet

awesome-mcp-servers-Community-Listen

PR, um dein Repository hinzuzufügen

Smithery / Glama und ähnliche Verzeichnisse

Gehostete Installations-Buttons

Die Registry-Anforderungen ändern sich schnell – überprüfe die aktuellen MCP-Registry-Dokumente auf das Manifest-Format, bevor du veröffentlichst.

Eine Anmerkung zur ehrlichen Obergrenze. Leute übernehmen einen MCP-Server, wenn er etwas tut, das sie nicht bereits können. Dieser hier umschließt ein generisches LLM, das die meisten Clients bereits eingebaut haben – perfekt zum Lehren des Protokolls, schwach als Produkt. Ein Server, der deine Datenbank, deine interne API oder deine proprietären Daten erreicht, ist derjenige, der wirkliche Benutzer bekommt. Es lohnt sich, dies der Klasse laut zu sagen.


Teil 8 – Was ihn produktionsreif macht

Die Workshop-Version und die Produktionsversion unterscheiden sich in Dingen, die nichts mit MCP zu tun haben. Dies ist die Liste, und jedes Element existiert wegen eines Fehlers, der tatsächlich beim Bau dieses Servers passiert ist.

Den Schlüssel schützen

Ein öffentlicher MCP-Endpunkt ist ein öffentlicher Ausgaben-Endpunkt: Jeder Aufruf kostet dich.

Guard

Env var

Default

Warum

Bearer-Auth

MCP_AUTH_TOKEN

empty = open

Zugriff nur, wenn ein kostenpflichtiger Schlüssel dahinter steckt

Ratenbegrenzung

RATE_LIMIT_PER_MIN

30/IP

Ein Skript kann nicht Ihr gesamtes Kontingent aufbrauchen

Eingabeobergrenze

MAX_INPUT_CHARS

20000

Ein eingefügter Roman wird abgelehnt, bevor er Token kostet

Größenbegrenzung

MAX_BODY_BYTES

1 MB

Überdimensionierte Nutzdaten sterben vor dem Parsen

Die Authentifizierung ist standardmäßig deaktiviert, damit der Server für einen Workshop mit einem kostenlosen Schlüssel offen bleibt. Schalten Sie sie ein, bevor Sie einen kostenpflichtigen Schlüssel auf eine öffentliche URL richten:

MCP_AUTH_TOKEN=$(python -c "import secrets;print(secrets.token_urlsafe(32))") python server.py --http

Clients senden dann Authorization: Bearer <token>.

Den Anbieter überstehen

Modelle werden ohne Vorankündigung eingestellt. Groq hat während der Entwicklung llama-3.3-70b-versatile entfernt – es funktionierte um 07:15 und eine Stunde später gab es einen 404. Jedes Tool war sofort kaputt, und ein 404 liest sich wie „Ihr Server ist defekt“, nicht „der Anbieter hat gewechselt.“

MODEL_CHAIN behebt dies: Bei einem Fehler „Modell nicht gefunden“ wird der Aufruf an das nächste Modell weitergeleitet, anstatt zu scheitern. Andere Fehler – ein falscher Schlüssel, eine Ratenbegrenzung – schlagen sofort fehl, da ein erneuter Versuch über fünf Modelle hinweg nur Zeit verschwendet.

Timeouts (LLM_TIMEOUT_SECONDS) und Wiederholungen (LLM_MAX_RETRIES) werden an die SDKs der Anbieter übergeben, die bereits einen korrekten Backoff implementieren.

Gesundheitschecks

/health gibt einfaches JSON zurück. Führen Sie niemals einen Health-Check auf /mcp durch – es ist ein SSE-Stream, der von Natur aus offen bleibt, sodass der Probe hängt, die Plattform den Dienst als tot meldet und Sie eine Neustartschleife erhalten, die wie ein Absturz aussieht. Das hat hier einen echten Debugging-Durchlauf gekostet.

Protokollierung

Alles geht an stderr, niemals an stdout. Im Stdio-Modus transportiert stdout den JSON-RPC-Stream, sodass ein einzelner print()-Befehl das Protokoll beschädigt. Dies ist die häufigste Art, einen MCP-Server beim Debuggen zu beschädigen.

Die Middleware auf MCP-Ebene protokolliert jede Methode mit ihrer Dauer und funktioniert für beide Transporte.

Tests und CI

pytest tests/ läuft offline ohne API-Schlüssel und verbraucht nichts. Es deckt den Ablauf des Ratenbegrenzers, Eingabeobergrenzen, Modell-Fallback, Schemaerhaltung der Tools und Konfigurationsvalidierung ab.

GitHub Actions führt die Suite auf 3.11 und 3.12 aus, startet den Server und durchsucht die gesamte Git-Historie nach eingecheckten API-Schlüsseln – der Fehler, der nicht wiederherstellbar ist, weil ein gepuschter Schlüssel in dem Moment, in dem er landet, öffentlich ist.

Bekannte Grenzen

Es ist fair, einer Klasse gegenüber ehrlich zu sein, was noch fehlt:

  • Ratenbegrenzung ist prozessgebunden. Skalieren Sie auf N Instanzen und Sie erlauben das N-fache des Limits. Tauschen Sie es gegen Redis aus, bevor es relevant wird.

  • Ein gemeinsamer Token, keine benutzerspezifischen Schlüssel. Für eine Klasse in Ordnung, nicht für Kunden.

  • Keine Nutzungsmessung. Sie können nicht sagen, wer was verbraucht hat.

  • Kaltstarts der kostenlosen Stufe dauern nach Inaktivität immer noch 30–50 Sekunden.


Dateiübersicht

Datei

Warum es existiert

server.py

Der gesamte Server – Tools, Resource, Prompt

requirements.txt

mcp[cli] + groq + python-dotenv

Dockerfile

Container für jeden Host

render.yaml

Ein-Klick-Render-Deploy

fly.toml

Fly.io-Deploy

.env.example

Welche Umgebungsvariablen existieren

.mcp.json.example

Client-Konfiguration zum Kopieren

USING-IT.md

Eigenständige Seite zum Weitergeben an Benutzer

guards.py

Authentifizierung, Ratenbegrenzung, Größenbeschränkungen, Protokollierung

tests/

Offline-Testsuite, kein API-Schlüssel nötig

.github/workflows/

CI: Tests, Boot-Check, Geheimnis-Scan

-
license - not tested
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • MCP server for AI dialogue using various LLM models via AceDataCloud

  • MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.

  • MCP server for Pentest-Tools.com: run scans, manage findings and reports via your preffered LLM.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aihunter9892/mcpserver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server