Pack einen Agent in dein SaaS,
in 5 Minuten.
Deine REST-API ist das Toolset. Der Agent handelt im Namen deines Users. Der Agent ist ein Ordner in deinem Repo.
Bildschirm 2 · Der Ordner
Dein Agent sind Dateien in deinem Repo.
Standard-Dateien. Standard-Formate. Editiert von Claude Code, geprüft in PRs, deployed per CLI. Source of Truth ist dein Repo, nicht eine Vendor-Datenbank.
mindvm/ ├── mindvm.jsonc # project manifest ├── agents/ │ └── copilot/ │ ├── agent.jsonc # model · capabilities · skills · evals │ ├── persona.md # system prompt │ ├── skills/ │ │ └── board/main.js # require()-able module · your REST adapter │ └── evals/ │ └── basic.json # { input, criteria, pass_threshold } └── .runs/ # session logs — gitignored
Bildschirm 3 · Wie es funktioniert
Ein Datenpfad. Keine Überraschungen.
Dein User klickt den Chat. Der Plan des Agents ist JavaScript, das du lesen kannst. Calls gehen als der User raus, gegen deine bestehende API. Das ist die ganze Schleife.
User in deiner App eingeloggt · hat ein JWT
<MindVMChat /> React-Komponente in deiner UI
MindVM-Sandbox LLM emittiert JS · läuft in einer JS-Sandbox · Trace auf Disk
adapter.js dein Code · in deinem Repo · ~20 Zeilen
Deine REST-API PocketBase / Supabase / dein eigenes Go
Der Agent kann nur, was der User schon kann. Keine neue Permission-Surface, kein neuer Audit-Trail.
„Agenten, die denken, indem sie Code schreiben" ist die Implementierung, die den Rest lesbar, debuggbar und wiederabspielbar macht.
Mehrstufige Agenten,
auf die sich deine Nutzer wirklich verlassen.
Jeder ist ein dünner .js-Adapter über deiner bestehenden API. Cursor und Claude Code schreiben diese in Minuten aus deinem OpenAPI-Spec.
support.js Tier-1-Tickets klassifizieren, routen, lösen
Priorität einstufen, Kunden im CRM nachschlagen, Antwort mit Quellen entwerfen, bei Bedarf an Oncall eskalieren.
getTicket(id) { return req('GET', '/tickets/' + id);},replyToTicket(id, body) { return req('POST', '/tickets/' + id + '/reply', { body });},
refunds.js Refund-Eligibility & Approval-Flows
Policy-Matrix prüfen, Berechnung ausführen, ab Schwellwert menschliche Freigabe anfordern.
getOrder(id) { return req('GET', '/orders/' + id);},requestApproval(amount, reason) { return req('POST', '/approvals', { amount, reason });},
project.js Geführte Project-Einrichtung
Liest die Daten, stellt Rückfragen, ruft deine APIs auf — jeweils mit Bestätigung vor jedem Write.
getProject(id) { return req('GET', '/projects/' + id);},updateProject(id, patch) { return req('PATCH', '/projects/' + id, patch);},
analytics.js Natürlich-sprachliche Queries auf deinen Daten
Nutzer fragt im Klartext; der Agent schreibt die Query gegen dein Schema, führt sie aus, rendert das Ergebnis inline.
describeSchema() { return req('GET', '/schema');},runQuery(sql) { return req('POST', '/query', { sql });},
Jede Adapter-Datei ist ~20 Zeilen auf einer echten API. Das JWT lebt im Egress-Shim, nicht in diesem Code.
Alle 10 Muster in 4 Buckets ansehenBildschirm 5 · Die Eval-Story
Promotion ist von deinen Tests gegated.
Evals sind JSON-Dateien im selben Ordner. mindvm dev läuft sie bei jedem Save. Verhaltensänderungen werden wie Code-Änderungen reviewed — diffbar im PR, blockiert einen Deploy bei Regression.
{
"name": "adds a card to the named list",
"input": "Add a card called \"order coffee\" to Todo.",
"criteria": "Trace contains a single board.createCard call with listId 'l_todo' and title 'order coffee'. No other writes.",
"pass_threshold": 7
} $ mindvm dev⠋ syncing draft… synced (sha256:800b43c…)⠋ running 4 eval cases against the draft ✓ basic 9.1 ✓ adds a card to the named list 8.4 ✗ moves a card across lists 4.2 ← below 7.0 ✓ refuses to delete without yes 9.6 3 / 4 passing · log: .runs/2026-05-22T08-30-12Z-…
$ mindvm dev⠋ syncing draft… synced (sha256:9c4f17b…)⠋ running 4 eval cases against the draft ✓ basic 9.1 ✓ adds a card to the named list 8.4 ✓ moves a card across lists 8.7 ✓ refuses to delete without yes 9.6 4 / 4 passing · ready to deploy
Kein angeschraubtes Eval-Produkt. Kein „Tracing später einrichten." Das Pass/Fail-Signal liegt auf Disk, in derselben Schleife, die das AI-Coding-Tool sowieso schon nutzt.
Bildschirm 6 · Sicherheit
Der Agent ruft dein Backend als der User auf.
Die Sandbox hängt das JWT des Users am Egress-Shim an. Der Adapter-JS sieht es nie, kann es nicht loggen, nicht leaken. Dein Backend autorisiert den Call genauso, wie es einen normalen Request aus dem Browser des Users autorisiert.
// agents/copilot/agent.jsonc
"fetchPolicies": [
{
"origin": "${env.BACKEND_URL}",
"headers": {
"Authorization": "Bearer ${session.jwt}"
}
}
] - JWT lebt im Egress-Shim
Templates in agent.jsonc — nie im .js-Code, nie in einem Vault, den du rotieren musst. Die Session gibt das Token des Users mit; die Runtime stempelt den Header.
- Tenant-Scoping ist ein Prop
Gib den Tenant an <MindVMChat tenant={orgId} /> mit. Die Runtime trägt ihn in die Session; dein Backend filtert danach. Gleicher Agent, jeder Tenant, gescoped durch den Call.
- Keine neue Permission-Surface
Der Agent kann nur, was der User schon kann. Kein Service-Account zu auditieren. Keine „Agent-Rolle", die dein Security-Team modellieren muss.
- Gehärtete JS-Sandbox
Kein Dateisystem, kein Subprozess, kein beliebiges Netzwerk. Speicher und Zeit gedeckelt. Outbound-Fetches laufen durch Policies, nicht durch raw fetch.
„Der Agent kann nur, was der User kann" ist die Ein-Zeilen-Antwort auf die gruseligste Frage, die ein CTO stellt.
Dein Stack
MindVM ♥ dein bestehendes Backend.
Wir ersetzen dein CRUD nicht. Wir betreiben den Agent darüber — deine REST-API ist das Toolset, deine Auth ist die Auth, deine DB bleibt deine DB.
Nicht dabei? Wenn es HTTP und JSON spricht, läuft es.
Pack einen Agent in dein SaaS, in 5 Minuten.
Early Access — begrenzte Plätze, während wir die erste Welle onboarden. Erzähl uns von deiner App oder schnapp dir einen 30-Minuten-Slot.