3. Mit einem KI-Agenten
freemapper-print bringt einen MCP-Server mit. Ein KI-Agent wie Claude Code kann darüber ein Projekt lesen und prüfen, Abdeckungen, Postennummern, Layouts und Blattelemente in die Projektdatei schreiben und die PDFs erzeugen. Sie sagen dem Agenten in eigenen Worten, was Sie brauchen, etwa „Mach aus dem Training einen Fenster-OL mit 12-mm-Fenstern“, und er ruft die passenden Werkzeuge auf. Der Server ruft selbst kein Sprachmodell auf. Er tut dasselbe wie die Befehle der Kommandozeile und liefert dieselben Meldungen.
Einrichten
freemapper-print mcp startet den Server. Er liest Anfragen von der Standardeingabe und antwortet auf der Standardausgabe, bis der Agent die Verbindung schließt. Von Hand starten Sie ihn nicht, das übernimmt das Programm des Agenten. Für Claude Code legen Sie eine Datei .mcp.json in den Ordner, in dem Sie Claude Code starten, zum Beispiel den Ordner mit Ihren Veranstaltungen:
{
"mcpServers": {
"freemapper-print": {
"command": "/home/user/bin/freemapper-print",
"args": ["--lang", "de", "mcp"]
}
}
}
Bei command steht der absolute Pfad zum Programm, dort, wohin Sie es entpackt haben (README, Abschnitt „Installation“). Unter Windows lautet er etwa C:\\Users\\name\\freemapper-print\\freemapper-print.exe, mit doppelten Backslashes, weil die Datei JSON ist. --lang de wählt deutsche Meldungen; ohne die Option gilt die Sprache des Systems wie bei der Kommandozeile. Nach dem nächsten Start von Claude Code zeigt /mcp den Server mit seinen dreizehn Werkzeugen.
Einrichten lassen
Ein Agent, der Befehle ausführen kann, etwa Claude Code oder Codex, übernimmt auch das Herunterladen, das Prüfen, das Entpacken und die Anmeldung des Servers. Er richtet sich nach der Datei AGENTS.md, die im Archiv neben dem Programm liegt. Sie sagen ihm zum Beispiel: „Lies AGENTS.md von github.com/HenryJobst/freemapper-print und richte freemapper-print ein.“ Unter macOS hebt er dabei die Sperre für nicht signierte Programme auf und sagt Ihnen das. Je nach Einstellung fragt er vor jedem Befehl nach. Claude Desktop führt keine Befehle aus; dort melden Sie den Server selbst an, wie oben beschrieben.
Die Werkzeuge
Jedes Werkzeug nimmt dazu lang ("de" oder "en"), um für diesen einen Aufruf eine andere Sprache zu wählen. project ist der Projektordner oder die Datei freemapper-print.toml darin.
| Werkzeug | Entspricht | Pflichtangaben | Weitere Angaben | Ergebnis |
|---|---|---|---|---|
project_info | project | Titel, Kartenart und -maßstab, Karte und Bahndatei, Layouts mit ihren Elementen, Bahnen mit Layout und Abdeckungen, die Abdeckungen und die Zuordnungen | ||
check_project | check | project | die Hinweise jedes Blatts mit kind, severity (info, warning, error), course und message; needs_attention ist wahr, wenn check mit Exit-Code 1 enden würde | |
list_courses | project | die Bahnen der Bahndatei mit Postenzahl, Layout und Abdeckungen | ||
init_project | init | folder, map | title, kind, courses | die geschriebenen Layouts, woher die Kartenart stammt, und die Meldungen von init |
masks_window | masks window | project, course | controls, radius, radius_for, gap, no_start, no_finish, id, assign | die ID der Abdeckung, die Fenster und die Meldungen |
masks_corridor | masks corridor | project, points | width, id, assign, course | die ID der Abdeckung und die Meldungen |
numbers_accept | numbers accept | project, course, control, scope (sheet oder layout_wide) | direction und gap, nur zusammen | die eingetragene Korrektur und die Meldung |
set_layout | project, id | paper, page_mm, orientation, print_scale, centre_map_mm, margin_mm, border_mm, crop, north_lines, hide_parts, hide_shared | das Layout, wie es jetzt in der Datei steht, und change | |
set_element | project, id, kind, anchor | layout, lines, size_pt, box_white, file, width_mm, cell_mm | das Element und change | |
assign_mask | project, course | mask, layout | die Zuordnung und change | |
export_project | export | project, out_dir | courses, layouts, single_file | die geschriebenen PDFs mit Größe, die Hinweise der Blätter und die Erinnerung, in Originalgröße zu drucken |
check_update | update --check | ob es eine neuere Version gibt, mit den Versionsnummern und den Versionshinweisen | ||
install_update | update --yes | confirm | Installiert nur mit confirm auf true; ohne gibt das Werkzeug einen Fehler zurück. Installiert das neueste Release und sagt, dass der laufende Server die alte Version behält, bis er neu gestartet wird |
Die Eingaben heißen wie die Optionen der Befehle (Kapitel 5, 8 und 11) und die Schlüssel der Projektdatei (Kapitel 6 und 7), nur mit Unterstrich: radius_for statt --radius-for, points als Text "x,y;x,y" wie bei --points. change sagt, ob das Werkzeug etwas hinzugefügt (added), geändert (changed) oder nichts zu tun hatte (unchanged).
set_layout ändert nur die Schlüssel, die der Aufruf nennt; die übrigen behalten ihren Wert, ein neues Layout bekommt für sie die Vorgaben. null bei print_scale druckt wieder im Kartenmaßstab, bei centre_map_mm zentriert es den Ausschnitt wieder. Die Elemente eines Layouts ändert nur set_element. Es ersetzt das Element mit derselben ID ganz; ohne layout gilt es für alle Layouts ([[shared]]). Ein Logo nennt file mit absolutem Pfad, die Projektdatei speichert ihn relativ zu sich. assign_mask setzt die Abdeckung einer Bahn, auch wenn sie schon eine hat; ohne mask druckt die Bahn ohne Abdeckung. masks_window und masks_corridor mit assign ersetzen dagegen keine Abdeckung.
check_update und install_update brauchen kein project. check_update sagt, ob es eine neuere Version gibt. install_update installiert sie nur mit confirm auf true; ohne liefert es „Es wurde nichts installiert. Fragen Sie zuerst die Person und rufen Sie install_update erst nach ihrer Zustimmung mit confirm: true auf.“ Das erste Ergebnis einer Server-Sitzung trägt einen Hinweis, wenn es eine neuere Version gibt. Der Agent gibt ihn weiter und fragt Sie, bevor er installiert. Ein Server läuft nach einer Installation mit der alten Version weiter, bis der Assistent ihn neu startet.
Die Ergebnisse sind JSON. Die Werkzeuge, die schreiben, geben in messages dieselben Sätze zurück, die der Befehl in der Kommandozeile ausgibt. Wo der Befehl eine Option nennt, nennt der Server das Werkzeug und die Eingabe: „Mit check_project sehen Sie das Ergebnis“ statt „Mit check sehen Sie das Ergebnis“.
Regeln
- Alle Pfade sind absolut. Der Server kennt den Arbeitsordner des Agenten nicht, deshalb lehnt er einen relativen Pfad mit einer Meldung ab, die genau das sagt.
~zählt als relativ. - Geht etwas schief, kommt die Meldung zurück, die auch die Kommandozeile ausgeben würde, und die Projektdatei bleibt, wie sie war. Die Werkzeuge, die Layouts, Elemente und Zuordnungen ändern, prüfen die geänderte Datei, bevor sie sie schreiben. Scheitert ein Export an einem Blatt, bleiben die PDFs davor stehen, und die Meldung nennt sie.
- Eine Eingabe, die das Werkzeug nicht kennt, ist ein Fehler, der sie nennt. Ein Tippfehler wie
print_scalgeht so nicht als Aufruf durch, der nichts geändert hat. - Schreiben geht der Reihe nach. Alle Werkzeuge, die schreiben, und
export_projectwarten aufeinander, auch wenn der Agent mehrere zugleich aufruft. So sieht jeder Aufruf, was der vorige geschrieben hat.project_info,check_projectundlist_courseswarten nicht. - Kommentare in der Projektdatei bleiben stehen, mit drei Ausnahmen. Ändert sich der Wert eines Schlüssels, bekommt er eine neue Zeile. Ein Kommentar am Ende dieser Zeile geht dabei verloren, ebenso einer in einem Wert über mehrere Zeilen, etwa zwischen den Einträgen von
lines = [ … ]. Eine Untertabelle wie[layouts.map_frame]oder[layouts.elements.anchor]wird zu einer Zeile in der kurzen Formmap_frame = { … }. Die Kommentarzeilen über und in ihr wandern über diese Zeile, Kommentare am Ende ihrer Zeilen gehen verloren. Fällt der Schlüssel dagegen weg, gehen seine Kommentare mit. Eine neue Zeile verliert außerdem die Einrückung der alten. - Ist die Projektdatei ein Link, ändert der Server sie nicht und sagt das. Die Kommandozeile ersetzt den Link in diesem Fall durch eine Datei, was ein Agent nicht bemerken würde. Ein Projektordner, der ein Link ist, ist dagegen kein Problem.
export_projectschreibt inout_dir, einen Ordner, den es schon gibt. Ein PDF gleichen Namens dort ersetzt es.layoutsgeht nicht zusammen mitcoursesodersingle_file.- Die Ergebnisse bleiben auch bei großen Bahndateien klein.
export_projectnennt höchstens 200 Dateien,check_project200 Blätter,project_info200 Bahnen, Abdeckungen und Zuordnungen,list_courses200 Bahnen undinit_project200 Bahnnamen über alle Layouts.check_projectundexport_projectgeben höchstens 200 Hinweise zurück.more_files,more_sheets,more_courses,more_masks,more_assignmentsundmorezählen den Rest.needs_attentiongilt für alle Blätter, auch die weggelassenen, undmore_sheets_needing_attentionzählt die weggelassenen Blätter, die einen Blick brauchen. - Abbrechen lässt sich nur
export_project. Bricht der Agent den Aufruf ab, endet der Export nach dem Blatt, an dem er gerade zeichnet. Die PDFs davor bleiben ganz, eine halbe Datei bleibt nicht zurück. Mitsingle_fileentsteht dann gar kein PDF. Schließt der Agent die Verbindung, zeichnet der Server noch bis zu fünf Sekunden weiter und endet dann ebenso. Die anderen Werkzeuge laufen bis zum Ende. Das dauert beicheck_projectmit einer sehr großen Bahndatei (1000 Bahnen mit je 200 Posten) knapp zwei Minuten. Ein Werkzeug, das schreibt und abgebrochen wird, während es auf einen anderen Schreibvorgang wartet, ändert nichts. Das Schließen der Verbindung zählt als Abbruch: Ein Schreibaufruf, den der Agent kurz davor schickt, kann ausbleiben. Nach so einer Sitzung zeigtproject_info, was in der Datei steht. - Die Standardausgabe gehört dem Protokoll. Fehler des Servers selbst stehen auf der Standardfehlerausgabe.
Was kein Werkzeug ändert, etwa [event], [print] oder eine vorhandene Korrektur unter [[numbers]], ändert der Agent mit seinen eigenen Mitteln in der Datei, oder Sie tun es selbst. check_project zeigt danach, ob die Datei noch stimmt.
Ein Beispiel
Das Beispiel examples/rummelsburg-mcp-session zeichnet eine echte Sitzung auf. Die Bitte an den Agenten lautet sinngemäß: „Mach daraus einen Fenster-OL mit Fenstern von 12 mm und leg das PDF in den Ordner out.“ Karte und Bahn T (8 Posten, 2,0 km) liegen schon im Ordner.
init_projectlegt das Projekt aus Karte und Bahndatei an, mitkind„sprint“. Das Ergebnis meldet ein Layouta4-4000mit der Bahn „T“, undfitsist falsch: Kein Blatt zeigt die ganze Karte.check_projectmeldet drei Warnungen,needs_attentionist wahr. Auf dem A4-Blatt überdeckt der Titelblock den Start, die Nummer von Posten 31 überdeckt das Liniensymbol 520.1 der Karte, und auf jedem Blatt steht der Hinweis, dass die Schrift Arimo Calibri ersetzt.set_layoutstellt das Layout auf A3 um. Der Layoutnamea4-4000bleibt, dennset_layoutbenennt nichts um.masks_windowmitcourse„T“,radius12 undassignschreibt die Abdeckungwindow-Tmit zehn Fenstern um Start, die Posten 31 bis 38 und Ziel und gibt sie der Bahn. Kein Fenster wird kleiner, denn keine zwei Punkte der Bahn liegen näher als 134 m.check_projectmeldet die Warnung zum Titelblock nicht mehr. Es bleiben die Schrift und die Nummer von Posten 31, deshalb istneeds_attentionweiter wahr. Der Agent exportiert trotzdem.export_projectschreibtT.pdf(1 091 820 Byte, A3 quer, 1:4000) und erinnert daran, in Originalgröße zu drucken.
Die Sitzung lief mit einem Stand nach Version 0.8.0, der den Abstand zwischen Fenstern schon hält (ADR 0063).