Add language assistant settings and related features: Introduce new routes and controller methods for managing language assistant settings, including retrieval and saving of LLM configurations. Update navigation structure to include language assistant options. Enhance vocab course model to support additional learning attributes such as learning goals and core patterns. Update SQL scripts to reflect new database schema changes for vocab courses. Improve localization for language assistant settings in German and English.

This commit is contained in:
Torsten Schulz (local)
2026-03-25 15:53:49 +01:00
parent 8af726c65a
commit d50d3c4016
40 changed files with 3145 additions and 56 deletions

View File

@@ -0,0 +1,85 @@
# Language Course MCP Server
Model-Context-Protocol-Server zum **Ergänzen und Abfragen** von Sprachkurs-Inhalten: Glossar (Begriffe/Phrasen), neue Einträge speichern, **Konversationsübungen** als Rollenspiel-Prompts.
Liegt bewusst **neben** der YourPart-App (`mcp/language-course-server/`); Daten sind zunächst eine lokale JSON-Datei. Du kannst Inhalte später in `backend/scripts/create-language-courses.js` / Vocab-Modelle oder per API spiegeln.
## Tools
| Tool | Zweck |
|------|--------|
| `search_terms` | Glossar durchsuchen (`query`, optional `targetLang`, `nativeLang`) |
| `add_phrase` | Neue Phrase in `glossary.json` schreiben |
| `conversation_practice` | Zufälliges Szenario zum Üben (optional `topicHint`) |
| `export_glossary_snippet` | Letzte `n` Einträge als JSON für Export |
| `llm_status` | Prüft, ob API-Key/Modell gesetzt sind (ohne Netz) |
| `llm_chat` | Freier Chat mit dem LLM (`userMessage`, optional `systemPrompt`) |
| `llm_language_tutor` | `mode: dialogue` (Rollenspiel in Zielsprache) oder `evaluate` (Feedback zur Antwort) |
## LLM-Anbindung (OpenAI-kompatibel)
Voraussetzung für `llm_*`: ein **API-Key** und optional **Base-URL** / **Modell**.
| Variable | Bedeutung |
|----------|-----------|
| `LANGUAGE_COURSE_LLM_API_KEY` oder `OPENAI_API_KEY` | Pflicht für LLM-Tools |
| `LANGUAGE_COURSE_LLM_BASE_URL` | Leer = OpenAI-Default; z.B. `http://127.0.0.1:11434/v1` (Ollama) |
| `LANGUAGE_COURSE_LLM_MODEL` | Default: `gpt-4o-mini` |
Lokal: `cp .env.example .env` und Key eintragen. Beim Start wird `mcp/language-course-server/.env` geladen (sofern vorhanden).
**Cursor:** dieselben Variablen im `env`-Block des MCP-Eintrags setzen (oder nur Pfad zur `.env` vermeiden und Keys dort nicht duplizieren dann Server per Wrapper starten, der `dotenv` lädt; unser Server lädt `.env` automatisch aus seinem Ordner).
**Ollama-Beispiel:**
```bash
LANGUAGE_COURSE_LLM_BASE_URL=http://127.0.0.1:11434/v1
LANGUAGE_COURSE_LLM_MODEL=llama3.2
LANGUAGE_COURSE_LLM_API_KEY=ollama
```
## Daten
- Standard: `data/glossary.json` (wird bei Bedarf angelegt).
- Alternativ: Umgebungsvariable `LANGUAGE_COURSE_MCP_DATA` auf ein Verzeichnis setzen (dort liegt `glossary.json`).
## Installation
```bash
cd mcp/language-course-server && npm install
```
## Cursor einbinden
In den Cursor-Einstellungen unter **MCP** einen Server hinzufügen, z.B.:
```json
{
"mcpServers": {
"language-course": {
"command": "node",
"args": ["/ABSOLUTER/PFAD/zu/YourPart3/mcp/language-course-server/src/server.mjs"],
"env": {
"LANGUAGE_COURSE_MCP_DATA": "/ABSOLUTER/PFAD/zu/YourPart3/mcp/language-course-server/data",
"OPENAI_API_KEY": "sk-…"
}
}
}
}
```
`args` und `LANGUAGE_COURSE_MCP_DATA` an deinen Rechner anpassen.
## Manuell testen
```bash
cd mcp/language-course-server && npm run inspector
```
Öffnet den MCP Inspector; dort Tools ausprobieren.
## Hinweis zur App
Die Sprachkurse in der App nutzen `VocabCourse` / `vocabService` (siehe `backend/`). Dieser MCP ist eine **autororientierte Ergänzung** für deinen Workflow in der IDE.
**YourPart-Web:** Unter **Einstellungen → Sprachassistent** (`/settings/language-assistant`) speichern Nutzer **API-Key** und Metadaten in **`community.user_param`** (Typen `llm_settings` / `llm_api_key`, Gruppe `languageAssistant` in `type.settings`) — verschlüsselt wie andere Profilparameter. Der lokale MCP nutzt weiterhin die Umgebungsvariablen hier; beides ist getrennt, bis ein Backend-Proxy die gespeicherten Werte nutzt.