AWS Germany – Amazon Web Services in Deutschland

MCP-Server über MQTT mit AWS IoT Core verbinden

Das Model Context Protocol (MCP) bietet KI-Anwendungen eine standardisierte Schnittstelle, um Tools zu entdecken und aufzurufen. Viele MCP-Server laufen lokal über stdio. Das ist praktisch für Desktop-Anwendungen, aber problematisch für verteilte Umgebungen, in denen Geräte ausschließlich über MQTT kommunizieren. In Edge- und IoT-Szenarien ist das Öffnen von HTTP-Ports häufig keine Option.

Dieser Beitrag zeigt Ihnen, wie Sie stdio-basierte MCP-Server über einen schlanken MQTT-Wrapper mit AWS IoT Core verbinden können. Damit ermöglichen Sie Ihren KI-Anwendungen den sicheren Zugriff auf Maschinendaten und Steuerungsfunktionen – ohne Änderungen an bestehenden MCP-Servern und ohne zusätzliche Firewall-Freigaben. Sie reduzieren den Entwicklungsaufwand, nutzen bewährte MCP-Bibliotheken und profitieren von der skalierbaren, verwalteten MQTT-Infrastruktur von AWS IoT Core.

Was ist MCP?

MCP ist keine REST-API. Es handelt sich um ein strukturiertes, RPC-basiertes Protokoll: Clients rufen explizite Methoden wie tools/list oder tools/call auf, anstatt URL-basierte Ressourcen anzusprechen. MCP verwendet JSON-RPC 2.0. Methodenaufrufe und Antworten sind JSON-Nachrichten mit Feldern wie method, params und id.

Protokoll-Stack

MCP baut auf einem Transport und einem Nachrichtenformat auf:

Schematische Darstellung des MCP-Protokoll-Stacks: Auf der untersten Ebene befindet sich TCP, darüber die Transportschicht mit HTTP, stdio oder WebSocket, gefolgt von JSON-RPC 2.0 als Nachrichtenformat, MCP als Semantik-Schicht und der Anwendungslogik an der Spitze

Abbildung 1: Der MCP-Protokoll-Stack zeigt die Schichtung von TCP über Transport und JSON-RPC 2.0 bis zur Anwendungslogik.

  1. TCP bildet die Basis.
  2. HTTP, stdio oder WebSocket dient als Transport.
  3. JSON-RPC 2.0 definiert das Nachrichtenformat.
  4. MCP definiert die Semantik.
  5. Anwendungslogik umfasst Ihre Tools, Ressourcen und Prompts.

Kern-Methoden

Die MCP-Spezifikation definiert unter anderem folgende Methoden:

Methode Beschreibung
initialize Handshake und Capability-Aushandlung
tools/list Verfügbare Tools und deren Schemata auflisten
tools/call Ein Tool mit Argumenten aufrufen
resources/list Ressourcen auflisten

MCP über HTTP und stdio im Vergleich

MCP über HTTP

Wenn der MCP-Server über http://localhost:PORT läuft, verhält er sich aus Netzwerksicht wie jeder andere lokale Dienst. Andere Dienste müssen den Port kennen und MCP über JSON-RPC 2.0 sprechen.

MCP über stdio

Beim stdio-Transport wird der MCP-Server vom Client als Kindprozess gestartet. Er lauscht nicht auf einem Port und öffnet keinen Netzwerk-Socket. Der Client kommuniziert über stdin und stdout. Das bedeutet:

  • Nur der Prozess, der den Server gestartet hat, kann mit ihm kommunizieren.
  • Andere Dienste auf derselben Maschine können ihn nicht entdecken.
  • Der Server verhält sich wie ein privates Plugin, nicht wie eine gemeinsam genutzte API.

Der stdio-Transport ist verbreitet bei IDE-Integrationen, lokalen KI-Assistenten und sicheren Umgebungen, in denen das Öffnen von Ports unerwünscht ist.

MCP-Handshake

Bevor ein Tool aufgerufen werden kann, muss der Client den MCP-Handshake abschließen. Der Ablauf ist pull-basiert: Der Server sendet keine Tool-Definitionen von sich aus. Der Client muss sie anfordern.

Schritt 1: Client sendet initialize

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": { "tools": {}, "resources": {}, "prompts": {} },
    "clientInfo": { "name": "my-agent", "version": "1.0.0" }
  }
}

Schritt 2: Server antwortet

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": { "tools": {}, "resources": {} },
    "serverInfo": { "name": "weather-server", "version": "1.2.0" }
  }
}

