-
v2.4.0 Stable
released this
2026-09-02 05:22:23 +00:00 | 98 commits to main since this release2.4.0 - 2026-09-02 - MCP-Leseserver: zweiter Konsument auf demselben Kern
Author: Torben Nehmer
Letzter Schritt der Sequenz aus #36, inhaltlich Issue #19.
chemenubekommt einen zweiten
Konsumenten:search,types,describe_type,lintundstatusüber MCP. Kein CLI mit
angeschraubter Netzwerkschnittstelle — CLI und Server sind zwei Adapter auf dem Kern, den 2.3.0
freigelegt hat.tools/chemenu/mcp/, im Repo statt als eigenes Artefakt. Der Golden-Test, der die
Serverantworten gegen die--json-Formen der CLI hält, läuft nur mit beiden Seiten in einer
Testsuite; getrennt würde aus einem Contract eine Versionsabsprache. Der Test ruftwikitoolals
Subprozess gegen denselben Baum auf, überCHEMENU_ROOT— womit er nebenbei die Root-Auflösung
von außen mitprüft.Zwei Transports.
stdiozum Entwickeln und Testen ohne Netz,streamable-httpfür die
Auslieferung — der einzige, vor den sich die Authentifizierungs-Middleware überhaupt setzen kann,
weil sie ein HTTP-Reverse-Proxy ist.sseist über das SDK erreichbar und wird bewusst nicht
angeboten: der abgelöste Remote-Transport, jetzt darauf zu bauen verschiebt den Wechsel nur.
--host/--portgibt es, weil der Default auf Loopback bindet und ein Container hinter einem
Proxy eine Adresse braucht, die der Proxy erreicht — eine Eigenschaft der Software, nicht einer
Installation. Beide Transports sind gegen den echten Korpus gegengeprüft.Kein Schreibpfad, strukturell. Weder der Server noch
chemenu.apiimportiert irgendetwas
unterchemenu.commands, also existierennew,touch,xref,cite,publish,migrate
undversion bumpin dieser Reichweite gar nicht, statt aus einer Liste gefiltert zu werden. Ein
Test importiert das Servermodul in einem frischen Interpreter und sieht insys.modulesnach;
ein zweiter ruft alle fünf Tools auf und vergleicht den Dateibaum,HEADund
git status --porcelainvorher/nachher.Jede Antwort trägt ihren Commit.
commitundas_ofin jedem Payload;nullheißt, der
bediente Baum hat uncommittete Änderungen und die Antwort entspricht keiner Revision. Der Stempel
ist die Revision, aus der die Seiten tatsächlich gelesen wurden — zwischen Laden und Stempeln
kann der Baum sich bewegen, deshalb reicht der Ladepfad seine Revision durch, statt noch einmal
zu fragen. Das war beim ersten Durchlauf falsch:types/lint/statuslasen die zuletzt
gecachte Revision und stempeltennull, obwohl der Baum sauber war.Telemetrie in den bedienten Baum wird beim Start verweigert, nicht stillschweigend
umgeleitet. Tracing ist per Default an und schreibt nachreports/telemetry/im Repo — genau das
Verzeichnis, das der Sync pergit reset --hardwegräumen darf.WIKI_TRACE=0oder
WIKI_TRACE_DIRaußerhalb des Korpus. Heute schreibt auf diesem Pfad nichts (der Emitter hängt an
cli.main()und den Gates), die Sperre ist gegen später.Fehler an der Protokollgrenze. Ein
ChemenuErrorwird zumToolErrordes SDK — eine
absichtliche Ablehnung, deren Text den Aufrufer erreicht. Alles andere bleibt ein Absturz, dessen
Text auf dem Server bleibt. Ein kaputtes Prädikat ist das Argument des Aufrufers, also muss die
Zeile mitreisen, die sagt, was stattdessen zu schreiben ist.Bewusst nicht enthalten: Authentifizierung und Rate Limiting (Middleware vor dem Prozess),
Deployment (private Infrastruktur), der Iteration Budget Gate — er begrenzt eine Agenten-Session
und nicht einen Nutzer, weshalb Retrieval von ihm befreit ist; ihn hier als Rate Limiter zu
benutzen würde ihn dazu verwässern.Die Abhängigkeit ist optional (
tools/requirements-mcp.txt): eine Instanz, die nur die CLI
benutzt, soll dafür nicht pydantic, starlette, uvicorn und cryptography installieren müssen. CI
installiert sie, denn ein übersprungener Golden-Test ist genau der Weg, auf dem Server und CLI
unbemerkt auseinanderlaufen.Betrieb und Sync-Mechanismus: instructions/mcp-read-server.md.
Polling (git fetch && git reset --hard) statt Webhook — kein eingehender Endpunkt, keine
Signaturprüfung.reset --hardist dort tragend und keine Bequemlichkeit: ein abgedrifteter Baum
antwortet zwar richtig, parst aber bei jeder Anfrage neu und stempelt jede Antwort mitnull.Dateien:
chemenu/mcp/(neu:server.py,__main__.py),chemenu/api.py,
tools/requirements-mcp.txt(neu),instructions/mcp-read-server.md(neu),tools/CONTRACT.md,
tools/README.md,.gitea/workflows/ci.yml,tests/test_mcp_server.py(neu).Downloads