Outlook-Mails per KI in Deine Access-Datenbank: MCP als Brücke zwischen Cloud und Desktop

Du willst Outlook-Mails automatisiert in eine Access-Datenbank überführen — nicht per Copy & Paste, sondern intelligent gefiltert und strukturiert? Mit Claude Desktop und dem Model Context Protocol (MCP) geht das. Hier zeige ich Dir Schritt für Schritt, wie Du einen eigenen lokalen MCP-Server in Python baust, der Claude direkt mit Deiner .accdb-Datei verbindet.

Worum geht’s?

Stell Dir vor, Du sagst Claude: „Lies die letzten 20 Mails von kunde@beispiel.de, extrahiere Betreff, Datum und den ersten Absatz, und schreib alles in meine Access-Tabelle tblMailImport.“

Claude liest die Mails über den Microsoft 365 MCP-Connector, verarbeitet sie intelligent — und schreibt das Ergebnis über einen lokalen Python-MCP-Server direkt in Deine Access-Datenbank. Kein manuelles Zwischenspeichern, keine CSV-Datei, kein Import-Assistent.

Das Ganze funktioniert komplett lokal auf Deinem Rechner. Deine Access-Datenbank verlässt nie Deinen PC.

Die Architektur im Überblick

┌─────────────────────────────────────────────────────┐
│                  Claude Desktop                      │
│                                                      │
│  ┌──────────────┐          ┌──────────────────────┐  │
│  │ M365 MCP     │          │ Access MCP Server     │  │
│  │ (Outlook)    │          │ (Python, lokal)       │  │
│  │              │          │                        │  │
│  │ Mails lesen  │  Claude  │ Daten schreiben/lesen │  │
│  │ durchsuchen  │◄────────►│ Tabellen auflisten    │  │
│  │ filtern      │ steuert  │ Struktur abfragen     │  │
│  └──────┬───────┘  beide   └──────────┬───────────┘  │
│         │                             │              │
└─────────┼─────────────────────────────┼──────────────┘
          │                             │
          ▼                             ▼
   Microsoft 365               Lokale .accdb-Datei
   (Cloud)                     (Dein Rechner)

Der entscheidende Punkt: Beide MCP-Server laufen parallel in Claude Desktop. Claude kann in einem einzigen Gespräch sowohl Mails lesen als auch in Access schreiben. Du brauchst keinen Zwischenschritt.

Voraussetzungen

Bevor es losgeht, prüfe folgende Punkte:

  • Claude Desktop installiert und lauffähig (Windows)
  • Microsoft 365 MCP-Server bereits konfiguriert (z. B. @softeria/ms-365-mcp-server)
  • Python 3.10+ installiert (64-bit empfohlen)
  • Microsoft Access Database Engine installiert — der ODBC-Treiber Microsoft Access Driver (*.mdb, *.accdb) muss verfügbar sein
  • Bitness-Match: Python-Architektur (32/64-bit) muss zur Access-ODBC-Treiberversion passen

Bitness prüfen

Das ist die häufigste Fehlerquelle. Öffne eine Python-Konsole und teste:

import struct
print(struct.calcsize("P") * 8)  # Gibt 32 oder 64 aus

import pyodbc
print([x for x in pyodbc.drivers() if 'Access' in x])
# Erwartete Ausgabe: ['Microsoft Access Driver (*.mdb, *.accdb)']

Siehst Du eine leere Liste, stimmt die Bitness nicht überein, oder der Treiber fehlt. In dem Fall: Installiere die passende Version der Microsoft Access Database Engine Redistributable.

Wichtig: Wenn Du Office 32-bit installiert hast, brauchst Du auch Python 32-bit — oder umgekehrt. Mischbetrieb ist nicht vorgesehen und kann Office-Installationen beschädigen.

Schritt 1: Python-Umgebung einrichten

Erstelle ein neues Projektverzeichnis und eine virtuelle Umgebung:

mkdir access-mcp-server
cd access-mcp-server
python -m venv .venv
.venv\Scripts\activate
pip install pyodbc fastmcp

Alternativ mit uv (schneller):

uv init access-mcp-server
cd access-mcp-server
uv add pyodbc fastmcp

Schritt 2: Den MCP-Server bauen

