Alle Beiträge

MCP Server erstellen: dein erster Server in 30 Minuten

Ein MCP Server ist kein Hexenwerk: eine Handvoll Funktionen, sauber beschrieben. Hier baust du den ersten und hängst ihn an deinen Coding-Agent.

Kurz beantwortet

Ein MCP Server ist im Kern eine Handvoll gut beschriebener Funktionen, die ein Coding-Agent aufrufen kann — mit dem offiziellen Python-SDK (FastMCP) in rund 30 Minuten gebaut und über die MCP-Konfiguration als Prozess an Claude Code gehängt. Zwei Regeln entscheiden: Der Docstring ist deine komplette Schnittstelle zum Modell, und Tools bekommen minimale Berechtigungen — Read-only ist der Default.

Die meisten Entwickler reden über MCP, als wäre es ein Protokoll-Monster. Ist es nicht. Ein MCP Server ist im Kern eine Handvoll Funktionen, die du so beschreibst, dass ein Coding-Agent sie aufrufen kann. Wenn du schon mal eine REST-Route gebaut hast, kannst du das hier auch. In den nächsten 30 Minuten hängst du dein erstes eigenes Tool an einen Agenten — und verstehst danach, warum das mehr bringt als noch ein cleverer Prompt.

Wozu überhaupt MCP?

Ein Coding-Agent ohne Tools ist ein sehr belesener Praktikant ohne Zugriff auf irgendwas. Er kann über deine Datenbank reden, aber nicht hineinschauen. Er kann ein Deployment beschreiben, aber nicht auslösen. MCP — das Model Context Protocol — ist die standardisierte Steckdose, über die du dem Agenten echte Fähigkeiten gibst: eine Datenbank abfragen, ein internes API aufrufen, ein Ticket-System lesen.

Der Punkt ist die Standardisierung. Du schreibst das Tool einmal, und es funktioniert in Claude Code, in Cursor und in jedem anderen MCP-Client. Kein Glue-Code pro Agent.

Der kleinste Server, der etwas tut

Wir bauen einen Server mit einem Tool: er liest die offenen Tickets aus einer (hier simulierten) Quelle. Python, mit dem offiziellen SDK.

# server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("ticket-tools")

@mcp.tool()
def list_open_tickets(assignee: str) -> list[dict]:
    """Listet offene Tickets für eine Person.

    Args:
        assignee: Benutzername, z. B. "nico". Pflichtfeld.
    """
    # In echt: DB-Query oder API-Call. Hier hartkodiert.
    tickets = [
        {"id": 142, "title": "Login bricht bei leerem Passwort", "assignee": "nico"},
        {"id": 187, "title": "Rechnung-PDF fehlt MwSt-Zeile", "assignee": "mara"},
    ]
    return [t for t in tickets if t["assignee"] == assignee]

if __name__ == "__main__":
    mcp.run()

Das war der ganze Server. FastMCP übernimmt das Protokoll-Geplänkel; du schreibst nur die Funktion. Installieren und starten:

pip install "mcp[cli]"
python server.py

An den Agenten hängen

Jetzt verbindest du den Server mit Claude Code. In deiner MCP-Konfiguration trägst du ihn als Prozess ein:

{
  "mcpServers": {
    "ticket-tools": {
      "command": "python",
      "args": ["/absoluter/pfad/zu/server.py"]
    }
  }
}

Agent neu starten, und das Tool list_open_tickets taucht in seiner Werkzeugliste auf. Ab jetzt kannst du fragen: „Welche offenen Tickets hat nico?" — und der Agent ruft deine Funktion auf, statt zu raten.

Die Sache, die niemand erwähnt: der Docstring ist deine API

Hier kommt der Teil, der über Erfolg oder Frust entscheidet — und in keinem Schnellstart steht. Der Agent sieht deinen Code nicht. Er sieht nur den Tool-Namen, die Parameter und den Docstring. Das ist deine komplette Schnittstelle zum Modell.

