Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🧠 MindSift
Der Kopf frei in drei Sekunden.
MindSift ist eine selbst gehostete Schaltstelle für spontane Gedanken, Aufgaben mit Kanban-Board, hierarchische Outliner-Notizen, die mehrere Personen gleichzeitig bearbeiten können, und gemeinsame Listen. Alles läuft als ein einzelner Container mit eingebetteter SQLite-Datenbank, auf deinem eigenen Server.
Links das helle, rechts das dunkle Theme.
Philosophie • Funktionen • Schnellstart • Betrieb • Entwicklung • Dokumentation
💡 Die Philosophie
Die meisten Notiz- und Aufgaben-Apps verlangen Struktur im falschen Moment: Wenn dir ein Gedanke kommt, willst du keinen Ordner suchen und keine Felder ausfüllen. MindSift trennt deshalb Erfassen und Organisieren:
- Abladen: In die Eingabeleiste tippen,
Enter, fertig. Wer will, weist den Gedanken gleich einer Aufgabe, Liste oder Notiz zu. - Sichten (Triage): Später gehst du den Stapel Karte für Karte durch: verwerfen, zur Aufgabe machen, in eine Notiz oder Liste verwandeln.
- Vertiefen: Aus losen Ideen werden Aufgaben mit Unteraufgaben, vernetzte Outliner-Notizen oder geteilte Listen für Familie und Team.
✨ Funktionen
⚡ Schnellerfassung & Triage
- Eingabeleiste im Kopf der App, jederzeit mit
Coder/fokussierbar; auch per Spracheingabe: über den Browser oder datenschutzfreundlich über einen eigenen Whisper-Container (optional indocker-compose.yml, siehe Architektur); auf Smartphones auch per Gedrückthalten des+-Knopfs (Hold-to-Record mit Pegel-Wellen). - Ziel beim Erfassen wählbar: Posteingang, Aufgabe, Listeneintrag oder Notiz.
- Triage-Deck:
H/←verwerfen,L/→zur Aufgabe,TAufgabe mit Termin,Din Notiz verwandeln, Leertaste = später. Auf dem Smartphone per Wischgeste oder über große Knöpfe unter der Karte; die Warteschlange klappt bei Bedarf auf. - Teilen aus anderen Apps: Als installierte App erscheint MindSift im Teilen-Menü des Smartphones; geteilte Texte und Links landen im Posteingang und lassen sich direkt danach mit einem Tipp zur Aufgabe oder auf eine Liste schicken.
- Papierkorb mit Wiederherstellen.
✅ Aufgaben & Kanban
- Listen- und Kanban-Ansicht, Spalten pro Aufgabenliste frei konfigurierbar.
- Prioritäten, Fälligkeitsdatum, Hashtags, Unteraufgaben mit Fortschrittsbalken, Markdown-Notizen.
- Filter, Gruppierung und Sortierung; Drag & Drop in Liste und Board, auch auf den Reiter einer anderen Aufgabenliste.
- Aufgabenlisten teilen mit Benutzern oder Gruppen, wahlweise als Bearbeiter oder nur lesend.
- Aufgaben beobachten: Beliebige Aufgaben per Klick abonnieren, um über alle Änderungen informiert zu werden.
- Wiederholungen: Wiederkehrende Aufgaben (täglich, wöchentlich, monatlich, jährlich) mit automatischer Folgeaufgabe beim Abhaken.
- Tageszusammenfassung: Tägliche Übersicht fälliger Aufgaben zur selbst gewählten Uhrzeit per E-Mail, Discord, eigenem Webhook oder Push.
- Push-Benachrichtigungen auf Handy und Desktop (auch bei geschlossener App; iPhone/iPad als Home-Bildschirm-App), als eigener Kanal je Ereignis.
- Alarme & Benachrichtigungen: Fälligkeits-Alarme sofort, alle übrigen Ereignisse (Freigaben, erledigte geteilte Aufgaben, beobachtete Aufgaben) gebündelt; pro Ereignis wählbar über E-Mail, Discord, eigenen Webhook und Push.
📝 Workspace: Outliner-Notizen
- Jeder Gedanke ein Bullet:
Enter,Tab/Shift+Tab, Ein-/Ausklappen, Drag & Drop ganzer Äste; am Handy eine Leiste über der Tastatur zum Ein-/Ausrücken und Verschieben. - Zoom-Fokus per Klick auf den Bullet, Breadcrumbs zum Zurücknavigieren; Fokus-Modus (
Strg+Umschalt+F) zeigt nur die Notiz in Lesebreite, Ordner gleiten bei Bedarf von links herein. - Journal: eine Notiz pro Tag, alle Tage untereinander (heute oben, ältere laden beim Scrollen nach), mit Kalender zum Springen; einzelne Tage lassen sich teilen. Pro Gerät abschaltbar.
- Blocktypen und Slash-Befehle:
/todo,/number(nummerierte Liste: 1., a., i.),/link,/h1–/h3,/code(mit Syntax-Hervorhebung),/callout,/divider,/extract,/image,/audio,/diktat. - Bilder & Audio in Notizen:
/image(Datei, Kamera, Zwischenablage oder Link),/audio(Sprachnotiz oder Datei-Upload) und/diktat(Live-Transkription). - Link-Vorschau: Vorschaukarte (Titel, Beschreibung, Bild) für Punkte, die nur aus einer Web-Adresse bestehen, z. B. über
/link; die Seite ruft der Server ab, nicht dein Browser. Pro Gerät abschaltbar. - Ast auslagern & Notizen zusammenführen: Bulletpoints samt Unterbaum in eigenständige Notizen auslagern (
/extract) oder Notizen per Drag & Drop bzw. Menü zusammenführen (jeweils mit vollständiger Rückgängig-Funktion). - Wiki-Links
[[Notiz]], auch auf einzelne Punkte ([[Notiz#^id|Text]], kopierbar an jedem Punkt), Links und#Hashtags; Tag-Seiten bündeln alle Fundstellen. - Ordner, Favoriten, To-Do-Rollup über alle Notizen und Export einer Notiz als
.md. - Eingefügtes Markdown wird zur Gliederung: Überschriften werden zu Abschnitten mit eingerücktem Inhalt, Listen (auch nummeriert) behalten ihre Ebenen, Absätze werden eigene Punkte. Kürzel beim Tippen:
-,1.,[],#,Strg+B/I/K.Strg+Z/Strg+Umschalt+Znimmt eigene Änderungen zurück bzw. stellt sie wieder her. - Teilen: Notizen und ganze Ordner lassen sich Benutzern oder Gruppen als Bearbeiter oder Leser freigeben. Empfänger sortieren sie in ihren eigenen Baum ein.
🤝 Gemeinsam bearbeiten
- Live: Mehrere Personen schreiben gleichzeitig in derselben Notiz; Änderungen erscheinen bei den anderen in Bruchteilen einer Sekunde. Die Leiste über der Notiz zeigt, wer gerade mitliest.
- Kein Überschreiben: Wer in einem Bullet schreibt, hält ihn kurz für sich; andere sehen ein Schloss mit Namen und arbeiten in den übrigen Bullets weiter. Kommt es doch zu einem Konflikt (z. B. nach Offline-Arbeit), bleibt der zweite Text als markierte Kopie mit „Übernehmen“/„Verwerfen“ erhalten.
- Offline-fest: Jede Eingabe wird zuerst im Browser gesichert und später übertragen, auch nach Neuladen oder Tagen ohne Netz.
- Hinter strengen Proxys: WebSocket → SSE → Long-Polling → Abfrage alle 3 s; MindSift wählt automatisch, was durchkommt. Der aktive Weg steht in der Leiste über der Notiz („Live“, „Abgleich alle 3 s“).
Technik dahinter: Doku/modules/collaboration.md.
🛒 Geteilte Listen
- Einkaufs-, Pack- und Checklisten mit Kategorien per Hashtag (
Hafermilch #Kühlregal), Mengenangaben und Drag & Drop zwischen Kategorien oder in eine andere Liste. - Freigabe an Benutzer und Gruppen (Bearbeiter oder Leser); abgehakte Einträge erscheinen bei allen in Echtzeit.
🏢 Benutzer, Gruppen, Administration
- Geführte Ersteinrichtung, Rollen Admin und Mitglied. Einladungen als Code oder Link (auch für mehrere Personen, auf Wunsch per E-Mail verschickt). Registrierung ohne Einladung wahlweise geschlossen, mit Freigabe durch einen Admin, nur für bestimmte E-Mail-Endungen oder offen, auf Wunsch mit Bestätigung der E-Mail-Adresse per Link – auch fest per Umgebungsvariable.
- Gruppen mit Gruppen-Admins für Freigaben.
- Admin-Bereich: Benutzer, Einladungen, Instanzname, SMTP, Freigabe-Modus, Sicherungen, Spracherkennung.
🎨 Darstellung & App
- Fünf Farbfamilien mit je einer hellen und dunklen Variante: Klassik, Fjord, Terrakotta, Polarized, Suri. Hell/Dunkel auf Wunsch „Wie System“, dazu eine eigene Akzentfarbe, Ecken rund oder eckig und Knöpfe mit oder ohne Rahmen (pro Gerät). Für eigene Themes gibt es einen Theme-Manager (eine CSS-Datei).
- Installierbar als App (PWA) auf Smartphone und Desktop. Sie startet auch ohne Netz mit dem zuletzt geladenen Stand; offline erfasste Gedanken und abgehakte Aufgaben oder Listeneinträge werden nachgereicht, sobald die Verbindung wieder da ist.
![]() Fjord |
![]() Terrakotta |
![]() Polarized |
![]() Suri |
🔌 Integrationen
- Eingehend (API-Key):
POST /api/v1/webhooks/ingestlegt Gedanken, Aufgaben oder Listeneinträge aus Smarthome, Skripten oder Automationen an. - Ausgehend: eigener Webhook als Benachrichtigungskanal (JSON per POST), Discord, E-Mail, Push.
- Persönliche API-Keys, Datenexport als JSON, Markdown-Archiv (Obsidian-kompatibel).
🚀 Schnellstart
MindSift läuft als einzelner Container mit Webserver, API, Datenbank und Frontend.
Option 1: Installationsskript
curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/install.sh | bash
Das Skript legt ein Verzeichnis an, lädt docker-compose.yml und .env.example, erzeugt ein JWT_SECRET und startet den Container.
Option 2: Docker Compose
mkdir -p mindsift && cd mindsift
curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/docker-compose.yml -o docker-compose.yml
curl -fsSL https://git.dsit.me/sandrodach/MindSift/raw/branch/dev/.env.example -o .env
# In .env: JWT_SECRET durch einen langen Zufallswert ersetzen!
docker compose up -d
Alle Einstellungen stehen mit Erklärung in .env. Optional kommt eine eigene Spracherkennung dazu: Block whisper in docker-compose.yml einkommentieren und STT_URL=http://whisper:8000 setzen (Anleitung in der Datei).
Minimal:
services:
mindsift:
image: git.dsit.me/sandrodach/mindsift:latest # :latest = Stand von main (jede Version), :dev = Entwicklungsstand
restart: unless-stopped
ports: ["8080:8080"]
volumes: ["./data:/data"]
environment:
- JWT_SECRET=hier-ein-langer-zufaelliger-wert
- BASE_URL=https://mindsift.example.com
Ersteinrichtung
Rufe http://localhost:8080 auf. Beim ersten Start führt ein Assistent durch das Anlegen des Administrator-Kontos.
⚠️
JWT_SECRET: Ohne Angabe (oder mit einem der Platzhalter aus den Beispielen) erzeugt der Server beim ersten Start einen Zufallswert und speichert ihn alsjwt.secretim Datenverzeichnis. Für Produktion lieber selbst einen langen Zufallswert setzen. Rufe die Instanz außerdem direkt nach dem Start auf, damit kein Fremder das erste Konto anlegt.
⚙️ Betrieb & Konfiguration
| Variable | Standard | Zweck |
|---|---|---|
PORT |
8080 |
HTTP-Port |
DATA_DIR |
/data (Container) |
Ablage der Datenbank mindsift.db |
JWT_SECRET |
zufällig erzeugt (/data/jwt.secret) |
Signaturschlüssel der Anmelde-Tokens; Platzhalter werden ignoriert |
BASE_URL |
http://localhost:8080 |
Öffentliche URL. Nur wenn gesetzt (und SMTP eingerichtet ist), gibt es „Passwort vergessen?“ – die Links in den Mails werden ausschließlich daraus gebaut |
TRUSTED_PROXIES |
private |
Wessen X-Forwarded-For/X-Real-IP geglaubt wird: private (Proxy im Docker-/Heimnetz), all (immer, früheres Verhalten), none oder eigene CIDR-Bereiche (Doku/reverse-proxy.md) |
LOGIN_PROTECTION |
true |
Sperre nach Fehlversuchen: 3 pro Konto und Adresse, 20 pro Konto, 30 pro Adresse, jeweils 15 Minuten. false schaltet sie ab |
TZ |
Europe/Berlin |
Zeitzone für Fälligkeiten und Alarme (ganztägige Aufgaben melden sich um 9:00) |
REGISTRATION_MODE |
leer (Admin-UI entscheidet) | Registrierung ohne Einladung: closed, approval (Admin gibt frei), domain (nur erlaubte E-Mail-Endungen), domain+approval (Endungen sofort, andere nach Freigabe), open. Gesetzt ist es im Admin-UI gesperrt |
REGISTRATION_DOMAINS |
leer | Erlaubte E-Mail-Endungen für die domain-Modi, z. B. firma.de, *.firma.de; gesetzt im Admin-UI gesperrt |
REGISTRATION_VERIFY_EMAIL |
leer (Admin-UI entscheidet) | true: Wer sich ohne Einladung registriert, bestätigt zuerst seine E-Mail-Adresse per Link (braucht SMTP und BASE_URL); unbestätigte Konten werden nach 48 Stunden gelöscht |
ALLOW_REGISTRATION |
false |
true = wie REGISTRATION_MODE=open (gesperrt); false lässt die Wahl dem Admin-UI |
LOG_LEVEL / DEBUG |
info / false |
Logging |
SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM, SMTP_TLS |
leer | E-Mail-Alarme (auch im Admin-UI) |
SMTP_FROM_NAME |
MindSift |
Anzeigename des Absenders bei E-Mails |
SMTP_SKIP_VERIFY |
false |
Zertifikatsprüfung für interne Mailserver abschalten |
NOTIFY_DIGEST_MINUTES |
5 |
Bündelungsintervall für Benachrichtigungen in Minuten |
VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, VAPID_SUBJECT |
automatisch | Schlüssel für Push-Benachrichtigungen; ohne Angabe einmal erzeugt und in der Datenbank gespeichert. VAPID_SUBJECT (Kontakt für die Push-Dienste, mailto: oder https://) sonst aus BASE_URL |
MEDIA_* |
diverse | Grenzen für Bilder und Audio in Notizen (MEDIA_MAX_IMAGE_MB=15, MEDIA_MAX_AUDIO_MB=50, MEDIA_QUOTA_MB=0) |
STT_* |
diverse | Optionale eigene Spracherkennung per Whisper (STT_URL, STT_MODEL, STT_LANGUAGE …; siehe Doku/architecture.md) |
LEGAL_IMPRINT_URL, LEGAL_PRIVACY_URL |
leer | Impressum/Datenschutz als externer Link (nur http(s)) |
LEGAL_IMPRINT_CONTENT, LEGAL_PRIVACY_CONTENT (oder …_CONTENT_FILE mit Dateipfad) |
leer | Impressum/Datenschutz als Markdown, angezeigt in einem Lesefenster. Ohne URL und Text bleibt der Link unsichtbar. |
LEGAL_CUSTOM_LINK_LABEL, LEGAL_CUSTOM_LINK_URL |
leer | Zusätzlicher Link im Footer (z. B. Statusseite), nur https |
MINDA_DEMO |
false |
Legt Demo-Konten admin/admin (mit Beispieldaten) und user/user an; eine Notiz und zwei Listen sind zwischen beiden geteilt, um das gemeinsame Bearbeiten auszuprobieren. Nie auf öffentlichen Servern! |
DEMO_RESET_MINUTES |
20 |
Nur im Demo-Modus: setzt die Datenbank in diesem Abstand auf die Beispieldaten zurück (0 = nie). Angemeldete bleiben angemeldet, die App zeigt einen Countdown und lädt danach neu. |
- Reverse-Proxy: Am besten WebSocket-Upgrade und ungepufferte SSE-Streams durchreichen. Blockiert ein Proxy beides, funktioniert MindSift trotzdem über Long-Polling bzw. regelmäßige Abfragen, nur etwas träger. Beispiele für Nginx, Traefik, Caddy und Cloudflare: Doku/reverse-proxy.md.
- Datensicherung: In den Admin-Einstellungen lassen sich automatische tägliche Backups einschalten (ganze Datenbank plus ein Backup je Benutzer unter
data/backups/, Standard 3 Tage aufbewahrt). Benutzer laden ihre Server-Backups herunter oder spielen sie ganz oder für einzelne Bereiche wieder ein. Der Ordner liegt neben der Datenbank: zusätzlich woanders sichern. Manuell geht weiterhinsqlite3 mindsift.db ".backup 'backup.db'". - Updates: Neues Image ziehen und Container neu starten (
docker compose pull && docker compose up -d). Das Schema wird beim Start automatisch angepasst. Die laufende Version steht im Kopf der App unter dem Namen. - Image-Tags:
:dev= Stand des Branchesdev,:latest= Stand vonmain(jede neue Version landet dort). Ein Git-Tag wiev1.2.0erzeugt zusätzlich:v1.2.0und:stable; Vorabversionen wiev1.0.0-rc.1verschieben:stablenicht. - Versionen & Änderungen: Semantic Versioning, was sich geändert hat, steht in der CHANGELOG.md.
🛠 Entwicklung
Voraussetzungen: Go 1.23, Node 22.
# Backend: Vet und Tests
go vet ./... && go test ./...
# Frontend
cd frontend
npm ci
npm run dev # Vite-Entwicklungsserver
npx tsc --noEmit # Typprüfung
npm run test:run # Komponententests (Vitest, jsdom)
npm run build # Produktions-Build
cd ..
e2e/run.sh # Browser-Tests (Playwright, zwei Benutzer) gegen ein frisch gebautes Image
e2e/screenshots.sh # Screenshots dieser README neu erzeugen (Demo-Daten, hell/dunkel diagonal)
Für das Binary wird das gebaute Frontend nach cmd/server/dist kopiert (go:embed); das mehrstufige Dockerfile erledigt das und führt Typprüfung, Frontend-Tests, Go-Vet und Go-Tests beim Image-Build aus.
Stack: Go (chi, gorilla/websocket, JWT, modernc SQLite, webpush-go) · React 18, TypeScript, Vite, Tailwind.
📚 Dokumentation
Die technische Doku liegt unter Doku/: Architektur, Datenbank, REST- und Echtzeit-API, Module (inkl. gemeinsamem Bearbeiten), Freigaben und Berechtigungen, Reverse-Proxy, Themes. Bekannte Schwachstellen und offene Punkte stehen in Doku/flaws.md.
🔒 Deine Daten gehören dir
- Selbst gehostet, keine Telemetrie, keine Fremddienste, Schrift und Icons werden mitgeliefert. Ausgehende Verbindungen baut nur der Server auf, und nur für das, was du nutzt: Benachrichtigungen (SMTP, Discord, eigener Webhook, die Push-Dienste der Browser), Link-Vorschauen (die verlinkte Seite wird einmal abgerufen, pro Gerät abschaltbar) und optional dein eigener Whisper-Server.
- Alle Inhalte liegen in einer einzigen SQLite-Datei; Bilder und Sprachnotizen liegen daneben in
data/media/. Der ganze Workspace lässt sich als Obsidian-kompatibles Markdown-Archiv (ZIP, mitattachments/) exportieren, alle Daten eines Benutzers als Backup-ZIP (JSON plus Mediendateien).
📄 Lizenz
MindSift ist gemeinfrei unter The Unlicense: Du darfst den Code ohne jede Bedingung nutzen, ändern, weitergeben und verkaufen, auch ohne Namensnennung. Es gibt keine Gewährleistung.