Erstelle eine Datei access_mcp_server.py. Der Server stellt Claude vier Tools zur Verfügung: Tabellen auflisten, Tabellenstruktur abfragen, Daten lesen und Daten schreiben.

"""
Access MCP Server — Lokaler MCP-Server für Microsoft Access.
Gibt Claude Desktop Lese- und Schreibzugriff auf eine .accdb-Datei.
"""

import os
import json
import pyodbc
from fastmcp import FastMCP

# --- Konfiguration ---
DB_PATH = os.environ.get(
    "ACCESS_DB_PATH",
    r"C:\Daten\MeineDatenbank.accdb"
)
DRIVER = "{Microsoft Access Driver (*.mdb, *.accdb)}"

# --- MCP Server initialisieren ---
mcp = FastMCP(
    name="Access Database",
    instructions=(
        "Lokaler MCP-Server für Microsoft Access. "
        "Ermöglicht Lese- und Schreibzugriff auf eine .accdb-Datei. "
        "Nutze list_tables, um verfügbare Tabellen zu sehen. "
        "Nutze describe_table, um die Spaltenstruktur zu prüfen. "
        "Nutze query_table für SELECT-Abfragen. "
        "Nutze insert_records, um neue Datensätze einzufügen."
    )
)


def get_connection() -> pyodbc.Connection:
    """Stellt eine Verbindung zur Access-Datenbank her."""
    conn_str = f"DRIVER={DRIVER};DBQ={DB_PATH};"
    return pyodbc.connect(conn_str)


@mcp.tool()
def list_tables() -> str:
    """Listet alle Tabellen in der Access-Datenbank auf.
    Gibt Tabellennamen als JSON-Array zurück.
    Systemtabellen (MSys*) werden ausgeblendet.
    """
    conn = get_connection()
    try:
        cursor = conn.cursor()
        tables = [
            row.table_name
            for row in cursor.tables(tableType="TABLE")
            if not row.table_name.startswith("MSys")
        ]
        return json.dumps(tables, ensure_ascii=False)
    finally:
        conn.close()


@mcp.tool()
def describe_table(table_name: str) -> str:
    """Gibt die Spaltenstruktur einer Tabelle zurück.
    
    Args:
        table_name: Name der Tabelle (z.B. 'tblMailImport')
    
    Returns:
        JSON-Array mit Spaltenname, Datentyp und Nullable-Info.
    """
    conn = get_connection()
    try:
        cursor = conn.cursor()
        columns = []
        for row in cursor.columns(table=table_name):
            columns.append({
                "name": row.column_name,
                "type": row.type_name,
                "nullable": bool(row.nullable),
                "size": row.column_size
            })
        if not columns:
            return json.dumps({"error": f"Tabelle '{table_name}' nicht gefunden."})
        return json.dumps(columns, ensure_ascii=False)
    finally:
        conn.close()


@mcp.tool()
def query_table(sql: str) -> str:
    """Führt eine SELECT-Abfrage auf der Access-Datenbank aus.
    
    Args:
        sql: SQL SELECT-Anweisung (nur Leseabfragen erlaubt)
    
    Returns:
        JSON-Array mit den Ergebniszeilen.
    """
    sql_stripped = sql.strip().upper()
    if not sql_stripped.startswith("SELECT"):
        return json.dumps({"error": "Nur SELECT-Abfragen erlaubt."})
    
    conn = get_connection()
    try:
        cursor = conn.cursor()
        cursor.execute(sql)
        columns = [desc[0] for desc in cursor.description]
        rows = []
        for row in cursor.fetchall():
            rows.append(dict(zip(columns, [
                str(v) if not isinstance(v, (str, int, float, bool, type(None))) else v
                for v in row
            ])))
        return json.dumps(rows, ensure_ascii=False, default=str)
    finally:
        conn.close()