Ein vager Docstring führt zu vagen Aufrufen: Der Agent ruft das Tool zur falschen Zeit auf, erfindet Parameter oder ignoriert es. Behandle die Beschreibung wie API-Doku für einen Junior, der nie nachfragen kann:

  • Sag, wann das Tool benutzt werden soll, nicht nur was es tut.
  • Beschreibe jeden Parameter mit Format und Beispiel.
  • Sei ehrlich über die Grenzen („nur offene Tickets, keine geschlossenen").

Die zweite Regel aus eigener schmerzhafter Erfahrung: gib niemals mehr Berechtigung weiter, als das Tool braucht. Ein MCP-Tool, das DELETE auf deine Produktiv-DB kann, weil es bequemer war, ist eine Zeitbombe. Read-only ist der Default. Schreibzugriff bekommt ein eigenes Tool mit engem Scope — damit du im Agenten-Log genau siehst, was passiert ist.

Vom Spielzeug zum echten Werkzeug

Die hartkodierte Liste ersetzt du durch deinen echten Datenzugriff — eine Query, ein API-Call, ein Dateisystem-Zugriff. Das Muster bleibt gleich: scharf umrissene Funktionen, klar beschrieben, minimal berechtigt. Genau so bauen wir bei anvil-coder die Tools, mit denen über 58 Agenten ein Ticket bis zum getesteten, reviewten Code führen — jedes Tool macht eine Sache, und du kannst im Log jeden Schritt nachvollziehen.

Der Takeaway, den du heute mitnimmst: Ein MCP Server ist keine Infrastruktur, es sind gut beschriebene Funktionen. Bau das kleinste, das einen echten Schmerz löst — und schreib den Docstring, als hinge dein Deployment davon ab. Tut es nämlich. Und für den Output des Agenten, der dein neues Tool nutzt, gilt erst recht: Review bleibt die Hauptdisziplin.

Willst du sehen, wie ein ganzer Schwarm aus Tools und Agenten ein Ticket bis zum Merge bringt? Schau dir anvil-coder an.

Häufige Fragen

Wie baue ich einen MCP Server in Python?

Mit dem offiziellen SDK: pip install "mcp[cli]", dann FastMCP instanziieren und Funktionen mit @mcp.tool() dekorieren — Docstring und Parameter beschreiben das Tool für den Agenten, mcp.run() startet den Server. In Claude Code trägst du ihn in der MCP-Konfiguration als Prozess mit command und args ein; nach dem Neustart taucht das Tool in der Werkzeugliste des Agenten auf.

Warum ist der Docstring bei MCP-Tools so wichtig?

Weil der Agent deinen Code nicht sieht — nur Tool-Name, Parameter und Docstring. Ein vager Docstring führt zu vagen Aufrufen: falscher Zeitpunkt, erfundene Parameter oder das Tool wird ignoriert. Schreib ihn wie API-Doku für einen Junior, der nie nachfragen kann: wann das Tool benutzt werden soll, jeder Parameter mit Format und Beispiel, ehrliche Grenzen.

Welche Berechtigungen sollte ein MCP-Tool bekommen?

So wenige wie möglich. Read-only ist der Default; Schreibzugriff bekommt ein eigenes Tool mit engem Scope, damit im Agenten-Log genau sichtbar ist, was passiert ist. Ein MCP-Tool, das aus Bequemlichkeit DELETE auf die Produktiv-Datenbank kann, ist eine Zeitbombe.

Was bringt MCP gegenüber einem besseren Prompt?

Echte Fähigkeiten statt Raten: Ohne Tools kann der Agent über deine Datenbank reden, aber nicht hineinschauen, ein Deployment beschreiben, aber nicht auslösen. MCP ist die standardisierte Steckdose dafür — du schreibst das Tool einmal, und es funktioniert in Claude Code, Cursor und jedem anderen MCP-Client, ohne Glue-Code pro Agent.

AI-Code ohne Tech-Schuld — die Checkliste

Trag dich ein: die Checkliste plus neue Beiträge zu KI-Engineering. Kein Spam, jederzeit abbestellbar.