Schritt 3: Client sendet initialized (Notification ohne id)

Schritt 4: Client ruft tools/list auf

Schritt 5: Client ruft tools/call auf

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": { "city": "Berlin" }
  }
}

Der minimale Ablauf für einen Tool-Aufruf ist: initializeinitializedtools/listtools/call.

Herausforderung: stdio in IoT-Umgebungen

Stellen Sie sich vor, Sie betreiben Maschinen, die keine HTTP-Server exponieren können, aber jeweils einen MCP-Server über stdio ausführen. Die Maschinen verbinden sich über MQTT mit AWS IoT Core. Sie möchten einen zentralen MCP-Server, der alle Tools der Maschinen aggregiert.

Das Problem: stdio-Server sind nur lokal erreichbar. Die Lösung: ein schlanker MQTT-Wrapper.

Lösung: MQTT-Wrapper

Der Wrapper ist ein kleiner Prozess auf jedem Gerät, der MQTT-Nachrichten empfängt, sie an den lokalen MCP-Server über stdio weiterleitet und die Antworten über MQTT zurücksendet.

Vorteile des Wrapper-Ansatzes

  • Einfach: Wenige Zeilen Code statt Hunderte.
  • Standardkonform: Verwendet offizielle MCP-Implementierungen unverändert.
  • Flexibel: Funktioniert mit jedem MCP-Server.
  • Wartbar: Protokolländerungen werden von der MCP-Bibliothek behandelt.

Architektur

Architekturdiagramm der Lösung: Links ein Edge-Gerät mit MCP-Server als Subprocess, der über stdin/stdout mit dem Thin Wrapper kommuniziert. Der Wrapper verbindet sich über einen MQTT-Client mit AWS IoT Core auf der rechten Seite. Pfeile zeigen den bidirektionalen Datenfluss.

Abbildung 2: Architektur des MQTT-Wrappers mit Datenfluss vom MCP-Server über den Wrapper zu AWS IoT Core.

Implementierung

Voraussetzungen

Für diese Lösung benötigen Sie:

  • Ein AWS-Konto
  • Zugriff auf AWS IoT Core
  • Python 3.10 oder höher
  • Grundkenntnisse in MQTT und asyncio
  • Einen funktionierenden MCP-Server (beispielsweise mit FastMCP [EN, Extern])

MQTT-Bridge für stdio-MCP-Server

1. Überblick

Die Bridge verbindet AWS IoT Core (MQTT) mit einem MCP-Server, der als Subprocess läuft und über stdin/stdout (zeilenbasiertes JSON-RPC) angesprochen wird. Sie übernimmt genau drei Aufgaben:

  1. MCP-Server starten (Kindprozess)
  2. Anfragen weiterleiten: MQTT → stdin des MCP-Servers
  3. Antworten zurücksenden: stdout des MCP-Servers → MQTT

2. MCP-Server als Subprocess

Der Wrapper startet den MCP-Server als Kindprozess mit festem stdin/stdout:

self.process = await asyncio.create_subprocess_exec(
    *self.mcp_command,
    stdin=asyncio.subprocess.PIPE,
    stdout=asyncio.subprocess.PIPE,
    stderr=asyncio.subprocess.PIPE,
)

3. MQTT → stdin (Anfragen)

  • Die Bridge abonniert alle relevanten MQTT-Anfragen:
    • mcp-rpc/+/{server_id}/{server_name} (beispielsweise mcp-rpc/+/device-a1b2c3d4/devices/iot-sensor-hub).
  • Jede eingehende MQTT-Nachricht wird als JSON geparst und als eine Zeile auf stdin des MCP-Servers geschrieben.
  • Caller-ID: Sofern mehrere Aufrufer vorhanden sind, wird die Caller-ID aus dem Topic ausgelesen und in pending_requests[request_id] = caller_id gespeichert, damit die Antwort dem richtigen Aufrufer zugeordnet werden kann.

4. stdout → MQTT (Antworten)

  • Jede Zeile von stdout wird als JSON-RPC-Antwort interpretiert.
  • Die Antwort wird als eine MQTT-Nachricht auf dem Response-Topic veröffentlicht:
    • mcp-rpc/{server_id}/{caller_id}/{server_name} (Reihenfolge: zuerst server_id, dann caller_id).
  • Aus der Antwort wird die id gelesen, über pending_requests die zugehörige caller_id ermittelt und der Eintrag entfernt.