@mcp.tool()
def insert_records(table_name: str, records: list[dict]) -> str:
    """Fügt einen oder mehrere Datensätze in eine Access-Tabelle ein.
    
    Args:
        table_name: Zieltabelle (z.B. 'tblMailImport')
        records: Liste von Dictionaries mit Spaltenname-Wert-Paaren.
                 Beispiel: [{"Betreff": "Test", "Absender": "max@firma.de"}]
    
    Returns:
        JSON mit Anzahl der eingefügten Datensätze oder Fehlermeldung.
    """
    if not records:
        return json.dumps({"error": "Keine Datensätze übergeben."})
    
    conn = get_connection()
    try:
        cursor = conn.cursor()
        inserted = 0
        
        for record in records:
            columns = list(record.keys())
            placeholders = ", ".join(["?" for _ in columns])
            col_names = ", ".join([f"[{c}]" for c in columns])
            values = [record[c] for c in columns]
            
            sql = f"INSERT INTO [{table_name}] ({col_names}) VALUES ({placeholders})"
            cursor.execute(sql, values)
            inserted += 1
        
        conn.commit()
        return json.dumps({
            "success": True,
            "inserted": inserted,
            "table": table_name
        })
    except Exception as e:
        conn.rollback()
        return json.dumps({"error": str(e)})
    finally:
        conn.close()


if __name__ == "__main__":
    mcp.run()

Was der Server kann

ToolZweckTypischer Einsatz
list_tablesAlle Tabellen auflistenOrientierung: „Was gibt’s in der DB?“
describe_tableSpaltenstruktur einer TabelleClaude prüft vor dem Insert die Feldnamen
query_tableSELECT-Abfragen ausführenDuplikatprüfung, bestehende Daten lesen
insert_recordsDatensätze einfügenMails in Zieltabelle schreiben

Sicherheitshinweise

  • Nur SELECT: query_table blockiert alles, was nicht mit SELECT beginnt. Kein DELETE, kein UPDATE, kein DROP über die Abfrage-Funktion.
  • Parametrisierte Queries: insert_records nutzt Platzhalter (?) statt String-Konkatenation — kein SQL-Injection-Risiko.
  • Lokaler Betrieb: Der Server läuft nur auf Deinem Rechner und ist von außen nicht erreichbar (stdio-Transport, kein HTTP).

Schritt 3: Claude Desktop konfigurieren

Öffne die Datei claude_desktop_config.json. Unter Windows findest Du sie hier:

%APPDATA%\Claude\claude_desktop_config.json

Füge den Access-MCP-Server neben Deinem bestehenden M365-Server ein:

{
  "mcpServers": {
    "ms365": {
      "command": "npx",
      "args": ["-y", "@softeria/ms-365-mcp-server"],
      "env": {
        "// Deine bestehende M365-Konfiguration": ""
      }
    },
    "access-db": {
      "command": "C:\\pfad\\zu\\access-mcp-server\\.venv\\Scripts\\python.exe",
      "args": ["C:\\pfad\\zu\\access-mcp-server\\access_mcp_server.py"],
      "env": {
        "ACCESS_DB_PATH": "C:\\Daten\\MeineDatenbank.accdb"
      }
    }
  }
}

Wichtig:

  • Verwende den vollständigen Pfad zur python.exe in Deiner virtuellen Umgebung. Nicht python ohne Pfad — Claude Desktop kennt Deine PATH-Variable nicht zuverlässig.
  • Der Pfad zur .accdb-Datei wird als Umgebungsvariable übergeben. So kannst Du die Datenbank wechseln, ohne den Server-Code anzufassen.

Starte Claude Desktop nach der Änderung neu.

Schritt 4: Zieltabelle in Access anlegen

Bevor Claude schreiben kann, brauchst Du eine Zieltabelle. Hier ein einfaches Beispiel für einen Mail-Import:

CREATE TABLE tblMailImport (
    ID AUTOINCREMENT PRIMARY KEY,
    Absender TEXT(255),
    AbsenderMail TEXT(255),
    Betreff TEXT(255),
    EmpfangsDatum DATETIME,
    Auszug MEMO,
    Kategorie TEXT(100),
    ImportDatum DATETIME DEFAULT Now()
);

Oder erstelle die Tabelle im Access-Entwurfsmodus — das ist für Access-Entwickler vermutlich der vertrautere Weg.

Das Feld Kategorie ist dabei besonders interessant: Claude kann beim Import die Mail inhaltlich einordnen — z. B. „Anfrage“, „Rechnung“, „Terminbestätigung“. Das ist der Punkt, an dem KI echten Mehrwert gegenüber einem simplen Import liefert.

Schritt 5: Testen

Starte Claude Desktop und prüfe, ob beide MCP-Server erkannt werden. Du siehst die verfügbaren Tools in der Toolleiste (Hammer-Symbol).

