inbox-sync
Der Bruecken-Skill zwischen “Handy-Notiz per Siri” und “Datei im Repo”. Zieht Emails die Marvin an sich selbst geschickt hat und legt sie als Rohmaterial in inbox/ ab. Einsortieren in Wiki / Tasks / Ideen macht wiki-maintenance in einem separaten Schritt — dieser Skill transportiert nur.
Trigger-Prinzip. Marvin schreibt sich normalerweise keine Emails selber. Jede Email von Marvin an Marvin ist also bewusst eine Inbox-Notiz. Kein Subject-Marker noetig, kein zusaetzliches Ritual. Das macht Siri-Diktat einfach: “Hey Siri, neue Mail an mich, Text: …“.
Was zaehlt als “Marvin”? Beide Konten: hello@marvinkuehlmann.com (business) und marvinkuehlmann@gmail.com (privat). Jede Kombination gilt:
| From | To | Inbox-Mail? |
|---|---|---|
| hello@ | hello@ | ja |
| hello@ | marvinkuehlmann@ | ja |
| marvinkuehlmann@ | marvinkuehlmann@ | ja |
| marvinkuehlmann@ | hello@ | ja |
| Externer | egal | nein |
1. Gmail durchsuchen (beide Accounts parallel)
Query pro Account: from:(hello@marvinkuehlmann.com OR marvinkuehlmann@gmail.com) to:(hello@marvinkuehlmann.com OR marvinkuehlmann@gmail.com) in:anywhere
in:anywheredamit Emails auch gefunden werden wenn Gmail sie in SPAM geschoben hat (passiert bei from=hello@ to=privat — Spoofing-Verdacht).- Accounts beide abfragen, identische Email kann in beiden Mailboxen landen (delivered_to unterscheidet sich). Dedupe laeuft ueber
message_id(siehe naechster Schritt).
Dedupe: schon verarbeitete Emails ueberspringen
Vor dem Zeigen der Treffer alle .md-Files in inbox/ lesen und gmail_id-Werte aus dem Frontmatter sammeln. Jede Email deren id bereits in dieser Menge ist — skippen. Das File-System ist die Dedupe-Quelle, nicht ein Gmail-Label.
Warum File-basiert: Das MCP-Toolset hat kein create_label. Ein agent-inbox-processed-Label anzulegen ist nicht moeglich ohne zusaetzliches Tooling. File-Dedupe ist direkter und braucht keinen Gmail-State.
Wenn 0 neue Treffer (nach Dedupe) in beiden Accounts: Ausgabe "Keine neuen Inbox-Emails." und STOP. Keine leere Ordner-Aktion, keine falsche Betriebsamkeit.
Edge Case: echte Self-Emails ausschliessen
Seltene Faelle wo Marvin doch MAL eine Mail an sich selbst schreibt, die kein Inbox-Material ist:
- Drafts die er sich zum spaeter-schicken ablegt
- Google-Docs/Drive-Benachrichtigungen die technisch “von mir” aussehen (Sender kann vom Service manipuliert sein)
Darum gibt es Schritt 2 (Preview) — Marvin kann dort einzelne Mails ausschliessen. Nie stillschweigend importieren.
2. Pro Email Preview zeigen
Bevor du schreibst, zeig eine Kurz-Uebersicht:
📥 {n} neue Inbox-Emails gefunden:
1. [privat→privat] 2026-04-17 18:42 — "Becker Stahl Mittwoch"
→ "Alex hat angerufen, Mittwoch 14 Uhr..."
2. [hello→privat] 2026-04-17 19:15 — "Idee Podcast Skill"
→ "Ich hatte eben die Idee, dass wir..."
...
Alle in `inbox/` ablegen und Emails aufraeumen? [j/n/auswaehlen]
Warum Preview: Marvin soll eine versehentlich self-adressed Email (Draft, Google-Benachrichtigung) noch abfangen koennen. Nach dem OK laeuft der Skill durch.
Auswahl-Modus: Wenn Marvin einzelne Emails skippen will (nur 1 und 3), die restlichen bleiben unberuehrt (kein File, keine Gmail-Aktion).
3. Pro Email ein File schreiben
Zielpfad: inbox/YYYY-MM-DD-<slug>.md
YYYY-MM-DD= Email-Empfangs-Datum (nicht heute — konsistent mit dem Moment wo der Gedanke kam)<slug>= aus dem Betreff, ohne[inbox]-Marker, kebab-case, max 60 Zeichen, Umlaute aufgeloest (ae/oe/ue/ss — sieheconventions.md §1)- Konflikt-Strategie: Wenn File schon existiert (gleicher Tag, gleicher Slug) → suffix
-2,-3
File-Inhalt:
---
description: "Roh-Inbox-Eintrag via Siri/Email. Noch nicht einsortiert."
last_reviewed: {Datum-heute}
source: email
source_account: {delivered_to-Adresse}
source_message_id: {Email-Message-ID}
gmail_id: {Gmail-message-id, fuer Dedupe}
received_at: {ISO-Timestamp aus date-Header}
---
# {Betreff}
{Email-Body als Plain-Text — HTML strippen, signatur-ueblich bereinigen (Gmail-typische `--`-Trenner, `"Von meinem iPhone gesendet"`, Attachments-Footer etc. raus)}Keine Interpretation, keine Zusammenfassung. Nur transportieren. wiki-maintenance ist fuer’s Einsortieren zustaendig, dieser Skill ist reiner Kurier.
Betreff-Slug-Sonderfall: Wenn der Betreff leer oder generisch ist (z.B. nur “Inbox”, “Notiz”, “(kein Betreff)”): slug aus den ersten ~5-8 Woertern des Body bauen. Der H1-Titel kann trotzdem der Original-Betreff bleiben.
HTML-Bereinigung: Wenn die Mail nur HTML ist (kein Plain-Text-Teil), den HTML-Body in Plain-Text konvertieren. Keine Links/Formatting erhalten — falls Marvin Formatting braucht, schreibt er es ordentlich beim Einsortieren.
Siri-Typos tolerieren: Spracherkennung macht Fehler (“Das eine Test-E-Mail ist” statt “Dies eine Test-E-Mail ist”). Body nicht korrigieren — Marvin weiss was er gemeint hat, Korrektur wuerde Zusatz-Risiko fuer Inhalts-Aenderung einfuehren.
4. Email aufraeumen
Fuer jede erfolgreich geschriebene Email:
- SPAM-Label entfernen (falls gesetzt) — die Mail soll nicht im Spam-Ordner verschwinden, wir wollen sie in “Alle Nachrichten” auffindbar halten.
- UNREAD-Label entfernen — gelesen-Markierung, sie ist ja verarbeitet.
- INBOX-Label entfernen (falls gesetzt) — archivieren. Die Mail ist in “Alle Nachrichten” noch da.
Nicht loeschen. Die Email bleibt in “Alle Nachrichten” erhalten, falls spaeter noch was nachgeschaut werden muss. Audit-Spur via Gmail-Search: from:me to:me zeigt alles was jemals als Inbox-Notiz gesendet wurde.
Dedupe ist File-basiert, kein Label noetig. Der Skill liest gmail_id aus allen inbox/*.md Files im naechsten Lauf. Die Mail wird nicht erneut gezogen. Siehe Schritt 1.
Fehler-Handling: Wenn das Schreiben des Files fehlschlaegt, nicht die Email verändern — sonst geht der Kontext verloren. Schreib den Fehler in die Zusammenfassung und verarbeite den Rest weiter.
5. Zusammenfassung zeigen
Format:
✅ {n} Inbox-Emails verarbeitet:
1. inbox/2026-04-17-becker-stahl-mittwoch.md (privat)
2. inbox/2026-04-17-idee-podcast-skill.md (business)
...
{optional, bei Fehlern:}
⚠️ {n} Fehler:
- "Idee XYZ" (business): {Fehler-Text}
Naechster Schritt: `wiki-maintenance` laufen lassen um die Inbox einzusortieren.
Die letzte Zeile ist wichtig — macht den Chain zu wiki-maintenance sichtbar ohne ihn automatisch auszufuehren (Marvin entscheidet).
6. Edge Cases
- Anhaenge in der Email: Noch nicht unterstuetzt. Wenn eine Email Anhaenge hat, das File trotzdem schreiben (Text-Body), am Ende eine Zeile
**Anhang in Email — nicht importiert:** {Dateiname(n)}anhaengen. Marvin entscheidet was damit passiert. Phase-2-Verbesserung: Anhaenge nachinbox/attachments/extrahieren. - Sehr kurze Email (z.B. “test”): trotzdem schreiben. Wiki-maintenance wird das wahrscheinlich loeschen.
- Threads (Replies auf frueheren Inbox-Email): Jede Message als eigenes File, Slug mit
-replySuffix. - Externer Absender an mich: Kein Inbox-Material. Die Query filtert das schon raus — Sicherheitshalber vor dem Schreiben nochmal
frompruefen. - Draft/Self-Email die KEIN Inbox-Material ist: Marvin skippt per Preview (Schritt 2). Skill macht dann nichts — File nicht schreiben, Email nicht anfassen.
7. Side-Effects-Uebersicht
| Aktion | Wann | Reversibel? |
|---|---|---|
File in inbox/ schreiben | pro Email, nach OK | Ja (manuell loeschen) |
| SPAM-Label entfernen | nach File-Write | Ja (in Gmail wieder setzen) |
| UNREAD-Label entfernen | nach File-Write | Ja (in Gmail wieder setzen) |
| INBOX-Label entfernen (archivieren) | nach File-Write | Ja (Email wieder in Inbox ziehen) |
Keine Email wird geloescht. Keine externe Kommunikation.
Related
- _context — Inbox-Zweck und Befuell-Wege
- SKILL — sortiert die Inbox ein
- config-planning — Email-Account-Strategie (welcher Account ist welcher)
- conventions §1 — Naming (kebab-case, Umlaut-Aufloesung)
- CLAUDE — Routing-Tabelle (Mobile-Notiz → inbox-sync)
- gsuite — Gmail-MCP (beide Accounts)