5. Presence (Discovery)

  • Beim MQTT-Connect ruft die Bridge intern tools/list beim MCP-Server auf und veröffentlicht anschließend einen Presence-Payload.
  • Topic: mcp-server/presence/{server_id}/{server_name} (beispielsweise mcp-server/presence/device-a1b2c3d4/devices/iot-sensor-hub).
  • Bei einem unerwarteten Abbruch bleiben die Tool-Informationen im Broker persistent gespeichert.

6. Topic-Struktur

Zweck Topic-Format Verwendung
Anfrage mcp-rpc/{caller_id}/{server_id}/{server_name} Client/Meta-Server veröffentlicht hier
Antwort mcp-rpc/{server_id}/{caller_id}/{server_name} Client/Meta-Server abonniert hier
Presence mcp-server/presence/{server_id}/{server_name} Bridge veröffentlicht; Discovery abonniert

AWS IoT Core konfigurieren

Der Wrapper verwendet TLS mit gegenseitiger Authentifizierung und ALPN:

import ssl

ssl_context = ssl.create_default_context()
ssl_context.load_cert_chain(certfile, keyfile)
ssl_context.load_verify_locations(ca_certs)
ssl_context.set_alpn_protocols(["x-amzn-mqtt-ca"])

mqtt_client.tls_set_context(ssl_context)
mqtt_client.connect(aws_endpoint, 8883)

Konfigurieren Sie Zertifikate und IoT-Policies in AWS IoT Core so, dass Geräte und der Meta-Server ausschließlich auf den erlaubten Topics abonnieren und veröffentlichen können.

Weitere Informationen finden Sie in der AWS IoT Core-Dokumentation und im Abschnitt Gerätezertifikate erstellen.

Bereinigung

Um unerwartete Kosten zu vermeiden, löschen Sie nach dem Testen folgende Ressourcen in der AWS IoT Core-Konsole [EN]:

  1. IoT Things
  2. Zertifikate
  3. IoT Policies

Fazit

MCP bietet KI-Anwendungen eine standardisierte Möglichkeit, Tools über JSON-RPC zu entdecken und aufzurufen. Für Edge- oder IoT-Deployments mit AWS IoT Core ermöglicht ein schlanker MQTT-Wrapper die Nutzung von Standard-MCP-Servern auf Geräten, ohne MQTT in jede einzelne MCP-Implementierung einbauen zu müssen. Der Wrapper übernimmt ausschließlich Transport und Presence. Die gesamte MCP-Protokolllogik verbleibt in bestehenden, gut gewarteten MCP-Bibliotheken.

Nächste Schritte

  • Erstellen Sie ein IoT Thing in AWS IoT Core und generieren Sie Zertifikate.
  • Implementieren Sie den MQTT-Wrapper auf Ihrem Edge-Gerät.
  • Testen Sie die Verbindung mit einem einfachen MCP-Server, beispielsweise dem Weather-Beispiel.
  • Erweitern Sie die Lösung um einen Meta-Server, der Tools mehrerer Geräte aggregiert.

Weitere Informationen zum MQTT-Topic-Design finden Sie im Whitepaper Designing MQTT Topics for AWS IoT Core [EN]. Für Best Practices zur Gerätesicherheit empfehlen wir den Abschnitt Security Best Practices in AWS IoT Core [EN].


Über die Autoren

Tim Schäfer arbeitet als Solutions Architect bei AllCloud, einem AWS Premier Tier Services Partner. Sein Schwerpunkt liegt dabei auf der Unterstützung von KMU in der DACH-Region beim Aufbau sicherer Cloud-Plattformen. Auf Basis seiner fundierten Plattform-Expertise als ehemaliger Technical Instructor bei AWS spezialisiert er sich auf cloudnative Systeme. Dabei konzentriert er sich besonders auf Technologien an der Schnittstelle von IoT, Networking und generativer KI, um Unternehmen dabei zu helfen, ihre Cloud-Infrastruktur in einen Innovationstreiber zu verwandeln.
Thomas Wagner ist als Solutions Architect bei Amazon Web Services (AWS) in München tätig und ein zentraler Wegbereiter für die digitale Transformation des deutschen Mittelstands. Er spezialisiert sich darauf, etablierte Unternehmen sicher und effizient in die Cloud zu führen und die damit verbundenen strategischen Herausforderungen zu meistern. Neben der Konzeption robuster Cloud-Architekturen liegt sein Fokus auf der Implementierung zukunftsweisender Technologien wie Künstlicher Intelligenz und Machine Learning, um neue Geschäftspotenziale zu erschließen.