Test 1 — Access-Verbindung prüfen

Schreib in Claude Desktop:

Welche Tabellen gibt es in meiner Access-Datenbank?

Claude ruft list_tables auf und zeigt Dir die Tabellennamen.

Test 2 — Tabellenstruktur prüfen

Zeig mir die Struktur von tblMailImport.

Claude ruft describe_table auf und listet Spalten mit Datentypen.

Test 3 — Der eigentliche Workflow

Suche in meinem Outlook-Postfach die letzten 10 Mails von support@beispiel.de. Extrahiere Absender, Betreff, Datum und die ersten zwei Sätze des Mail-Bodys. Kategorisiere jede Mail als „Anfrage“, „Rechnung“ oder „Sonstiges“. Schreib alles in tblMailImport.

Claude wird:

  1. Den M365-MCP-Server nutzen, um die Mails zu lesen
  2. Die Inhalte intelligent parsen und kategorisieren
  3. Den Access-MCP-Server nutzen, um die Ergebnisse einzufügen
  4. Dir eine Zusammenfassung geben, wie viele Datensätze geschrieben wurden

Fehlerbehebung

„ODBC Driver nicht gefunden“

Prüfe die Bitness (siehe Voraussetzungen). Der häufigste Fehler: Python 64-bit mit Access/Office 32-bit oder umgekehrt.

„Datei gesperrt / Unable to open registry key“

Access erlaubt nur eine exklusive Verbindung. Schließe die .accdb-Datei in Access, bevor Du über den MCP-Server darauf zugreifst. Tipp: Verwende für MCP-Zugriffe eine separate .accdb, nicht Deine Entwicklungsdatenbank.

„Tabelle nicht gefunden“

Tabellennamen in Access sind case-insensitive, aber der ODBC-Treiber kann bei Sonderzeichen (Leerzeichen, Umlaute) im Tabellennamen stolpern. Empfehlung: Keine Leerzeichen, keine Umlaute in Tabellennamen — wie es sich sowieso gehört.

Server startet nicht in Claude Desktop

Prüfe das Log: %APPDATA%\Claude\logs\. Häufige Ursachen: falscher Python-Pfad, fehlende Pakete in der venv, Syntaxfehler im JSON der Config.

Erweiterungsmöglichkeiten

Der hier gezeigte Server ist ein Grundgerüst. Je nach Anforderung kannst Du ergänzen:

  • update_record-Tool: Bestehende Datensätze aktualisieren (z. B. Kategorie nachträglich ändern)
  • delete_record-Tool: Datensätze löschen (mit Sicherheitsabfrage)
  • execute_action-Tool: Aktionsabfragen ausführen (UPDATE/DELETE mit bewusstem Opt-in)
  • Mehrere Datenbanken: Pfad als Parameter statt Umgebungsvariable
  • Logging: Jeden MCP-Aufruf in eine separate Log-Tabelle schreiben
  • Schema-Cache: Tabellenstruktur beim Start einlesen und als MCP-Resource bereitstellen — dann muss Claude nicht jedes Mal describe_table aufrufen

Fazit

MCP macht Claude Desktop zu einer echten Integrationsplattform. Der hier gezeigte Ansatz verbindet zwei Welten, die normalerweise nicht zusammenkommen: Microsoft 365 in der Cloud und eine lokale Access-Datenbank auf Deinem Rechner.

Das Besondere daran: Claude ist nicht nur ein Durchleitungspunkt. Claude versteht die Mails, kann filtern, kategorisieren, zusammenfassen und strukturiert ablegen. Das ist kein stupider Import — das ist ein intelligenter Datenprozess.

Und der lokale MCP-Server? Der ist in einer halben Stunde aufgesetzt und beliebig erweiterbar. Heute Mails importieren, morgen Kundendaten abgleichen, übermorgen Berichte aus Access-Daten generieren lassen.

Struktur vor KI — aber wenn die Struktur steht, kann die KI richtig loslegen.

Du willst den Mail-zu-Access-Workflow für Dein Unternehmen einrichten oder hast eine andere Access-Datenbank, die Du per MCP anbinden willst? Meld Dich bei mir — als Access-Spezialist und KI-Berater helfe ich Dir, die Brücke zu bauen.

Schreibe einen Kommentar

Nach oben scrollen