Projekt-Id in zwei Formen
Data Management braucht die Id mit b.-Präfix, alle Modul-APIs ohne.
Besprechungen bestehen auf einer reinen UUID. container() und
with_prefix() entscheiden das an einer Stelle.
Nur Proof of Concept. Experimenteller MCP-Server aus einem Nebenprojekt. Kein Autodesk-Produkt, kein unterstützter Workflow, keine Produktzusage. Wo ein offizieller Autodesk-MCP die Aufgabe abdeckt, diesen verwenden.
Proof of concept only. Experimental MCP server, built as a side project. Not an Autodesk product, not a supported workflow, no product commitment. Where an official Autodesk MCP covers the job, use that one.
Ein MCP-Server, der Autodesk Forma über natürliche Sprache bedienbar macht. Aufgaben anlegen, Bautagebücher rückdatieren, Nachträge ändern, Objekte pflegen, Nutzer einladen. Alles im Chat, ohne Klickweg durch die Oberfläche.
An MCP server that makes Autodesk Forma operable through natural language. Create issues, backdate daily logs, change change orders, maintain assets, invite users. All from a chat, without clicking through the interface.
Eine Common Data Environment beantwortet normalerweise nur, was man anklickt. Forma-MCP macht sie ansprechbar: Wer im Chat schreibt „leg einen Mangel Brandschottung im 2. Obergeschoss an und weise ihn dem Polier zu“, bekommt keinen Vorschlag, wie er das in der Oberfläche macht. Der Mangel ist danach in Forma.
MCP steht für Model Context Protocol. Es ist die vereinbarte Sprache, in der ein Chat-Modell erfährt, welche Werkzeuge es hat und wie es sie aufruft. Ein MCP-Server meldet beim Start eine Liste von Tools an, jedes mit Namen, Parametern und einer Beschreibung in Prosa. Das Modell liest diese Liste, entscheidet selbst, welches Tool zur Anfrage passt, füllt die Parameter und ruft auf. Der Server macht die eigentliche Arbeit gegen die API und gibt Text zurück.
Der praktische Unterschied zu einem Skript: Ein Skript muss man kennen, finden und mit den richtigen Argumenten starten. Ein Tool beschreibt sich selbst, und das Modell wählt es aus. Genau daran hängt die Qualität der Tool-Beschreibungen. Sie sind kein Kommentar für Entwickler, sie sind die Bedienungsanleitung für das Modell.
Zwei Zwecke, beide aus der Pre-Sales-Arbeit heraus. Erstens: eine Demo-Umgebung aufbauen und lebendig halten. Ein leeres Forma-Projekt überzeugt niemanden, ein Projekt mit Firmen, Nutzern, 150 Objekten, 21 rückdatierten Bautagebüchern, Verträgen und Nachträgen schon. Zweitens: einem Kunden im Gespräch zeigen, was die API hergibt, ohne Folien. Die Frage „geht das auch automatisiert?“ lässt sich mit einem Satz im Chat beantworten statt mit einer Roadmap.
Dasselbe Produkt, umbenannt. Technisch tragen Teile der Schnittstelle noch den alten Namen, weil Autodesk sie nicht mit umbenannt hat. In Texten steht Forma. Das ist kein Fehler.
A common data environment usually only answers what you click on. Forma-MCP makes it conversational: type “create a defect for incomplete fire stopping on level 2 and assign it to the foreman” into the chat and you do not get a suggestion for how to do it in the interface. The defect is in Forma afterwards.
MCP stands for Model Context Protocol. It is the agreed language in which a chat model learns which tools it has and how to call them. An MCP server announces a list of tools at startup, each with a name, parameters and a description in prose. The model reads that list, decides for itself which tool fits the request, fills in the parameters and calls it. The server does the actual work against the API and returns text.
The practical difference from a script: a script has to be known, found and started with the right arguments. A tool describes itself, and the model picks it. That is exactly what the quality of the tool descriptions hangs on. They are not comments for developers, they are the manual for the model.
Two purposes, both grounded in pre-sales work. First, building a demo environment and keeping it alive. An empty Forma project convinces nobody; a project with companies, users, 150 assets, 21 backdated daily logs, contracts and change orders does. Second, showing a customer in conversation what the API is capable of, without slides. The question “can that be automated too?” can be answered with one sentence in a chat rather than with a roadmap.
The same product, renamed. Technically parts of the interface still carry the old name, because Autodesk did not rename them along with the product. Prose says Forma. That is not a mistake.
Der Server läuft als lokaler Prozess auf demselben Rechner wie der Chat-Client. Die Verbindung ist STDIO: Anfragen und Antworten laufen als JSON-RPC über die Standardein- und -ausgabe. Nichts davon geht über das Netz, außer den API-Aufrufen selbst.
The server runs as a local process on the same machine as the chat client. The connection is STDIO: requests and answers travel as JSON-RPC over standard input and output. None of that goes over the network, except the API calls themselves.
core.py den Token der gewünschten
Identität und ruft den passenden APS-Endpunkt. Zurück geht immer Text, nie ein
Objekt. Deshalb liest sich jede Antwort auch ohne Nachbearbeitung.
core.py and calls the matching APS endpoint. What comes back is
always text, never an object. That is why every answer reads well without
post-processing.
core.py abnimmtVier Dinge, die vorher in jedem einzelnen Tool standen und dort jedes Mal neu falsch werden konnten.
Data Management braucht die Id mit b.-Präfix, alle Modul-APIs ohne.
Besprechungen bestehen auf einer reinen UUID. container() und
with_prefix() entscheiden das an einer Stelle.
APS legt den Grund je nach Modul unter detail, message,
errorCode oder in einer errors-Liste ab.
_error_text() sammelt alle vier Stellen ein, statt nur den
Statuscode zu zeigen.
Objekte per Cursor, Data Management über links.next, Kosten und
Aufgaben über offset. api_all() deckt alle drei ab
und bricht ab, sobald eine Seite nichts Neues bringt.
Jeder Aufruf nimmt einen persona-Parameter entgegen und holt
darüber den passenden Token. Ohne das trügen alle Einträge denselben Namen.
core.py takes off your handsFour things that used to sit in every single tool and could go wrong afresh in each one.
Data Management needs the id with the b. prefix, every module API
without it. Meetings insist on a bare UUID. container() and
with_prefix() decide that in one place.
Depending on the module, APS puts the reason under detail,
message, errorCode or in an errors list.
_error_text() collects all four instead of showing the status code
alone.
Assets by cursor, Data Management via links.next, cost and issues
via offset. api_all() covers all three and stops as
soon as a page brings nothing new.
Every call accepts a persona parameter and fetches the matching
token through it. Without that every entry would carry the same name.
99 Tools, davon 46 lesend und 53 schreibend. Vollständige Parameterlisten stehen in der Tool-Referenz, hier steht, wofür die Bereiche gut sind.
Hubs und Projekte auflisten, den Ordnerbaum eines Projekts durchlaufen,
Ordnerberechtigungen lesen und setzen. Die Berechtigungen werden dabei in die sechs
Stufen der deutschen Oberfläche übersetzt, von „Anzeigen“ bis „Verwalten“, statt
roher Aktionslisten wie VIEW, DOWNLOAD, COLLABORATE. Wer eine Rolle
auf Stufe 4 setzt, muss nicht wissen, dass dahinter fünf Einzelaktionen stehen.
list_sheets zeigt die Pläne des Planmoduls mit ihren Ids, das ist
der Eingabewert für einen Pin.
Seit 1.6.0 schreibt der Bereich auch in die Dokumentenablage.
create_folder legt einen Ordner samt fehlender Elternordner an und
lässt sich gefahrlos wiederholen. upload_file lädt eine Datei hoch;
liegt dort schon eine gleichen Namens, wird der Upload ihre nächste Version, wie
beim Ziehen in den Browser. delete_document löscht Dateien und
Ordner, endgültig weg ist dabei nichts: Ein Projektadministrator stellt Gelöschtes
im Browser wieder her. Gelöscht wird nur mit vollem Pfad oder Id, und ein Ordner
direkt unter einem obersten Ordner oder mit mehr als 50 Einträgen braucht dazu
force. Diese drei schreiben nur in Projekten, die unter
FORMA_ADMIN_PROJECTS stehen, derselben Liste wie bei den Admin-Tools.
Ein Transmittal ist die förmliche Übergabe von Dokumenten an benannte Empfänger,
ein Paket die Mappe dahinter, etwa eine Planlieferung mit festen Versionen. Beides
lässt sich lesen: wer wann was an wen geschickt hat, welche Dokumente in welcher
Version und mit welchem Freigabestand dabei waren. Für jede Person hält Forma fest,
wann sie das Transmittal erhalten, zuerst geöffnet und zuerst heruntergeladen hat.
Darauf baut list_open_transmittals auf und beantwortet die Frage, die
nach jeder Übergabe kommt: Wer hat noch nicht reagiert? Ohne Projekt-Id läuft die
Abfrage über alle Projekte der Identität.
Seit 1.7.0 versendet der Server auch. send_transmittal übergibt
Dateien oder ganze Ordner an Projektmitglieder, Rollen oder Firmen, und Forma
benachrichtigt sie per Mail. Empfänger gehen über ihren Namen, und jeder Name
muss genau ein aktives Mitglied, eine Rolle oder eine Firma treffen. Adressen
außerhalb des Projekts lehnt das Tool mit Absicht ab. Von jeder Datei geht die aktuelle
Version mit und bleibt im Transmittal fest. Als Absender steht in Forma die
Persona, die sendet. Pakete lassen sich weiterhin nur lesen, sie entstehen in der
Oberfläche.
Ein Transmittal lässt sich weder ändern noch löschen, und die Mails an die Empfänger sind draußen. Das Senden ist am 05.10.2026 an einem Demoprojekt erprobt, das Verhalten kann sich ohne Ankündigung ändern. Eine Antwort auf ein Transmittal kennt Forma nicht, Reaktion heißt geöffnet oder heruntergeladen.
Ein Freigabeablauf legt fest, wer einen Review startet, wer prüft, wer am Ende
freigibt und wohin freigegebene Dateien kopiert werden.
list_review_workflows zeigt die Abläufe mit Schritten und Beteiligten,
create_review_workflow legt einen neuen an: Prüfer und Freigebende
über Namen von Personen, Rollen oder Firmen, das Kopierziel als Ordnerpfad.
start_review schickt die aktuelle Version einer oder mehrerer Dateien
in einen Ablauf. list_reviews und get_review zeigen, bei
wem ein Review gerade liegt, bis wann, und wie über jede Datei entschieden wurde.
Seit 1.7.0 lässt sich hier auch aufräumen. void_review verwirft einen
offenen Review, archive_reviews nimmt abgeschlossene und verworfene
aus der Liste, update_review_workflow benennt einen Ablauf um oder
nimmt ihn außer Betrieb und holt ihn zurück.
Freigeben und Ablehnen bleibt Sache eines Menschen in der Oberfläche, der Server entscheidet keinen Review. Verwerfen, Archivieren, Umbenennen und Deaktivieren gehen. Diese vier sind am Demoprojekt erprobt, ihr Verhalten kann sich ohne Ankündigung ändern. Archivieren ist endgültig: Die Reviews sieht danach nur noch ein Projektadministrator. Löschen lässt sich weder ein Ablauf noch ein Review.
Anlegen, ändern, löschen, filtern, dazu die Typen und Untertypen des Projekts
auflisten. Ein Untertyp ist beim Anlegen Pflicht, und im Demoprojekt sind die
meisten Typen inaktiv, weshalb create_issue inaktive automatisch
überspringt und einen Namen wie „Brandschutz“ oder „Mangel“ selbst auflöst.
Zuweisen geht an Personen über Namen oder Mailadresse und an Firmen über den
Firmennamen. Ein Pin setzt die Aufgabe an eine Stelle auf einem Plan, entweder
auf ein PDF der Dokumentenablage oder auf einen Plan des Planmoduls. Die Lage
ist ein Wertepaar zwischen 0 und 1 und damit unabhängig von Blattgröße und
Auflösung.
Eine per API angelegte Aufgabe wäre ohne Zutun ein Entwurf, und Entwürfe sieht
außer dem Ersteller niemand, auch kein Projektadministrator.
create_issue setzt published deshalb standardmäßig.
Ein unsichtbarer Mangel nützt in einer Vorführung nichts.
Vorlagen listen, Formulare anlegen, Kopf- und Inhaltsfelder füllen. Der wichtigste
Punkt steckt in create_form: Über das Feld userCreatedAt
lässt sich das Anlegedatum in die Vergangenheit setzen. Das ist der einzige Weg zu
glaubwürdiger Historie in Forma. Bei Aufgaben ist Rückdatierung gesperrt, bei
Formularen nicht. Zwanzig Bautagebücher, die über sechs Wochen verteilt entstanden
zu sein scheinen, machen ein Demoprojekt erst glaubhaft.
Der einzige Bereich, in dem sich auch die Konfiguration anfassen lässt: Kategorien,
Statusgruppen und benutzerdefinierte Felder lassen sich über
list_asset_config lesen und über eigene Tools auch anlegen, samt
Auswahloptionen und automatischer Farbverteilung bei Statusgruppen. Beim Anlegen
eines Objekts genügen Kennung und Kategorie, den Pflicht-Status leitet
create_asset selbst ab. Felder lassen sich über ihren Anzeigenamen
setzen, also Hersteller:Hilti statt ca3:Hilti.
Der Block, der ein leeres Projekt überhaupt erst bevölkert. Nutzer listen und
einladen, Produktzugriffe ändern, Firmen anlegen und ins Projekt holen. Die
unangenehmste Falle steckt eingebaut: Die API ersetzt bei jedem Aufruf die komplette
Produktliste, statt zu ergänzen. update_user liest deshalb den
Ist-Stand, rechnet die Änderung darauf und schickt immer die vollständige Liste.
Dazu kommt der Blick auf das Konto: seine Eckdaten, die Stammdaten eines
Projekts, alle Projekte und Vorlagen, die Rollen und das Mitgliederverzeichnis.
list_projects zeigt nur die Projekte, in denen man Mitglied ist.
list_account_projects zeigt, was ein Kontoadministrator sieht, und
das sind schnell mehrere hundert. list_user_projects beantwortet
die Frage, die vor jedem Austritt steht: In welchen Projekten ist diese Person,
und mit welchen Rechten?
Schreibend reicht der Bereich vom leeren Konto bis zum besetzten Projekt.
create_project legt ein Projekt an, leer oder aus einer Vorlage, und
trägt den Ersteller als Projektadministrator ein, weil ein per API angelegtes
Projekt sonst kein einziges Mitglied hat. import_users lädt das
Team in einem Aufruf ein, mit Firma und Rollen. update_project
ändert die Stammdaten und archiviert. Löschen lässt sich ein Projekt nicht.
Ein Kontoadministrator erreicht jedes Projekt des Kontos, auch die der
Kollegen. Ein falsch verstandener Projektname im Chat würde genügen, um dort
jemanden einzuladen oder zu entfernen. Alle schreibenden Tools dieses Bereichs
arbeiten deshalb nur in Projekten, die in der .env unter
FORMA_ADMIN_PROJECTS stehen: Projekt-Id, voller Name oder
Namensanfang mit *, durch Kommas getrennt. Nicht gesetzt heißt
verweigert. Ein neues Projekt braucht einen Namen, den die Liste deckt.
Personen und Firmen im Konto zu löschen wäre per API möglich, und beides ist nicht gebaut. Die Erlaubnisliste hängt an Projekten. Ein Löschen im Konto träfe jedes Projekt, in dem die Person oder die Firma vorkommt, und davor kann die Liste nicht schützen.
Der größte Bereich. Hauptvertrag mit Wertgliederung, Nachunternehmerverträge,
Budgetzeilen nach DIN 276, alle fünf Nachtragstypen und Abschlagsrechnungen.
Zwei Tools bündeln jeweils mehrere API-Aufrufe: create_cost_item
sucht die Budgetzeile, verknüpft Budget und Vertrag und legt dann erst die Position
an. create_payment legt Abrechnungszeitraum, Zahlung und Positionen in
einem Rutsch an und trägt den Fortschritt ein.
Planungsanfragen sind der einzige Vorgang mit zwei sichtbar Beteiligten: Gefragt
wird von der einen Seite, geantwortet von der anderen. Antworten darf ausschließlich
die zugewiesene Person, weshalb hier der persona-Parameter wirklich
gebraucht wird und nicht nur die Optik verbessert. Besprechungen kommen mit
Teilnehmern und Tagesordnung, beides trägt create_meeting gleich mit
ein. Ohne Teilnehmer wäre die Besprechung für alle außer dem Ersteller unsichtbar.
Seit 1.8.0 trägt ein Tagesordnungspunkt Referenzen. add_meeting_item
legt unter einem Thema einen Eintrag an und verknüpft ihn mit dem, worum es geht:
den Dateien einer Übergabe, der Freigabe, den betroffenen Objekten, einer Aufgabe.
In der Übergabebesprechung von Birgit, Hannes und Simon hängen so die
Revisionsunterlagen, Review #15 und der Bestandsplan C03 direkt am Punkt, und das
Protokoll zeigt auf die Sache, statt sie zu beschreiben. Eine Übertragung selbst
lässt sich in Forma nicht referenzieren; das Tool verknüpft stattdessen ihre
Dokumente und nennt die Übertragung im Text.
Terminpläne (importierte XER-, MPP- oder XML-Dateien) mit ihren Vorgängen lesen und
filtern: kritischer Pfad, Verzug, die nächsten drei Wochen. Arbeitspläne anlegen,
mit einem Terminplan verbinden und mit Aufgaben füllen, die einem Vorgang folgen;
Aufgaben zuweisen, zusagen, kommentieren, ändern, löschen. Zurück in den
Terminplan führt ein Update Request, der Vorschlag an den Terminplaner.
fill_workplan_from_schedule macht daraus einen Satz: die Vorgänge der
kommenden Wochen als Aufgaben, wiederholbar ohne Dubletten.
Am Demoprojekt erprobt, das Verhalten kann sich ändern.
Eine API verbindet Objekte über Modulgrenzen hinweg: eine Aufgabe mit einem Foto,
ein Objekt mit einem Dokument, einen Nachtrag mit einer Planungsanfrage. In Forma
erscheinen diese Verknüpfungen als „Referenzen“ am jeweiligen Eintrag. Suchen,
anlegen, löschen, dazu die Matrix der erlaubten Paare und ein Sync-Mechanismus für
externe Ablagen. Adressiert wird mit Kurznamen wie issue oder
photo; die sperrigen Domain-Namen der API bleiben unter der Haube.
Die Standortgliederung als Baum mit Barcodes. Mengenpakete samt Import von DIN 276
und Geschossgliederung. Und forma_request, ein bewusst grobes
Werkzeug: Es fragt jeden beliebigen APS-Endpunkt lesend ab, mit Kürzeln für die
Modulwurzeln und einer Tiefenbegrenzung, damit eine Antwort mit 200 Einträgen den
Kontext nicht flutet. Damit lassen sich neue Endpunkte im Gespräch erkunden, ohne
vorher ein Skript zu schreiben. Dazu list_personas: die
eingerichteten Identitäten samt Standard-Persona.
99 tools, 46 of them reading and 53 writing. Full parameter lists live in the tool reference; this section says what the areas are good for.
List hubs and projects, walk a project’s folder tree, read and set folder
permissions. Permissions are translated into the six levels of the interface, from
“view” to “manage”, instead of raw action lists such as
VIEW, DOWNLOAD, COLLABORATE. Setting a role to level 4 does not
require knowing that five individual actions sit behind it.
list_sheets shows the sheets of the sheets module with their ids,
which is the input for a pin.
Since 1.6.0 the area also writes into the document store.
create_folder creates a folder along with any missing parents and can
be repeated safely. upload_file uploads a file; if one of the same
name is already there, the upload becomes its next version, as with a drag and
drop in the browser. delete_document deletes files and folders, and
nothing is gone for good: a project administrator restores deleted items in the
browser. Deleting takes the full path or an id, and a folder directly below a
top folder or with more than 50 entries needs force on top. These
three only write in projects listed under
FORMA_ADMIN_PROJECTS, the same list the admin tools use.
A transmittal is the formal handover of documents to named recipients, a package
the folder behind it, such as a drawing issue with fixed versions. Both can be
read: who sent what to whom and when, which documents went along in which version
and with which approval state. For every person Forma records when they received
the transmittal, first opened it and first downloaded it.
list_open_transmittals builds on that and answers the question that
follows every handover: who has not reacted yet? Without a project id it runs
across every project of the identity.
Since 1.7.0 the server sends as well. send_transmittal hands files or
whole folders to project members, roles or companies, and Forma notifies them by
mail. Recipients go in by name, and each name has to match exactly one active
member, one role or one company; addresses outside the project are refused on
purpose. The current version of each file goes along and stays fixed in the
transmittal. The sender shown in Forma is the persona that sends. Packages can
still only be read; they are built in the interface.
A transmittal can be neither changed nor deleted, and the mails to the recipients are out. Sending was tested on a demo project on 5 Oct 2026; the behaviour may change without notice. Forma knows no reply to a transmittal, a reaction means opened or downloaded.
An approval workflow sets who starts a review, who checks, who approves at the end
and where approved files are copied to. list_review_workflows shows
the workflows with their steps and participants, create_review_workflow
creates a new one: reviewers and approvers by the names of people, roles or
companies, the copy target as a folder path. start_review sends the
current version of one or more files into a workflow. list_reviews and
get_review show whose desk a review is on, until when, and what was
decided on each file.
Since 1.7.0 the area can tidy up as well. void_review voids an open
review, archive_reviews takes closed and voided ones off the list,
update_review_workflow renames a workflow or takes it out of use and
brings it back.
Approving and rejecting stay with a person in the interface; the server decides no review. Voiding, archiving, renaming and deactivating work. Those four are tested on a demo project; their behaviour may change without notice. Archiving is final: afterwards only a project administrator sees the reviews. Neither a workflow nor a review can be deleted.
Create, update, delete, filter, plus listing the project’s types and subtypes. A
subtype is mandatory when creating, and in the demo project most types are inactive,
which is why create_issue skips inactive ones automatically and
resolves a name such as “Brandschutz” or “Mangel” by itself. Assignment works
for people by name or email address and for companies by company name. A pin puts
the issue at a place on a plan, either on a PDF in the document store or on a
sheet in the sheets module. The position is a pair of values between 0 and 1 and
therefore independent of sheet size and resolution.
An issue created through the API would be a draft by default, and nobody sees a
draft except its creator, not even a project administrator.
create_issue therefore sets published as standard. An
invisible defect is of no use in a demo.
List templates, create forms, fill header and content fields. The crucial point
sits inside create_form: the field userCreatedAt lets you
push the creation date into the past. That is the only route to believable history
in Forma. For issues backdating is blocked, for forms it is not. Twenty daily logs
that appear to have been written across six weeks are what makes a demo project
credible in the first place.
The only area where the configuration can be touched as well: categories, status
sets and custom fields can be read through list_asset_config and
created through tools of their own, pick-list options and automatic colour spread
included. To create an asset, an identifier and a category suffice;
create_asset derives the mandatory status itself. Fields can be set
by display name, so Hersteller:Hilti rather than
ca3:Hilti.
The block that populates an empty project in the first place. List and invite
users, change product access, create companies and add them to the project. The
nastiest pitfall is built in: the API replaces the entire product list on every
call instead of merging. update_user therefore reads the current
state, applies the change to it and always sends the complete list.
On top of that comes the view of the account: its key data, a project’s master
data, every project and template, the roles and the member directory.
list_projects only shows the projects you are a member of.
list_account_projects shows what an account administrator sees,
and that quickly runs into the hundreds. list_user_projects
answers the question that comes up before anybody leaves: which projects is
this person in, and with which rights?
On the writing side the area reaches from an empty account to a staffed
project. create_project creates a project, empty or from a
template, and puts its maker in as project administrator, because a project
made through the API has no members at all otherwise.
import_users invites the team in one call, with company and
roles. update_project changes the master data and archives. A
project cannot be deleted.
An account administrator reaches every project of the account, colleagues’
projects included. One misheard project name in a chat would be enough to
invite or remove somebody there. Every writing tool of this area therefore
only works in projects listed in .env under
FORMA_ADMIN_PROJECTS: project id, full name, or the start of a
name followed by *, separated by commas. Not set means refused.
A new project needs a name the list covers.
Deleting people and companies in the account would be possible through the API, and neither is built. The allowlist is tied to projects. A deletion in the account would hit every project the person or the company appears in, and the list cannot protect against that.
The largest area. Main contract with schedule of values, subcontracts, budget lines
by DIN 276, all five change order types and payment applications. Two tools bundle
several API calls each: create_cost_item finds the budget line, links
budget and contract and only then creates the item. create_payment
creates the billing period, the payment and the items in one go and records
progress.
RFIs are the only process with two visibly involved parties: one side asks, the
other answers. Only the assigned person may answer, which is why the
persona parameter is genuinely needed here rather than merely
cosmetic. Meetings come with participants and an agenda, both of which
create_meeting adds straight away. Without participants the meeting
would be invisible to everyone but its creator.
Since 1.8.0 an agenda item carries references. add_meeting_item adds
an item under a topic and links it to what it is about: the files of a handover,
the approval, the affected assets, an issue. In the handover meeting of Birgit,
Hannes and Simon the as-built documents, review #15 and the as-built plan C03 hang
on the item itself, and the minutes point at the objects instead of describing
them. A transmittal itself cannot be referenced in Forma; the tool links its
documents instead and names the transmittal in the text.
Read and filter schedules (imported XER, MPP or XML files) and their activities:
critical path, delays, the next three weeks. Create work plans, connect them to a
schedule and fill them with tasks that follow an activity; assign, commit, comment,
update and delete tasks. The way back into the schedule is an update request, the
suggestion put in front of the scheduler.
fill_workplan_from_schedule turns that into one sentence: the
activities of the coming weeks as tasks, repeatable without duplicates.
Tested on a demo project; the behaviour may change.
One API connects objects across module boundaries: an issue with a photo, an asset
with a document, a change order with an RFI. In Forma these links appear as
“references” on the entry. Search, create, delete, plus the matrix of allowed
pairs and a sync mechanism for external stores. Addressing works through short
names such as issue or photo; the unwieldy domain names
of the API stay under the hood.
The location breakdown as a tree with barcodes. Takeoff packages including an
import of DIN 276 and a storey breakdown. And forma_request, a
deliberately coarse instrument: it queries any APS endpoint read-only, with
shorthands for the module roots and a depth limit so that an answer holding 200
entries does not flood the context. It makes exploring new endpoints possible mid
conversation, without writing a script first. Plus list_personas: the configured
identities with the default persona.
In einem Demoprojekt steht an jedem Eintrag ein Name. Legt ein einziger Zugang alles an, tragen zwanzig Bautagebücher, alle Mängel und sämtliche Planungsanfragen denselben Namen. Das fällt in einer Vorführung sofort auf und zerstört die Glaubwürdigkeit der Umgebung.
Deshalb gibt es sechs 3-legged-Identitäten, jede mit eigener Token-Datei. Alle
schreibenden Tools nehmen einen persona-Parameter entgegen, Vorgabe ist
default. Wer ein Bautagebuch als Bauleitung anlegen will, übergibt
deren Kurznamen als persona, und in Forma steht danach dieser Name.
| Persona | Token-Datei | Rolle in der Demo-Umgebung |
|---|---|---|
default | refresh_token.txt | Standard-Identität, erweiterte Scopes |
<kurzname> | refresh_token_<kurzname>.txt | je eine Identität pro Rolle, z. B. Architektur, Bauleitung, Polier |
Die Identität steuert nicht nur die Optik. Bei Planungsanfragen darf ausschließlich die zugewiesene Person antworten, alle anderen lehnt Forma ab, auch Projektadministratoren. Entwürfe von Aufgaben und Planungsanfragen sind ebenfalls nur für ihren Ersteller sichtbar. Wer einen gerade angelegten Entwurf sucht und nicht findet, hat meist nur die falsche Identität benutzt.
In a demo project every entry carries a name. If a single account creates everything, twenty daily logs, all defects and every RFI carry the same name. That is noticed immediately in a demo and destroys the credibility of the environment.
Hence six three-legged identities, each with its own token file. All writing tools
accept a persona parameter, defaulting to default. To
create a daily log as site management you pass that persona’s short name, and
their name is what appears in Forma.
| Persona | Token file | Role in the demo environment |
|---|---|---|
default | refresh_token.txt | Default identity, extended scopes |
<shortname> | refresh_token_<shortname>.txt | one identity per role, e.g. architecture, site management, foreman |
The identity governs more than appearances. On an RFI only the assigned person may answer, Forma refuses everyone else, even a project administrator. Drafts of issues and RFIs are likewise visible only to their creator. If you look for a draft you just created and cannot find it, you usually just used the wrong identity.
Aus 145 dokumentierten Punkten die, die beim Benutzen des Servers wirklich beißen.
b.-Präfix
Data Management verlangt die Projekt-Id mit Präfix, alle Modul-APIs ohne, und
Besprechungen bestehen auf einer reinen UUID. Der falsche Zuschnitt gibt eine Fehlermeldung, die exakt aussieht wie ein
fehlendes Recht oder eine falsche Id. Der Server nimmt das ab, aber wer
forma_request mit freiem Pfad benutzt, muss es wissen.
Aufgaben und Planungsanfragen entstehen ohne Zutun als Entwurf, und ein Entwurf
taucht bei jedem anderen weder in der Liste auf noch beim Einzelabruf. Der
Einzelabruf wird abgelehnt. Bei Aufgaben umgeht create_issue das durch
sofortiges Veröffentlichen, bei Planungsanfragen ist es nicht umgehbar, siehe
Abschnitt 9.
Ein rückdatiertes Formular trägt das gewünschte Datum in userCreatedAt.
Das technische createdAt bleibt der echte Zeitstempel und ist nicht
rücksetzbar. Wer nach dem Anlegen createdAt prüft, hält die
Rückdatierung fälschlicherweise für gescheitert.
Jede Identität sieht unterschiedlich viele Formularvorlagen, und eine Vorlage in der Liste zu sehen bedeutet nicht, darin anlegen zu dürfen. Vor dem Anlegen also nachsehen, wer die bestehenden Einträge derselben Vorlage geschrieben hat, und dieselbe Identität nehmen.
| Objekt | Verhalten |
|---|---|
| Aufgabe | Soft-Delete. Verschwindet aus Liste und Oberfläche, bleibt über die Id mit deleted: true abrufbar. Ein zweites Löschen schlägt fehl |
| Objekt | Hard-Delete, danach nicht mehr abrufbar. Braucht Administratorrechte, der Ersteller allein darf nicht |
| Planungsanfrage | Nicht löschbar. Bereinigen über Status void |
| Formular | Nicht löschbar. Skripte deshalb idempotent bauen, also vorhandenes Datum vorher abfragen |
| Mengenpaket | Nicht löschbar |
| Projekt | Nicht löschbar. Archivieren über update_project, lässt sich zurückholen |
| Projektnutzer | Entfernen wirkt im Projekt sofort. Im Konto bleibt der Eintrag stehen, bei Personen ohne weiteres Projekt mit Status not_invited |
| Firma | Löschbar auf beiden Ebenen. Achtung: Firmen entstehen im gesamten Konto, nicht im Projekt |
invite_user löst eine Einladungsmail aus, die sich nicht zurückholen
lässt. Der Nutzer lässt sich danach zwar wieder aus dem Projekt entfernen, die Mail
ist trotzdem draußen. Vor dem Einsatz in einer Live-Umgebung die Adresse zweimal
lesen.
Out of 145 documented points, the ones that actually bite while using the server.
b. prefix
Data Management requires the project id with the prefix, every module API without
it, and meetings insist on a bare UUID. The wrong shape returns an error that looks exactly like a missing permission or
a wrong id. The server handles this, but anyone using forma_request
with a free-form path needs to know.
Issues and RFIs are created as drafts by default, and for everyone else a draft
appears neither in the list nor on a direct fetch. The direct fetch is refused.
For issues create_issue works around this by publishing immediately;
for RFIs there is no way around it, see section 9.
A backdated form carries the intended date in userCreatedAt. The
technical createdAt remains the real timestamp and cannot be reset.
Checking createdAt after creating makes the backdate look like it
failed.
Each identity sees a different number of form templates, and seeing a template in the list does not mean being allowed to create in it. So before creating, check who wrote the existing entries of that template and use the same identity.
| Object | Behaviour |
|---|---|
| Issue | Soft delete. Disappears from list and interface, stays retrievable by id with deleted: true. A second delete fails |
| Asset | Hard delete, gone afterwards. Needs administrator rights; the creator alone is not allowed |
| RFI | Cannot be deleted. Clean up via status void |
| Form | Cannot be deleted. Build scripts idempotently, that is, query the existing date first |
| Takeoff package | Cannot be deleted |
| Project | Cannot be deleted. Archive through update_project; it can be undone |
| Project user | Removal takes effect in the project immediately. The entry stays in the account, for people without another project in status not_invited |
| Company | Deletable at both levels. Careful: companies are created account-wide, not in the project |
invite_user triggers an invitation email that cannot be recalled. The
user can be removed from the project afterwards, but the email is out regardless.
Before using this against a live environment, read the address twice.
Eine Anfrage entsteht immer als Entwurf. Der Wechsel auf open wird abgelehnt,
auch wenn die Pflichtattribute mitgeschickt werden. Vermutlich darf nur der
zugewiesene Manager den Übergang auslösen, und wie der gesetzt wird, ist offen.
Anfragen lassen sich also anlegen und beantworten, aber nicht regulär stellen.
Die Suche nach Verknüpfungen antwortet ohne Fehler, aber mit
null Treffern, vermutlich fehlen Pflichtparameter. Dateiversionen ließen sich
mangels Dateien in den oberen Ordnerebenen nicht gegen echte Daten prüfen. Bewusst
kein Tool gebaut. Zum Erkunden forma_request nutzen.
createdAt, openedAt und closedAt sind
gesperrte Migrationsfelder, jeder Versuch wird abgelehnt. Zeitlichkeit nur über
startDate und dueDate. Bei Formularen geht
Rückdatierung, bei Aufgaben nicht.
Die Photos-API ist endgültig als lesend bestätigt. Am Issue steht in den
erlaubten Aktionen ein add_attachment, der Endpunkt dahinter ist
unbekannt. Das bleibt der aussichtsreichste Weg zu Mängeln mit Bild.
Arbeitszeit, Material und Gerät im Bautagebuch lassen sich lesen, aber nicht schreiben. Lese- und Schreibschema unterscheiden sich, jedes naheliegende Feld gibt „Unknown field“. Nach mehreren Versuchen aufgegeben. Eigene benutzerdefinierte Felder funktionieren dagegen zuverlässig.
Der Wechsel von Entwurf über eingereicht zu genehmigt ist nicht per API setzbar, auch nicht mit Administratorrechten. Die Zeitstempel lassen sich setzen, ändern aber den Status nicht. Muss in der Oberfläche passieren.
Kommt aus einem Wetterdienst und ist nicht überschreibbar. Es wird zudem für den echten Anlegezeitpunkt gefüllt, nicht für das rückdatierte Datum. Ein rückdatiertes Bautagebuch zeigt also das Wetter von heute. Wetterangaben gehören deshalb in den Notiztext.
Der Endpunkt existiert, jeder Schreibversuch scheitert mit demselben Fehler, auch mit gültigen Ids. Vermutlich braucht das Feature eine Konfiguration in der Oberfläche, die per API nicht setzbar ist. Behelf: als Nachtrag mit reinem Budget-Bezug abbilden.
Eine Linie, die sich quer durch alle Module zieht: Daten sind schreibbar, Konfiguration meist nicht. Budgets, Verträge, Positionen, Nachträge und Ausgaben lassen sich per API anlegen. Der Budget-Code-Aufbau, Begriffe, Steuer, Währung, Einbehalt, Vertragstypen und die Firmeneinrichtung dagegen nicht. Die einzige Ausnahme sind Objekte: Kategorien, Status, Statusgruppen und benutzerdefinierte Felder lassen sich dort tatsächlich per API bauen. Für das Aufsetzen einer Demo-Umgebung aus dem Nichts ist das der wertvollste Block überhaupt. Freigabeabläufe lassen sich anlegen, umbenennen und deaktivieren, aber nicht löschen. Schritte und Beteiligte ändert man in der Oberfläche.
Vier Module sind laut Dokumentation machbar und trotzdem nicht gebaut, weil keines davon heute einen Anlass in einer Demo hat. Geholt wird erst, wenn ein Kundengespräch danach fragt.
| Modul | Warum draußen |
|---|---|
| Submittals | Elf Endpunkte, für Generalunternehmer ein starkes Thema. Bisher blinder Fleck, der erste Kandidat für einen Ausbau |
| Data Connector | Massenexport von Projektdaten. Interessant für Auswertungen, nicht für eine Vorführung |
| Webhooks | Ereignisse statt Abfragen. Erst relevant bei einer echten Integration, nicht bei einem Demo-Werkzeug |
| Model Coordination | Ohne Bezug zu den aktuellen Demo-Themen |
An RFI is always created as a draft. Moving it to open is refused,
even when the mandatory attributes are sent along. Presumably only
the assigned manager may trigger the transition, and how that manager is set is
unresolved. RFIs can therefore be created and answered, but not formally raised.
The relationship search answers without an error but with zero hits,
presumably missing mandatory parameters. File versions could not be tested against real
data because the upper folder levels hold no files. Deliberately no tool built. Use
forma_request to explore.
createdAt, openedAt and closedAt are
locked migration fields; every attempt is refused. Timing only through
startDate and dueDate. Forms allow backdating, issues do
not.
The photos API is confirmed read-only for good. The issue’s permitted actions
list an add_attachment, but the endpoint behind it is unknown. That
remains the most promising route to defects with images.
Labour, materials and equipment in the daily log can be read but not written. Read and write schemas differ, and every obvious field returns “Unknown field”. Abandoned after several attempts. Custom fields of your own, by contrast, work reliably.
The move from draft through submitted to approved cannot be set through the API, not even with administrator rights. The timestamps can be set but do not change the status. It has to happen in the interface.
Comes from a weather service and cannot be overwritten. It is also filled for the real creation time, not for the backdated date. A backdated daily log therefore shows today’s weather. Weather information belongs in the notes text.
The endpoint exists, every write attempt fails with the same error, even with valid ids. Presumably the feature needs a setting in the interface that cannot be set through the API. Workaround: model it as a change order with budget-only scope.
One line runs through every module: data is writable, configuration mostly is not. Budgets, contracts, items, change orders and expenses can be created through the API. The budget code scheme, terminology, tax, currency, retention, contract types and company setup cannot. The single exception is assets: categories, statuses, status sets and custom fields really can be built through the API there. For setting up a demo environment from nothing, that is the most valuable block of all. Approval workflows can be created, renamed and deactivated, but not deleted. Their steps and people are changed in the interface.
Four modules are feasible according to the documentation and still not built, because none of them has an occasion in a demo today. They get picked up when a customer conversation asks for them.
| Module | Why it is out |
|---|---|
| Submittals | Eleven endpoints, a strong topic for main contractors. A blind spot so far, and the first candidate for an expansion |
| Data Connector | Bulk export of project data. Interesting for analysis, not for a demo |
| Webhooks | Events instead of polling. Only relevant for a real integration, not for a demo instrument |
| Model Coordination | No bearing on the current demo topics |
Alle 99 Tools mit Parametern, Fallen und einem Beispielsatz, der sie auslöst.
project_id nimmt jedes Tool mit oder ohne b.-Präfix
entgegen, der Server setzt die richtige Form selbst. Alle schreibenden Tools
nehmen zusätzlich persona, Vorgabe default; die
übrigen Kurznamen zeigt list_personas. Einige lesende Tools haben ihn ebenfalls, etwa weil Entwürfe nur ihr
Ersteller sieht.
All 99 tools, with parameters, pitfalls and a sample sentence that triggers each
one. Every tool accepts project_id with or without the
b. prefix; the server normalises it. All writing tools also take
persona, defaulting to default; the
remaining short names come from list_personas. A few reading tools have it as well, for example because drafts are visible
only to their creator.