docs: MCP beschreiben, Fahrplan abschliessen
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
bdc4260d59
commit
0ccb21303d
@@ -6,6 +6,29 @@ die Versionierung [Semantic Versioning](https://semver.org/lang/de/).
|
||||
|
||||
## [Unveröffentlicht]
|
||||
|
||||
### Hinzugefügt
|
||||
|
||||
- **MCP-Server** unter `/api/mcp` mit sechs Werkzeugen: Aufgaben suchen,
|
||||
Woche ansehen, Kalender auflisten, Aufgabe anlegen, abhaken und einplanen.
|
||||
Beschreibung in [docs/MCP.md](docs/MCP.md).
|
||||
- Die Werkzeugliste richtet sich nach den Rechten des Tokens — was ein Token
|
||||
nicht darf, sieht das Modell gar nicht erst.
|
||||
|
||||
### Geändert
|
||||
|
||||
- Das Einplanen liegt jetzt an einer Stelle, die sowohl die Oberfläche als
|
||||
auch der MCP-Server benutzen. Ein über MCP angelegter Zeitblock verhält
|
||||
sich damit genau wie ein von Hand gezogener.
|
||||
|
||||
### Sicherheit
|
||||
|
||||
- MCP benutzt dieselben Tokens und dieselben Rechte wie die Schnittstelle.
|
||||
Ein Sprachmodell bekommt keinen eigenen Zugang.
|
||||
- Jede schreibende Nutzung steht im Protokoll, mit dem Vermerk, dass sie
|
||||
über MCP kam.
|
||||
- Der Server kann weder löschen noch Bereiche, Projekte, Kalenderkonten,
|
||||
Einstellungen oder Tokens anfassen.
|
||||
|
||||
## [0.7.0] – 2026-09-13
|
||||
|
||||
### Hinzugefügt
|
||||
|
||||
@@ -43,6 +43,8 @@ wird.
|
||||
Planer lässt sich als App auf dem Startbildschirm ablegen
|
||||
- **Öffentliche Schnittstelle** mit Tokens je Anwendung, Rechten je Token und
|
||||
jeder schreibenden Nutzung im Protokoll ([Beschreibung](docs/API.md))
|
||||
- **MCP-Server** für Sprachmodelle — dieselben Tokens, dieselben Rechte
|
||||
([Beschreibung](docs/MCP.md))
|
||||
- Anmeldung über einen OIDC-Anbieter, über Passkeys oder mit E-Mail und
|
||||
Passwort — je Instanz einzeln zuschaltbar
|
||||
- Rollen `Benutzer` und `Verwaltung`; jede schreibende Aktion wird
|
||||
@@ -51,9 +53,10 @@ wird.
|
||||
- Hell und Dunkel, Oberfläche durchgehend auf Deutsch
|
||||
- Betrieb über Docker Compose, mit Sicherung, Aktualisierung und Healthcheck
|
||||
|
||||
### Geplant
|
||||
### Was noch kommen könnte
|
||||
|
||||
Ein MCP-Server. Siehe [ROADMAP.md](ROADMAP.md).
|
||||
Der [Fahrplan](ROADMAP.md) ist abgearbeitet. Was danach denkbar wäre, steht
|
||||
dort unter „Ideen für später" — und was bewusst nicht kommt, gleich darunter.
|
||||
|
||||
## Bildergalerie
|
||||
|
||||
|
||||
+14
-4
@@ -12,7 +12,7 @@ grünen Prüfungen, aktueller Dokumentation und einem Eintrag im DEVLOG.
|
||||
| [M5](#m5--benachrichtigungen) | Benachrichtigungen | erledigt |
|
||||
| [M6](#m6--integrationen) | Integrationen | erledigt |
|
||||
| [M7](#m7--schnellerfassung-und-api) | Schnellerfassung und API | erledigt |
|
||||
| [M8](#m8--mcp) | MCP | geplant |
|
||||
| [M8](#m8--mcp) | MCP | erledigt |
|
||||
|
||||
---
|
||||
|
||||
@@ -156,9 +156,19 @@ Zeremonie als Schutz.
|
||||
|
||||
## M8 – MCP
|
||||
|
||||
- [ ] MCP-Server über `@modelcontextprotocol/sdk`
|
||||
- [ ] Lesen und Anlegen von Aufgaben und Zeitblöcken
|
||||
- [ ] Rechte wie bei der API, jede Nutzung im Protokoll
|
||||
**Erledigt am 13.09.2026 mit Version 0.8.0.**
|
||||
|
||||
**Ziel:** Ein Sprachmodell soll den Alltag erleichtern können — ohne einen
|
||||
eigenen, weicheren Zugang zu bekommen als jede andere fremde Anwendung.
|
||||
|
||||
- [x] MCP-Server über `@modelcontextprotocol/sdk`
|
||||
- [x] Lesen und Anlegen von Aufgaben und Zeitblöcken
|
||||
- [x] Rechte wie bei der API, jede schreibende Nutzung im Protokoll
|
||||
- [x] Werkzeugliste richtet sich nach den Rechten des Tokens
|
||||
|
||||
**Bewusst offen gelassen:** Der Server kann nichts löschen, keine Bereiche
|
||||
oder Projekte anlegen und keine Einstellungen anfassen. Ein Modell soll den
|
||||
Alltag erleichtern, nicht die Ordnung umbauen.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
# MCP-Server
|
||||
|
||||
Der Planer spricht das Model Context Protocol. Damit kann ein Sprachmodell
|
||||
Aufgaben suchen, anlegen, abhaken und einplanen — mit denselben Tokens und
|
||||
denselben Rechten wie die [Schnittstelle](API.md).
|
||||
|
||||
Adresse: `<APP_URL>/api/mcp`
|
||||
|
||||
## Einrichten
|
||||
|
||||
1. In der Anwendung unter **API** einen Token anlegen. Gib ihm nur, was das
|
||||
Modell wirklich braucht.
|
||||
2. Den Client auf die Adresse zeigen lassen, mit dem Token als Bearer.
|
||||
|
||||
Für Claude Code:
|
||||
|
||||
```bash
|
||||
claude mcp add planer --transport http https://planer.example.de/api/mcp \
|
||||
--header "Authorization: Bearer planer_…"
|
||||
```
|
||||
|
||||
Für Clients, die nur stdio können, dazwischen `mcp-remote` setzen:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"planer": {
|
||||
"command": "npx",
|
||||
"args": [
|
||||
"-y",
|
||||
"mcp-remote",
|
||||
"https://planer.example.de/api/mcp",
|
||||
"--header",
|
||||
"Authorization: Bearer planer_…"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Werkzeuge
|
||||
|
||||
Welche ein Modell zu sehen bekommt, hängt am Token. Was nicht erlaubt ist,
|
||||
taucht gar nicht erst in der Liste auf — ein Modell soll nicht gegen eine Tür
|
||||
laufen, die für es verschlossen ist.
|
||||
|
||||
| Werkzeug | Recht | Was es tut |
|
||||
| -------------------- | ----------- | ----------------------------------------------- |
|
||||
| `aufgaben_suchen` | `lesen` | Aufgaben auflisten, optional gefiltert |
|
||||
| `woche_ansehen` | `lesen` | Zeitblöcke einer Woche mit Summe |
|
||||
| `kalender_auflisten` | `lesen` | Verbundene Kalender samt Kennung |
|
||||
| `aufgabe_anlegen` | `erfassen` | Neue Aufgabe in der Inbox |
|
||||
| `aufgabe_abhaken` | `schreiben` | Aufgabe auf erledigt setzen |
|
||||
| `zeitblock_anlegen` | `schreiben` | Aufgabe einplanen und in den Kalender schreiben |
|
||||
|
||||
Zum Einplanen braucht es die Kennung eines Kalenderkontos — daher erst
|
||||
`kalender_auflisten`, dann `zeitblock_anlegen`.
|
||||
|
||||
`zeitblock_anlegen` geht durch dieselbe Stelle wie das Ziehen in der
|
||||
Wochenansicht: Rasterprüfung, Kalenderschreibweg, Schleifenschutz, Protokoll.
|
||||
Ein über MCP angelegter Zeitblock verhält sich also genau wie ein von Hand
|
||||
gezogener.
|
||||
|
||||
## Was der Server bewusst **nicht** kann
|
||||
|
||||
- **Löschen.** Weder Aufgaben noch Zeitblöcke. Abhaken ja, wegräumen nein.
|
||||
- **Bereich oder Projekt setzen.** Was hier entsteht, landet in der Inbox.
|
||||
- **Bereiche, Projekte oder Kalenderkonten anlegen und ändern.**
|
||||
- **Einstellungen oder Tokens anfassen.**
|
||||
|
||||
Ein Modell soll den Alltag erleichtern, nicht die Ordnung umbauen.
|
||||
|
||||
## Protokoll
|
||||
|
||||
Jede schreibende Nutzung landet im Protokoll — mit dem Vermerk, dass sie über
|
||||
MCP kam, und mit dem Token. Ein Modell, das Aufgaben anlegt, muss genauso
|
||||
nachvollziehbar sein wie ein Mensch. Eher noch mehr.
|
||||
|
||||
## Ohne Sitzungen
|
||||
|
||||
Der Server ist zustandslos: Jede Anfrage steht für sich. Der Planer hat keine
|
||||
langlaufenden Vorgänge, und eine Sitzungsverwaltung wäre Zustand, den mehrere
|
||||
Container nicht teilen könnten.
|
||||
+1
-10
@@ -31,18 +31,9 @@ Anleitung für den Alltag mit dem Planer. Eine Seite je Thema.
|
||||
|
||||
11. **[Protokoll](protokoll.md)** – nachsehen, wer wann was geändert hat
|
||||
|
||||
## Was noch kommt
|
||||
|
||||
Diese Seiten entstehen mit den nächsten Meilensteinen:
|
||||
|
||||
| Thema | Meilenstein |
|
||||
| ----- | ----------- |
|
||||
| MCP | M8 |
|
||||
|
||||
Der [Fahrplan](../../ROADMAP.md) sagt, was in welchem Meilenstein steckt.
|
||||
|
||||
---
|
||||
|
||||
Für fremde Anwendungen und Skripte: [Schnittstelle](../API.md).
|
||||
Für Sprachmodelle: [MCP-Server](../MCP.md).
|
||||
Zur Einrichtung einer neuen Instanz: [Schnellstart](../SCHNELLSTART.md).
|
||||
Für Betrieb, Sicherung und alle Umgebungsvariablen: [README](../../README.md).
|
||||
|
||||
@@ -70,10 +70,10 @@ export async function zeitblockAnlegen(daten: FormData): Promise<Rueckmeldung> {
|
||||
const ergebnis = await zeitblockAnlegenFuer(
|
||||
{ id: akteur.id, email: akteur.email },
|
||||
{
|
||||
aufgabeId: String(daten.get('aufgabeId') ?? ''),
|
||||
kalenderkontoId: String(daten.get('kalenderkontoId') ?? ''),
|
||||
beginn: new Date(String(daten.get('beginn') ?? '')),
|
||||
ende: new Date(String(daten.get('ende') ?? '')),
|
||||
aufgabeId: feld(daten, 'aufgabeId'),
|
||||
kalenderkontoId: feld(daten, 'kalenderkontoId'),
|
||||
beginn: new Date(feld(daten, 'beginn')),
|
||||
ende: new Date(feld(daten, 'ende')),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -91,6 +91,17 @@ export async function zeitblockAnlegen(daten: FormData): Promise<Rueckmeldung> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ein Textfeld aus dem Formular.
|
||||
*
|
||||
* FormData kann auch Dateien liefern; die haetten hier nichts zu suchen und
|
||||
* wuerden beim Stringify zu "[object Object]".
|
||||
*/
|
||||
function feld(daten: FormData, name: string): string {
|
||||
const wert = daten.get(name)
|
||||
return typeof wert === 'string' ? wert : ''
|
||||
}
|
||||
|
||||
// --- Verschieben -----------------------------------------------------------
|
||||
|
||||
const verschieben = z.object({
|
||||
|
||||
Reference in New Issue
Block a user