Build CasaDePrompt private prompt library with AI, versioning and MCP
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
# CasaDePrompt
|
||||
|
||||
Dein privates Zuhause für gute Prompts. Ein Python-Prozess, eine SQLite-Datei, ein Container. Kein PostgreSQL, Redis oder externer Suchdienst. Dunkle, responsive Weboberfläche ohne CDN oder Build-Schritt.
|
||||
|
||||
Eine optionale Sammlung mit sechs Beispielen liegt in `beispiel-prompts.json` und lässt sich über die Einstellungen importieren. Neue Installationen starten leer.
|
||||
|
||||
## Was drin ist
|
||||
|
||||
- Prompt-Bibliothek mit Kategorien, Tags, Favoriten, Papierkorb und Duplikaten.
|
||||
- Versionierung des vollständigen Prompts, Versionsvorschau und Wiederherstellung als neue Version. Gleichzeitige Änderungen werden erkannt.
|
||||
- Textsuche und Bedeutungssuche mit Embeddings. „Auto“ kombiniert beide; ähnliche Ergebnisse sind Vorschläge, keine garantierten Treffer.
|
||||
- OpenAI-kompatible API-Basis-URL, optionaler API-Key, Modellscan über `/models`, getrennte Chat- und Embedding-Modelle. Optional separater Embedding-Endpoint.
|
||||
- KI-Vorschläge für Kategorie, Tags und Kurzbeschreibung; vor dem Speichern manuell übernehmen.
|
||||
- KI-Überarbeitung als bearbeitbarer Vorschlag neben dem Original. Erst Übernehmen und Speichern ändert den Prompt.
|
||||
- Privater MCP-Server über Streamable HTTP, nur lesend: `search_prompts`, `get_prompt`, `list_categories`, `get_prompt_versions`.
|
||||
- JSON-Export und Import inklusive Versionen, ohne Modell-API-Keys.
|
||||
- Zugangsschlüssel für die Weboberfläche, separater MCP-Schlüssel. Keine Registrierung, keine öffentlichen Profile, keine Telemetrie.
|
||||
|
||||
## Unraid: normaler Python-Alpine-Container
|
||||
|
||||
### 1. Dateien auf dem NAS ablegen
|
||||
|
||||
```text
|
||||
/mnt/user/appdata/CasaDePrompt/
|
||||
├── bootstrap/
|
||||
│ └── Startpunkt.sh
|
||||
├── ssh/
|
||||
│ ├── athena_key
|
||||
│ └── known_hosts
|
||||
└── data/ # wird dauerhaft gespeichert
|
||||
```
|
||||
|
||||
`Startpunkt.sh` aus diesem Repository nach `bootstrap/` kopieren. Den SSH-Key `athena_key` und eine **bereits geprüfte** `known_hosts` mit dem Eintrag für `[192.168.1.2]:33` nach `ssh/` kopieren. Auf dem Entwicklungsrechner ist dieser Host bereits bekannt. Private Schlüssel niemals ins Repository committen. Für den dauerhaften Betrieb reicht ein eigener, nur lesender Deploy-Key für dieses Repository; er kann unter dem gleichen Dateinamen gemountet werden.
|
||||
|
||||
Die SSH-Dateien sollten nur root zugänglich sein (`chmod 700 ssh`, `chmod 600 ssh/athena_key ssh/known_hosts`). Das Skript prüft den Hostschlüssel strikt; es akzeptiert keine fremden Schlüssel automatisch. Passwortgeschützte Keys benötigen einen Agent und werden von diesem einfachen Bootstrap nicht unterstützt.
|
||||
|
||||
### 2. Unraid-Vorlage einspielen
|
||||
|
||||
`unraid/CasaDePrompt.xml` nach
|
||||
|
||||
```text
|
||||
/boot/config/plugins/dockerMan/templates-user/my-CasaDePrompt.xml
|
||||
```
|
||||
|
||||
kopieren. In **Docker → Container hinzufügen → Vorlage** `CasaDePrompt` auswählen. Falls die Auswahl noch nicht aktualisiert ist, die Seite neu laden.
|
||||
|
||||
Vorbelegt sind:
|
||||
|
||||
| Einstellung | Wert |
|
||||
|---|---|
|
||||
| Image | `python:3.13-alpine` |
|
||||
| Netzwerk | `bridge` (normales Unraid-Netz über Portfreigabe) |
|
||||
| Web-Port | Host `8765` → Container `8000` |
|
||||
| Repository | `ssh://git@192.168.1.2:33/michael/CasaDePrompt.git` |
|
||||
| Branch | `main` |
|
||||
| Startbefehl / Post Arguments | `/bin/sh /bootstrap/Startpunkt.sh` |
|
||||
| App-Benutzer | `99:100` |
|
||||
|
||||
Beim Start installiert das Skript Git/SSH und Python-Pakete, lädt den gewählten Branch bzw. Tag und startet die Anwendung ohne root-Rechte. Dafür benötigt es Zugriff auf dein Git, Alpine-Paketserver und PyPI. Ein Neustart lädt den aktuellen Stand erneut. Bei Download-/Installationsfehlern stoppt es mit einer Meldung, statt eine halb installierte App zu starten. Für reproduzierbare Updates einen Release-Tag in `APP_REF` verwenden.
|
||||
|
||||
### 3. Anmelden
|
||||
|
||||
Öffnen: `http://UNRAID-IP:8765`
|
||||
|
||||
Den automatisch erzeugten Zugangsschlüssel in der Unraid-Konsole auslesen:
|
||||
|
||||
```sh
|
||||
docker exec CasaDePrompt cat /data/admin-token
|
||||
```
|
||||
|
||||
In der Anmeldemaske eingeben. Der Browser erhält ein HttpOnly-Sitzungscookie (24 Stunden). Der Schlüssel wird nicht im Browser-LocalStorage gespeichert. Sitzungen enden auch bei einem Serverneustart.
|
||||
|
||||
### 4. Modelle verbinden
|
||||
|
||||
Unter **Einstellungen** beispielsweise `http://192.168.1.20:1234/v1` eintragen. Aus dem Container bedeutet `localhost` der Container selbst; für einen anderen Server dessen LAN-IP verwenden.
|
||||
|
||||
Optional API-Key eingeben → **Modelle scannen** → Modell-ID auswählen. Alternativ direkt eintippen. Der Scan speichert zunächst die Verbindungsfelder. Leere Schlüssel-Felder behalten gespeicherte Keys; zum Löschen gibt es eine eigene Checkbox.
|
||||
|
||||
- **Chatmodell:** für „Mit KI verfeinern“, verwendet `/chat/completions`.
|
||||
- **Embedding-Modell:** für Bedeutungssuche, verwendet `/embeddings`. Ein Chatmodell kann diese Aufgabe nicht automatisch ersetzen.
|
||||
|
||||
Danach **Index ergänzen**. Neue/geänderte Prompts werden beim Speichern indexiert. Bei einem Fehler bleibt der Prompt gespeichert und die Oberfläche zeigt einen Hinweis. Nach Wechsel von Embedding-Modell oder URL sind alte Vektoren nicht mehr gültig. Wenn hinter derselben Modell-ID ein anderes Modell läuft, **Komplett neu aufbauen** wählen.
|
||||
|
||||
Ohne Embeddings funktioniert die Textsuche. Es gibt keine versteckte Behauptung von Bedeutungssuche: Der verwendete Suchmodus und Fehler werden angezeigt. Die Embedding-Suche erfolgt im Python-Prozess, die Vektoren liegen in SQLite; gedacht für ein persönliches Archiv, nicht Millionen Dokumente.
|
||||
|
||||
## MCP / OpenClaw
|
||||
|
||||
**Einstellungen → MCP → Verbindungsdaten anzeigen** liefert URL und separaten Bearer-Token.
|
||||
|
||||
```text
|
||||
Transport: Streamable HTTP
|
||||
URL: http://UNRAID-IP:8765/mcp/
|
||||
Header: Authorization: Bearer DEIN_MCP_TOKEN
|
||||
```
|
||||
|
||||
Diese Angaben in einem MCP-fähigen Client bzw. dessen MCP-Bridge eintragen. Die konkrete OpenClaw-Konfiguration hängt von dessen installierter Version und MCP-Anbindung ab; das angezeigte JSON beschreibt die Verbindung und ist keine zugesicherte OpenClaw-Konfigurationsdatei.
|
||||
|
||||
Beispielauftrag: „Suche in CasaDePrompt nach einem Prompt, um einem Kunden höflich abzusagen.“
|
||||
|
||||
`search_prompts` akzeptiert `query`, `limit` und `mode` (`auto`, `text`, `semantic`). Ergebnisse enthalten Titel, vollständigen Prompt, Kategorie, Tags, Version und gegebenenfalls Ähnlichkeit sowie Suchhinweise. `get_prompt` kann gezielt eine frühere Version abrufen. Papierkorb-Inhalte werden nicht über MCP ausgegeben. MCP darf keine Prompts ändern und verwendet weder deinen Web-Zugangsschlüssel noch deinen Modell-API-Key.
|
||||
|
||||
## Alternative: fest gebautes Image
|
||||
|
||||
```sh
|
||||
docker compose up -d --build
|
||||
docker compose exec casadeprompt cat /data/admin-token
|
||||
```
|
||||
|
||||
Das beiliegende Dockerfile nutzt ebenfalls `python:3.13-alpine`; der App-Code wird beim Build eingebaut. Es braucht beim Start keinen Git-Key und keine Paketdownloads. Daten liegen in einem Docker-Volume. Dieser Weg ist unabhängig vom gewünschten Unraid-Bootstrap nutzbar.
|
||||
|
||||
## Lokal entwickeln
|
||||
|
||||
Python 3.13 oder neuer:
|
||||
|
||||
```sh
|
||||
python3 -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
DATA_DIR=./data uvicorn atelier.app:create_app --factory --host 127.0.0.1 --port 8765
|
||||
```
|
||||
|
||||
Tests:
|
||||
|
||||
```sh
|
||||
pip install pytest
|
||||
python -m pytest tests -q
|
||||
```
|
||||
|
||||
Der interne Python-Paketname `atelier` ist nur ein Implementierungsdetail.
|
||||
|
||||
## Daten, Backup und Betrieb
|
||||
|
||||
- `/data/atelier.sqlite3`: Prompts, Versionen und Vektoren.
|
||||
- `/data/settings.json`: Endpoint-Einstellungen und API-Keys. Nur serverseitig; in Exporten nicht enthalten.
|
||||
- `/data/admin-token`, `/data/mcp-token`: Zugangsschlüssel.
|
||||
- Gesamten Datenordner **bei gestopptem Container** sichern; bei laufender SQLite-WAL-Datenbank nicht nur die Hauptdatei kopieren. JSON-Export ist jederzeit für Prompts/Versionen nutzbar.
|
||||
- Import legt neue IDs an, erhält Versionen, löscht nichts. Danach Index ergänzen.
|
||||
- API-Keys sind durch Dateirechte geschützt, nicht separat verschlüsselt. Wer Host-/Root-Zugriff hat, kann sie lesen.
|
||||
- Für Zugriff außerhalb eines vertrauenswürdigen LANs HTTPS über einen Reverse Proxy nutzen. Bei HTTPS `COOKIE_SECURE=1` setzen. Keine CORS-Freigabe; Weboberfläche und API verwenden denselben Origin.
|
||||
- Ein uvicorn-Prozess; keine zusätzlichen Worker verwenden, da Sitzungen im Arbeitsspeicher liegen.
|
||||
- `GET /health` ist ein öffentlicher einfacher Healthcheck.
|
||||
- Schlüssel rotieren: Container stoppen, entsprechende Token-Datei löschen, starten. Bestehende Clients müssen den neuen Schlüssel erhalten. Alternativ `ADMIN_TOKEN`/`MCP_TOKEN` als Umgebungsvariablen setzen; dann gelten diese statt der Dateien.
|
||||
|
||||
## Stand und Grenzen
|
||||
|
||||
Erste eigenständige Version. Die KI-Überarbeitung ist absichtlich ein manueller Entwurf; ein grafischer Wort-für-Wort-Diff ist noch nicht enthalten. Versionsvorschau und Wiederherstellung sind vorhanden. Die Tests nutzen einen simulierten OpenAI-kompatiblen Modellserver; ein konkretes lokales Modell muss beim Einrichten noch geprüft werden. Docker/Unraid wird über die beiliegenden Dateien vorbereitet, ein echter Container-Test muss auf einer Maschine mit Docker erfolgen.
|
||||
Reference in New Issue
Block a user