+200 XP

Ihren eigenen MCP-Server bauen

# Ihren eigenen MCP-Server bauen

Ein Connector ist nichts anderes als ein Server, der ein Protokoll spricht, und in den nächsten dreißig Minuten schreiben Sie einen, der Claude ein Tool get_order_status gibt, das er in Ihrem Namen aufrufen kann. Wir betreiben ihn zuerst lokal, machen ihn dann als Remote-Connector verfügbar und sagen anschließend ein paar sorgfältige Worte dazu, wer ihn aufrufen darf.

Sie kennen MCP (das Model Context Protocol) bereits als den offenen Standard, über den Claude Tools und Daten außerhalb seines Context Window erreicht. Jetzt bauen Sie die andere Seite dieses Handshakes: den Server.

Was ein MCP-Server tatsächlich ist

Ein MCP-Server ist ein kleines Programm, das eine Liste von Capabilities bekannt macht und darauf wartet, dass ein Client sie aufruft. Die drei Capability-Typen sind Tools (Funktionen, die das Modell aufrufen kann), Resources (read-only Daten, die das Modell hereinziehen kann) und Prompts (wiederverwendbare Templates). Für einen Connector, der die Frage „Wo ist meine Bestellung?“ beantwortet, brauchen Sie ein Tool.

Der Client ist die Host-Anwendung: Claude Desktop, die Claude Apps, Claude Code oder Ihr eigener Code mit dem Agent SDK. Der Client entscheidet, *wann* Ihr Tool aufgerufen wird. Ihr Server entscheidet nur, *was das Tool tut*. Diese Trennung ist der ganze Punkt. Sie berühren das Modell nie. Sie veröffentlichen eine klare Funktionssignatur und eine Beschreibung, und Claude findet heraus, wann ein Aufruf hilft.

Zwei Transports sind relevant:

  • stdio: Der Server läuft als lokaler Subprozess und kommuniziert über Standard Input/Output. So startet Claude Desktop einen lokalen Connector. Kein Netzwerk, keine Auth, am schnellsten gebaut.
  • Streamable HTTP: Der Server läuft als Webservice unter einer URL. So funktioniert ein *Remote*-Connector, und das ist es, was Sie im Connector-Marketplace einreichen oder mit einem Team teilen.

Sie schreiben die Tool-Logik einmal. Der Transport sind ein paar Zeilen am Ende. Fangen Sie mit stdio an.

Der minimale Server

Installieren Sie zuerst das offizielle Python SDK. Das Paket mcp bringt einen FastMCP-Helper mit, der die Protokoll-Verkabelung übernimmt, sodass Sie fast nichts außer Ihrer eigenen Funktion schreiben.

bash
pip install "mcp[cli]"

Jetzt der Server. Das ist alles.

python
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("order-tools")

# Ein winziger Platzhalter für Ihre echte Datenbank oder interne API.
ORDERS = {
    "A1001": {"status": "shipped", "carrier": "DHL", "eta": "2026-02-14"},
    "A1002": {"status": "processing", "carrier": None, "eta": None},
}

@mcp.tool()
def get_order_status(order_id: str) -> dict:
    """Look up the current status of a customer order by its ID.

    Args:
        order_id: The order reference, e.g. 'A1001'.
    """
    order = ORDERS.get(order_id.strip().upper())
    if order is None:
        return {"found": False, "order_id": order_id}
    return {"found": True, "order_id": order_id, **order}

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

Lesen Sie ihn von oben nach unten:

  • FastMCP("order-tools") erzeugt den Server und benennt ihn. Dieser Name erscheint in der Client-UI.
  • Der Decorator @mcp.tool() registriert die Funktion als aufrufbares Tool. Das SDK liest Ihre Type Hints (order_id: str, Rückgabe dict) und baut daraus automatisch das Input- und Output-Schema. Kein JSON Schema von Hand.
  • Der Docstring ist keine Dekoration. Claude liest ihn, um zu entscheiden, wann und wie das Tool aufgerufen wird. Die erste Zeile beschreibt das Tool, der Abschnitt Args: dokumentiert jeden Parameter. Schreiben Sie ihn so, als briefen Sie einen klugen neuen Kollegen, der Ihren Code nicht sehen kann.
  • mcp.run() ohne Argumente nutzt standardmäßig den stdio-Transport. Lokal brauchen Sie nichts weiter.

In der echten Version ruft der Body von get_order_status Ihr Bestellsystem auf: eine SQL-Abfrage, einen internen REST-Endpoint, einen Stripe-Lookup. Die MCP-Schicht ändert sich nie. Sie kapseln eine bestehende Capability, Sie bauen sie nicht neu.

Lokal in Claude Desktop betreiben

Claude Desktop liest eine kleine Konfigurationsdatei, die die lokalen Server auflistet, die es starten soll. Unter macOS liegt sie unter ~/Library/Application Support/Claude/claude_desktop_config.json. Fügen Sie Ihren Server hinzu:

json
{
  "mcpServers": {
    "order-tools": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"]
    }
  }
}

Starten Sie Claude Desktop neu. Die App startet Ihr Skript als Subprozess, fragt die Tool-Liste ab und zeigt order-tools im Connector-Menü. Tippen Sie jetzt: *„Wie ist der Status von Bestellung A1001?“* Claude sieht das Tool, ruft get_order_status("A1001") auf, erhält das JSON zurück und antwortet in normaler Sprache. Beim ersten Mal werden Sie um Freigabe des Aufrufs gebeten. Dieser Freigabeschritt ist der Client, der Sie schützt, und er ist beabsichtigt.

Wenn nichts erscheint, führen Sie zuerst python /path/to/server.py im Terminal aus, um Import-Fehler zu finden, und nutzen Sie dann den MCP Inspector (mcp dev server.py), um das Tool direkt anzustoßen, bevor Claude überhaupt ins Spiel kommt. Debuggen Sie den Server isoliert, die Verbindung erst danach.

Für die offizielle Anleitung und die aktuellen SDK-Details halten Sie den MCP Server Quickstart in einem Tab offen. Das Protokoll bewegt sich, und diese Seite ist die Quelle der Wahrheit.

Build an MCP Server in Python

Watch on YouTube

Remote gehen: vom Subprozess zum Connector

Ein lokaler stdio-Server hilft nur der Person, die ihn auf ihrer eigenen Maschine betreibt. Damit ein *Team* Ihren Connector nutzen kann oder damit er im Connector-Marketplace gelistet wird, muss er als Remote-HTTP-Service unter einer URL laufen.

Die Codeänderung ist fast nichts. Tauschen Sie den Transport:

python
if __name__ == "__main__":
    mcp.run(transport="streamable-http")

Jetzt hört Ihr Server auf einem HTTP-Endpoint statt auf stdio. Deployen Sie ihn wie jeden Webservice: ein Container in der Cloud Ihrer Wahl, hinter HTTPS, unter einem stabilen Hostnamen wie https://tools.yourco.com/mcp. Die Dokumentation von Anthropic behandelt die Anforderungen an Remote-Connectors, einschließlich des Streamable HTTP-Transports, den die Claude Apps erwarten.

In den Claude Apps fügt ein Nutzer (oder ein Admin bei einer Organisation) Ihren Connector per URL unter Einstellungen, dann Connectors hinzu. Ab diesem Moment erscheint Ihr Tool neben den eingebauten in Projects, in normalen Chats und für managed Agents. Ein Server, viele Oberflächen.

Der schwierige Teil am Remote-Betrieb ist nicht der Transport. Es ist die Frage, die Sie in der stdio-Version ignorieren durften: Wer ruft auf, und was darf diese Person sehen?

Wissenscheck

1. Wie ist in der beschriebenen MCP-Architektur die Verantwortung zwischen dem Client und Ihrem Server aufgeteilt?

2. Welcher MCP-Capability-Typ ist für die Beantwortung einer Frage wie „Wo ist meine Bestellung?“ die richtige Wahl, und warum?

3. Warum empfiehlt die Lektion, mit dem stdio-Transport zu beginnen, bevor man zu Streamable HTTP wechselt?

MEHRFACHAUSWAHL

4. Wählen Sie ALLE Aussagen, die die Transports stdio und Streamable HTTP korrekt beschreiben.

Wählen Sie alle richtigen Antworten aus.

MEHRFACHAUSWAHL

5. Wählen Sie ALLE korrekten Aussagen über MCP-Server und den FastMCP-Helper.

Wählen Sie alle richtigen Antworten aus.

Ein Wort zur Authentifizierung

Sobald Ihr Server über das Internet erreichbar ist, ist get_order_status("A1001") ein Problem. Bestellung A1001 gehört *jemandem*. Ohne Auth kann jeder, der Ihre URL findet, sämtliche Bestellungen durchzählen. Lokale stdio-Server erben das Vertrauen der Maschine, auf der sie laufen. Remote-Server erben nichts. Sie müssen es hinzufügen.

Der Remote-Transport von MCP unterstützt genau dafür OAuth 2.1. Der Ablauf, einfach gesagt:

1. Ein Nutzer fügt Ihren Connector in der Claude App hinzu.

2. Bevor der Connector funktioniert, schickt die App den Nutzer zu Ihrem Authorization Server, um sich anzumelden und zuzustimmen.

3. Ihr Server stellt ein Access Token aus, das an *genau diesen Nutzer* gebunden ist.

4. Jeder Tool-Aufruf von Claude kommt jetzt mit diesem Token an.

In Ihrem Tool lesen Sie das Token, lösen es zu einem Nutzer auf und begrenzen die Abfrage. Derselbe Aufruf von get_order_status liefert unterschiedliche Zeilen, je nachdem, wer fragt:

python
@mcp.tool()
def get_order_status(order_id: str, ctx: Context) -> dict:
    user = resolve_user(ctx.request_context)   # aus dem Bearer Token
    order = lookup_order(order_id, owner=user.id)
    if order is None:
        return {"found": False, "order_id": order_id}
    return {"found": True, **order}

Das Prinzip: vertrauen Sie niemals der `order_id` allein. Vertrauen Sie der authentifizierten Identität und prüfen Sie dann, ob diese Identität diese Bestellung sehen darf. Das Modell ist nicht Ihre Sicherheitsgrenze. Ihr Server ist es. Claude gibt bereitwillig alles weiter, was der Nutzer eintippt, einschließlich einer Order-ID, die jemand anderem gehört. Die Eigentumsprüfung lebt also in Ihrem Code und nirgendwo sonst.

Zwei praktische Hinweise für 2025-2026:

  • Für rein interne Tools ist ein einfacheres Bearer Token oder ein API Key im Header akzeptabel, solange der Transport HTTPS ist und das Token auf ein echtes Principal abbildet, gegen das Sie eingrenzen können. Vollständiges OAuth ist für Connectors gedacht, die echte Nutzer selbst hinzufügen.
  • Wenn Sie einen Connector im Marketplace listen oder ihn organisationsweit teilen, halten Sie sich an die Connector- und Security-Anforderungen von Anthropic. Org-Admins steuern, welche Connectors aktiviert sind, und diese Governance-Schicht setzt voraus, dass Ihr Server darunter korrekt authentifiziert. Die aktuelle Messlatte finden Sie in der Anthropic Connector-Dokumentation.

Wo das im Ökosystem hineinpasst

Ihr MCP-Server ist ein Baustein, nicht die ganze App. Derselbe Server, den Sie gerade geschrieben haben, lässt sich ohne Änderungen in mehrere Anthropic-Oberflächen einstecken:

  • Claude Code kann ihn laden, sodass der Coding-Agent get_order_status aufruft, während er in Ihrem Repo arbeitet.
  • Das Claude Agent SDK erlaubt Ihnen, einen managed Agent zu bauen, der Ihren Connector als eines von mehreren Tools nutzt, neben Dateizugriff und der GitHub-Integration.
  • Der Connector-Marketplace erlaubt anderen, ihn zu entdecken und hinzuzufügen.

Vergleichen Sie das mit Skills, die Anweisungen, Skripte und Dateien bündeln und damit prägen, wie Claude sich bei einer Aufgabe *verhält*. Ein Skill bringt Claude eine Vorgehensweise bei. Ein MCP-Server gibt Claude eine *Capability*, die er vorher nicht hatte: Live-Zugriff auf Ihr Bestellsystem. Oft werden Sie beides kombinieren. Ein „Customer Support“-Skill, der Ihren Tonfall und Ihre Eskalationsregeln kennt und einen order-tools MCP-Server für die Live-Daten aufruft. Zu wissen, welches Problem jeweils gelöst wird, ist die Hälfte davon, gut auf Claude zu bauen.

Bauen Sie das Tool einmal. Entscheiden Sie den Transport nach Publikum. Schützen Sie es über Identität. Das ist die ganze Disziplin.

Key Takeaways

  • Mit stdio starten, mit HTTP ausliefern. Schreiben und debuggen Sie Ihr Tool als lokalen stdio-Server mit FastMCP, dann ändern Sie eine Zeile (transport="streamable-http"), um daraus einen Remote-Connector zu machen. Die Tool-Logik ändert sich nie.
  • Docstring und Type Hints sind das Interface. Claude entscheidet anhand von Name, Beschreibung und Parametern, wann Ihr Tool aufgerufen wird. Schreiben Sie sie so sorgfältig wie den Code.
  • Authentifizieren, sobald Sie remote gehen. Nutzen Sie OAuth 2.1 für nutzerseitige Connectors, grenzen Sie jede Abfrage auf die authentifizierte Identität ein und machen Sie den Input des Modells niemals zu Ihrer Sicherheitsgrenze.
  • Zuerst isoliert testen. Nutzen Sie mcp dev server.py und den MCP Inspector, um zu prüfen, dass das Tool funktioniert, bevor Sie es in Claude Desktop oder die Apps einbinden.
  • Das richtige Primitive wählen. MCP-Server ergänzen *Capabilities* (Live-Daten, Aktionen), Skills prägen *Verhalten* (Vorgehensweisen, Tonfall). Echte Connectors kombinieren meist beides.

Was Sie aus dieser Lektion umsetzen

Diese Maßnahmen sind im Playbook der Rolle zusammengefasst.

  • Tool-Docstrings und Type Hints für das Routing des Modells schreiben
  • MCP-Server zunächst als lokales stdio bauen, dann den Transport auf remote umstellen
  • Jede Remote-MCP-Abfrage auf die authentifizierte Identität eingrenzen
Vollständiges Action Playbook ansehen

Verwandte Artikel

Aktuelle Blogartikel, die auf dieser Lektion aufbauen.