MCP server for MQTT with a searchable message history, silence detection and connection-gap tracking
Server has 9 tools with complete input schemas and descriptions present. Naming follows verb_noun pattern (list_, get_, find_, publish). Descriptions are detailed but verbose (200-800+ chars, exceeding the 10-1024 baseline; many include German text and implementation details rather than LLM-optimized guidance). Parameters have types and descriptions. However, output schemas are not formally documented, responses are inferred from code. Error handling is minimal; no recovery guidance or actionable error messages. No tool annotations (readOnlyHint/destructiveHint). The publish tool lacks confirmation/dry-run pattern despite being destructive. Parameter descriptions mix implementation detail with usage guidance, reducing clarity for LLM selection.
Topics, die von MEHR ALS EINEM Broker bespielt werden. Der Ownership-Canary fuer den Parallelbetrieb zweier Broker: Die gefaehrliche Lage ist nicht "ein Geraet antwortet nicht", sondern "zwei Systeme schreiben auf dasselbe Topic und keiner merkt es". Verglichen wird ueber ALLE Broker-Datenbanken nebeneinander (jeder Server hat seit dem 22.08. seine eigene). `messbar` sagt, ob das Ergebnis ueberhaupt belastbar ist — bei `false` oder `"teilweise"` ist eine leere Konfliktliste ausdruecklich KEINE Entwarnung. ⛔ Eine BRIDGE ist kein Konflikt. Laeuft eine Bridge zwischen den Brokern, fuehren beide dieselben Topics — das ist der Normalzustand, nicht die Anomalie. Jedes Doppel-Topic wird deshalb eingeordnet: gespiegelt Bridge belegt (hohe Payload-Gleichheit) wahrscheinlich_gespiegelt Payloads zu einfoermig fuer einen Beweis, aber der Zeitversatz spricht dafuer unabhaengig ⛔ der echte Befund: zwei Schreiber unklar nicht entscheidbar — von Hand ansehen `nur_verdaechtige=True` (Default) listet Gespiegeltes nicht, sondern zaehlt es in `gespiegelt_nicht_gelistet`. Auf `False` setzen, um alles zu sehen.
Topics, die seit X Stunden NICHT mehr gemeldet haben. Die Frage vom 2026-08-01: 'seit wann meldet dieser Stecker nichts mehr?' (sonoff-4854 war seit dem 02.06. still — ein defekter Zwischenstecker).
Zeitraeume, in denen der Sammler NICHT mit dem Broker verbunden war. Trennt 'Geraet ist still' von 'ich habe nicht zugehoert'. Ohne diese Auskunft sehen beide Faelle in den Daten identisch aus.
Verlauf eines Topics mit Zeitstempeln — die Kernfunktion dieses Servers. mit_startschwall=False blendet den retained-Altbestand aus, der direkt nach dem Verbinden ankommt und einen irrefuehrend frischen Zeitstempel traegt.
Output schemas not formally documented. Responses are inferred from code; LLMs cannot predict return structure before calling tools.
Descriptions are verbose (200-800+ chars) and mix German implementation detail with usage guidance. Exceeds 1024-char baseline and reduces LLM clarity for tool selection.
No tool annotations (readOnlyHint/destructiveHint). LLMs cannot distinguish safe read-only tools from the destructive publish tool without explicit hints.
Destructive tool (publish) lacks confirmation/dry-run pattern. No mechanism to prevent accidental message publication.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
Letzter bekannter Wert eines Topics — sofort, ohne auf die naechste Nachricht zu warten. Genau das, was fertige MQTT-MCP-Server nicht koennen: bei einem schlafenden Batteriesensor (Shelly H&T) kaeme die naechste Nachricht erst in Stunden.
Topic-Baum ab einem Praefix — der Ueberblick wie im MQTT Explorer.
Topic-Inventar: welche Topics gibt es, wie viele Nachrichten, wann zuletzt. pattern: Glob wie 'tele/*' oder '*SENSOR'. seit_stunden schraenkt auf den juengeren Zeitraum ein.
Nachricht senden. Nur bei aktivem Schreibmodus und nicht auf gesperrte Topics. ⚠️ Die Sperrliste ist eine Bremse gegen Fehlgriffe, keine Sicherheitsgrenze.
Zustand des Servers: Verbindung, Datenbestand, Schreibmodus.
Error handling is minimal. No recovery guidance, actionable error messages, or error classification (retryable vs fatal). get_last returns a dict with 'gefunden' flag but no guidance on next steps.