MCP-Server
Basalt bringt einen hauseigenen MCP-Server mit. Damit kann ein Assistent — Claude, eine Agenten-CLI, alles, was das Protokoll spricht — einen Workspace lesen und beschreiben, ohne dass jemand Klebecode schreiben muss.
Es gibt nichts zu installieren. Der Server läuft auf Ihrer Basalt-Instanz und
antwortet unter https://app.basaltapp.io/mcp; Sie richten den Assistenten auf
diese Adresse und geben ihm ein Token.
Er ist eine dünne Schicht über der öffentlichen API: Der Endpunkt hat keine eigene Rechtelogik, sondern stellt gewöhnliche API-Anfragen mit Ihrem Zugangsdatum. Ein Assistent sieht und ändert damit genau das, was Sie können. Seiten gehen als kanonisches Markdown über die Leitung.
Einrichten
Zuerst ein Token anlegen: Einstellungen → Tokens, im Workspace, in dem der
Assistent arbeiten soll. content:read, wenn er nur lesen soll,
content:write, wenn er auch schreiben soll. Das Geheimnis wird einmal
angezeigt.
Ein hier erstelltes Token gilt hier — es liest und schreibt, was Basalt Ihnen zeigt, und nichts, was in den anderen Apps liegt. Deshalb müssen Sie dem Assistenten auch nicht sagen, welchen Workspace er nehmen soll: Das Token nennt einen, und der Endpunkt liest ihn dort ab.
In der Konfigurationsdatei eines MCP-Hosts:
{
"mcpServers": {
"basalt": {
"type": "http",
"url": "https://app.basaltapp.io/mcp",
"headers": {
"Authorization": "Bearer basalt_pat_…"
}
}
}
}
Die Hosts schreiben das unterschiedlich; gebraucht werden überall dieselben
zwei Dinge: die Adresse und der Authorization-Header. In Claude Code etwa:
claude mcp add --transport http basalt https://app.basaltapp.io/mcp \
--header "Authorization: Bearer basalt_pat_…"
Wenn Ihr Konto in mehreren Workspaces ist und Sie einen ausdrücklich nennen
möchten, verwenden Sie stattdessen
https://app.basaltapp.io/mcp/w/<Workspace-ID>. Ein Token kann immer nur
seinen eigenen Workspace nennen, die beiden müssen also übereinstimmen.
Dass ein Assistent nur liest, regelt das Token und keine Einstellung: Ein
content:read-Token weist der Server bei jedem Schreibvorgang ab, und das ist
eine härtere Zusicherung als ein Schalter auf der Clientseite.
Als Connector hinzufügen
Hosts ohne Header-Feld — claude.ai gehört dazu — fügen den Endpunkt als
Connector hinzu und melden Sie stattdessen an. Tragen Sie dieselbe Adresse
https://app.basaltapp.io/mcp in den Connector-Dialog ein; der Rest ist eine Anmeldung
und ein Bildschirm mit der Frage, ob Sie verbinden möchten. Nichts zu
kopieren, kein Token, das Sie aufbewahren müssen.
Ein Connector reicht weiter als ein Token, und der Bildschirm sagt das, bevor Sie zustimmen:
- Er gilt für jeden Workspace, in dem Sie Mitglied sind, nicht für einen.
- Er liest und schreibt, was Sie können. Einen nur lesenden Connector gibt
es nicht; für einen Assistenten, der nur schauen soll, erstellen Sie ein
Token mit
content:read. - Er sieht weiterhin nur Basalt, und er hört auf zu funktionieren, wenn Ihr Zugriff endet.
Weil ein Connector mehrere Workspaces umfasst, muss der Assistent sagen,
welchen er meint: https://app.basaltapp.io/mcp/w/<Workspace-ID>.
Wenn etwas abgelehnt wird
Der Endpunkt antwortet wie die API, eine Ablehnung sagt also, welcher der drei Fälle vorliegt:
- 401 — kein Zugangsdatum, oder eines, das unbekannt, widerrufen oder abgelaufen ist.
- 403 — ein Zugangsdatum, das das nicht darf: ein Token ganz ohne
content:read, eincontent:read-Token, das schreiben soll, oder eines, das zu einem anderen Workspace gehört als dem, den die Adresse nennt. - Alles andere ist die gewöhnliche Antwort der API, mit ihrem eigenen Wortlaut durchgereicht.
Was der Assistent bekommt
Zwölf Werkzeuge. Nur lesend, sofern nicht anders gekennzeichnet.
| Werkzeug | Wozu |
|---|---|
get_workspace |
Der Workspace, Ihre Rolle und jede Collection, die Sie sehen können, mit Ihrer dortigen Zugriffsstufe. Der erste Aufruf in einem fremden Workspace. |
search_pages |
Volltextsuche über Titel und Inhalte. So kommt man an eine Seitenkennung. |
list_pages |
Strukturelle Auflistung: die Kinder einer Seite oder die oberste Ebene einer Collection. |
get_page |
Eine Seite als kanonisches Markdown, Feldwerte als YAML-Frontmatter, dazu eine Versionsangabe. |
list_databases |
Die Datenbanken des Workspace oder einer Collection. |
get_database |
Die Spalten einer Datenbank: Schlüssel, Typen, Pflichtangaben und die erlaubten Auswahlwerte. |
query_database |
Zeilen mit Filtern und Sortierung. Jede Zeile trägt eine pageId. |
create_page |
schreibend — eine Seite in einer Collection, wahlweise unter einer Elternseite, wahlweise mit Inhalt. |
update_page |
schreibend — ersetzt den ganzen Inhalt und/oder benennt um. Nimmt die Version aus get_page. |
update_page_fields |
schreibend — setzt Feldwerte, ohne den Inhalt anzurühren. |
create_database_row |
schreibend — eine Zeile, die in Basalt eine Seite ist. |
trash_page |
schreibend — legt eine Seite samt Unterbaum in den Papierkorb. Umkehrbar; ein Werkzeug zum endgültigen Löschen gibt es bewusst nicht. |
Fünf Felder, auf die Sie sich verlassen können
Jeder Basalt-Workspace hat diese Felder, unter genau diesen Schlüsseln, und
niemand kann sie umbenennen, umtypisieren oder löschen. Im Frontmatter einer
Seite lesbar, über update_page_fields schreibbar, in query_database
filterbar.
| Schlüssel | Typ | Wofür |
|---|---|---|
summary |
Text | Ein, zwei Sätze dazu, worum es auf der Seite geht. search_pages und list_pages geben sie unter jedem Treffer aus — so lässt sich auswählen, was zu öffnen ist, ohne etwas zu öffnen. |
status |
Einfachauswahl | Draft, In Review, Approved, Published, Outdated, Archived — sagt, wie belastbar eine Seite ist. Die Liste ist in jedem Workspace dieselbe. |
page_type |
Einfachauswahl | Core, Process, Guide, Reference, Decision, Meeting notes, Template, Archive. Ebenfalls überall gleich. |
tags |
Mehrfachauswahl | Freier Wortschatz. Ein Wert, den es noch nicht gibt, entsteht beim Schreiben. |
related |
Relation | Kuratierte Verknüpfungen zwischen Seiten, symmetrisch: A mit B zu verknüpfen verknüpft B mit A. |
Auf einer gerade angelegten oder überarbeiteten Seite summary zu setzen ist
das Nützlichste, was ein Agent für den nächsten tun kann.
Zwei Ressourcen lassen sich direkt als Kontext anhängen: basalt://workspace
(Collections und Datenbanken mit ihren Kennungen) und basalt://page/{pageId}
(eine Seite als Markdown).
Drei Verhaltensweisen sollte man kennen, weil sie ändern, wie ein Assistent vorgehen sollte:
update_pageersetzt den Inhalt. Seite lesen, den erhaltenen Text ändern, alles zurückschicken. Ein Ausschnitt kürzt die Seite ab.- Versionen sind optimistische Sperren.
get_pageliefert eine; gibt man sie anupdate_pageweiter, scheitert der Schreibvorgang, statt eine Änderung zu überschreiben, die jemand zwischenzeitlich gemacht hat. Diese Weigerung ist der Zweck. - Kennungen werden nie geraten. Sie kommen aus
get_workspace,search_pages,list_pagesoderquery_database.
Was er kann und was nicht
Das Token ist die Identität. Der Server handelt als die Person, die das Token erzeugt hat, mit genau deren Zugriff — mehr kann er nicht, weil es unterhalb der API keinen Pfad gäbe, der das erlaubte. Eine Seite, die diese Person nicht lesen darf, wird nicht zurückgegeben, taucht in keiner Auflistung auf und wird von der Suche nicht gefunden.
Der Assistent sieht also einen betrachterabhängigen Workspace: Zeilenzahlen, Suchtreffer und Seitenbäume sind das, was diese Person sehen kann — nicht das, was existiert.
Manche Verweigerungen kann der Betreiber beheben, andere nicht. Der Server unterscheidet sie deshalb in der Nachricht, die er dem Modell reicht:
- Ein fehlender Geltungsbereich nennt die genaue Bereichszeichenkette und sagt, dass ein weiterer Versuch nichts hilft — jemand muss ein anderes Token erzeugen.
- Inhalt, den die Person nicht lesen darf, wird als solcher benannt, mit
Verweis auf
search_pages. - Nicht gefunden behauptet bewusst nicht zu wissen, ob die Seite fehlt oder bloß unlesbar ist — Basalt hält das absichtlich auseinander, und etwas anderes zu behaupten schickte einen Assistenten auf die Suche nach einem Tippfehler, den es nicht gibt.
BASALT_READ_ONLY=true hält die schreibenden Werkzeuge komplett zurück. Weiten
kann es nichts — ein content:read-Token verweigert ohnehin jeden Schreibzugriff
—, aber „das Modell hat nie ein Schreibwerkzeug gesehen" ist betrieblich eine
stärkere Aussage als „das Schreiben ist immer fehlgeschlagen", und es spart dem
Assistenten die Züge, in denen er das herausfindet.
Die Tokenverwaltung ist von hier aus überhaupt nicht erreichbar. Ein Zugang, der Zugänge erzeugen kann, weitet sich still aus und überlebt den Widerruf des ersten — deshalb ist die Token-Oberfläche von Haus aus nur mit Sitzung erreichbar.