Gmail-SAP-MCP-Assistant
Gmail + SAP MCP-Assistent
Eine Streamlit-Anwendung, mit der Sie Gmail lesen und verwalten, SAP Business Partner / Vertrieb / Abrechnung / Produktdaten durchsuchen und einen KI-Assistenten natürliche Sprachfragen zu Ihrem Posteingang (und SAP-Datensätzen) stellen können – alles über einen einzigen Model Context Protocol (MCP)-Server.
Streamlit UI (app.py)
│
┌───────────────┴───────────────┐
▼ ▼
Gmail / SAP / Admin tabs Ai tab
(direct button click) EmailAssistant (ai_agent.py)
│ → Mistral LLM decides which
│ tool(s) to call, if any
│ │
└───────────────┬────────────────┘
▼
MCPClient (mcp_client.py) — one persistent
background event loop for every call, either path
│
│ Streamable HTTP transport
▼
FastMCP server (server.py) — dispatches
the tool call by name
│
┌────────────────┴────────────────┐
▼ ▼
GmailService SAPService
(gmail_service.py) (sap_service.py)
│ │
▼ ▼
Gmail API SAP OData API
(OAuth credentials) (API key, sandbox)Die Benutzeroberfläche kommuniziert nie direkt mit Gmail oder SAP – jede
Aktion, ob ein Button-Klick oder etwas, das der KI-Assistent entschieden
hat, läuft über denselben MCPClient → FastMCP-Server → Service-Layer-Pfad.
Dadurch bleibt eine einzige, prüfbare Grenze zwischen der App und den beiden
externen Systemen erhalten.
Anfragefluss
Es gibt zwei Möglichkeiten, wie eine Anfrage in das System gelangt, und sie
treffen sich bei MCPClient.
1. Direkte UI-Aktion (Gmail / SAP / Admin-Tabs)
Sie klicken auf einen Button (z. B. „Suchen" im Gmail-Tab).
app.pyruft eine Methode direkt auf der gemeinsamenMCPClient-Instanz auf, z. B.mcp_client.gmail_search_messages(query, max_results).MCPClientplant diese Koroutine auf seiner dedizierten Hintergrund- Ereignisschleife und blockiert, bis sie abgeschlossen ist (_loop.run(...)inmcp_client.py) – das hält die MCP-Sitzung über Streamlits Rerun-pro-Interaktion-Modell hinweg sicher.Der FastMCP-Server (
server.py) empfängt den Tool-Aufruf über Streamable HTTP und leitet ihn an die passende Funktion weiter, z. B.gmail_search_messages().Diese Funktion ruft
GmailService(gmail_service.py) oderSAPService(sap_service.py) auf, die den eigentlichen Netzwerkaufruf durchführen – die Gmail-API (OAuth) oder die SAP-OData-API (API-Schlüssel) – und gibt geparste, einfache Dict-Ergebnisse zurück.Das Ergebnis wandert zurück: MCP-Server →
MCPClient._unwrap()→app.py, das es inst.session_statespeichert und rendert.
Fehler auf jeder Ebene (MCPToolError, MCPConnectionError oder etwas
Unerwartetes) werden zentral von run_action() in app.py abgefangen und
als st.error angezeigt, sodass ein fehlgeschlagener Aufruf die UI nie
abstürzen lässt.
2. KI-Assistent-Frage (KI-Tab)
Dies ist dieselbe Pipeline mit einer Entscheidungsschleife davor:
Ihre Frage (plus Chat-Verlauf) geht an
EmailAssistant.ask()inai_agent.py, das einen System-Prompt überprompts.pyerstellt (mit heutigem/morgigem Datum) und ihn zusammen mit demTOOLS-Schema an Mistral sendet.Mistral entscheidet, ob es ein Tool benötigt. Wenn ja, führt
ai_agent.pyden Aufruf über dieselbeMCPClient-Instanz aus, die auch von den manuellen Tabs verwendet wird –EmailAssistantkommuniziert nie selbst mit Gmail/SAP – und fügt das JSON-Ergebnis wieder in das Gespräch ein.Die Schritte 1–2 wiederholen sich (Suchen, dann vielleicht eine bestimmte Nachricht lesen, dann vielleicht eine weitere Suche) bis zu
MISTRAL_MAX_STEPS-Mal (Standard: 12).Sobald Mistral genügend Informationen hat, stoppt es die Tool-Aufrufe und gibt eine endgültige Antwort in natürlicher Sprache zurück, die
app.pyim Chat rendert – mit der vollständigen Tool-Aufruf-Spur in einem aufklappbaren „Verwendete Tool-Aufrufe"-Expander zum Debuggen.
Die Tool-Liste des Agents ist bewusst schmal (nur lesende Gmail/SAP- Nachschlagefunktionen), sodass er unabhängig von Ihrer Frage nichts senden, löschen oder ändern kann. Nur die manuellen Abläufe im Gmail-Tab können das, und jeder davon erfordert einen expliziten Bestätigungsschritt, bevor die zerstörerische Aktion ausgeführt wird.
3. App-Start (einmal pro Prozess)
get_mcp_client() in app.py ist mit @st.cache_resource umschlossen,
sodass es genau einmal ausgeführt wird: Es erstellt den MCPClient, ruft
.connect() auf, das den Hintergrund-Thread + die Ereignisschleife startet
und die Streamable-HTTP-Sitzung zum FastMCP-Server öffnet. Diese Sitzung
bleibt für die Lebensdauer des Streamlit-Prozesses aktiv – sie wird nicht
bei jedem Rerun neu erstellt.
Funktionen
Gmail (über den Tab „Gmail")
Nachrichten mit Gmail-eigener Suchsyntax auflisten / suchen
Vollständige Nachricht lesen (Text, Header, Anhänge)
E-Mails senden, Entwürfe erstellen, Nachrichten in den Papierkorb verschieben (jeweils mit explizitem Bestätigungsschritt in der UI)
Nachrichten als gelesen/ungelesen markieren, Labels auflisten, Anhangs-Bytes abrufen
SAP (über den Tab „SAP")
Konfiguration / Konnektivität zur SAP-OData-Sandbox prüfen
Business Partner auflisten und suchen, einen einzelnen Partner anzeigen
E-Mail-Adressen in den Daten auflisten
(Standardmäßig schreibgeschützt – siehe SAP-Schreibzugriffe unten)
KI-Assistent (über den Tab „KI")
Ein Mistral-basierter Agent (ai_agent.py / EmailAssistant), der
natürliche Sprachfragen beantwortet, wie zum Beispiel:
„Fasse die wichtigen E-Mails von heute zusammen"
„Finde E-Mails mit Anhängen"
„Habe ich morgen Vorstellungsgespräche geplant?"
„Fasse E-Mails der letzten 7 Tage zusammen"
Der Agent ist bewusst schreibgeschützt: Er kann nur
gmail_search_messages, gmail_read_message und gmail_list_messages
aufrufen (plus die schreibgeschützten SAP-Nachschlagefunktionen, die in
prompts.py beschrieben sind). Er hat kein Tool zum Senden, Antworten oder
Löschen von etwas, und der System-Prompt weist ihn ausdrücklich an, dies zu
sagen, wenn er danach gefragt wird – jede Tatsache in seinen Antworten muss
auf ein tatsächliches Tool-Ergebnis zurückgehen, niemals auf eine erfundene.
Verwaltungstab
Live-MCP-Verbindungsstatus, die Liste der Tools, die der Server derzeit bereitstellt, und die zuletzt abgerufene Gmail/SAP-Konfiguration – nützlich, um zu überprüfen, ob der Server erreichbar und korrekt konfiguriert ist.
Projektstruktur
Datei | Verantwortung |
| Streamlit-UI – Tabs für KI, Gmail, SAP und Admin |
| Streamlit-sicherer MCP-Client (einzelne persistente Hintergrund-Ereignisschleife; siehe Modul-Docstring für die Begründung) |
| Agent-Schleife: sendet die Benutzerfrage + Tool-Ergebnisse an Mistral, bis eine endgültige Antwort erzeugt wird |
| System-Prompt: Tool-Berechtigungen, Datumskontext, Gmail-Suchsyntax-Referenz, Antwortstil-Richtlinien |
| FastMCP-Server, der Gmail- und SAP-Operationen als MCP-Tools bereitstellt |
| Gmail-API-Wrapper: OAuth-Flow, Nachrichtenparsing, Senden/Entwurf/Löschen/Label-Operationen |
| SAP-OData-Wrapper: Business Partner, Sales Order, Billing Document, Produkt-Lesezugriffe (Schreibzugriffe implementiert, aber standardmäßig deaktiviert) |
| Python-Abhängigkeiten |
Voraussetzungen
Python 3.10+
Ein Google-Cloud-Projekt mit aktivierter Gmail-API und einem OAuth- Desktop-App-Client (
credentials.json)Zugriff auf eine SAP-OData-Sandbox (z. B. den SAP Business Accelerator Hub) mit einem API-Schlüssel, wenn der SAP-Tab/die SAP-Tools funktionieren sollen
Ein Mistral-API-Schlüssel, wenn der KI-Assistent-Tab funktionieren soll
Einrichtung
Abhängigkeiten installieren
python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txtGmail-OAuth-Anmeldedaten
Laden Sie die
credentials.jsonIhres OAuth-Clients von der Google Cloud Console herunter und legen Sie sie untercredentials/credentials.jsonab (oder setzen SieGMAIL_CREDENTIALS_FILEauf einen anderen Pfad). Beim ersten Aufruf eines Gmail-Tools öffnet der Server ein Browserfenster zur Autorisierung; das resultierende Token wird incredentials/token.jsongeschrieben.Umgebungsvariablen
Erstellen Sie eine
.env-Datei im Projektstamm:# --- MCP server --- MCP_SERVER_HOST=127.0.0.1 MCP_SERVER_PORT=8000 LOG_LEVEL=INFO # --- MCP client (Streamlit side) --- MCP_SERVER_URL=http://127.0.0.1:8000/mcp MCP_CONNECT_TIMEOUT_SECONDS=20 MCP_CALL_TIMEOUT_SECONDS=60 # --- Gmail --- GMAIL_CREDENTIALS_FILE=credentials/credentials.json GMAIL_TOKEN_FILE=credentials/token.json # --- SAP --- SAP_MODE=sandbox SAP_BASE_URL=https://sandbox.api.sap.com/s4hanacloud/sap/opu/odata/sap/API_BUSINESS_PARTNER SAP_API_KEY=your-sap-api-key SAP_VERIFY_SSL=true SAP_WRITE_ENABLED=false SAP_TIMEOUT_SECONDS=30 # --- AI Assistant --- MISTRAL_API_KEY=your-mistral-api-key MISTRAL_MODEL=mistral-large-latest MISTRAL_MAX_STEPS=12Jede Variable hat einen sinnvollen Standardwert, außer den Anmeldedaten/ API-Schlüsseln selbst – siehe die Spitze jeder
*_service.py/*_client.py- Datei für die genauen Fallback-Werte.MCP-Server ausführen
python server.pyDies startet den FastMCP-Server auf
MCP_SERVER_HOST:MCP_SERVER_PORTüber den Streamable-HTTP-Transport.Streamlit-App ausführen (in einem zweiten Terminal)
streamlit run app.pyÖffnen Sie die URL, die Streamlit ausgibt (normalerweise
http://localhost:8501).
SAP-Schreibzugriffe
SAPService implementiert bereits create_business_partner und
update_business_partner gegen die OData-Schreibendpunkte von SAP, aber die
entsprechenden MCP-Tools sind in server.py auskommentiert und die Aufrufe
sind in sap_service.py hart hinter SAP_WRITE_ENABLED=true gesperrt. Um
sie zu aktivieren:
Setzen Sie
SAP_WRITE_ENABLED=truein.env.Kommentieren Sie die Tool-Definitionen
sap_create_business_partner/sap_update_business_partnerinserver.pyaus.Starten Sie den MCP-Server neu.
Bis dahin ist der gesamte SAP-Zugriff unabhängig vom Flag schreibgeschützt.
Sicherheitshinweise
Der KI-Assistent kann Gmail nur lesen – er hat kein Sende-/Lösch-/ Änderungs-Tool, was sowohl in der
TOOLS-Liste vonai_agent.pyals auch im System-Prompt inprompts.pyerzwungen wird.Das Senden von E-Mails, das Erstellen von Entwürfen und das Löschen/ Verschieben in den Papierkorb im Gmail-Tab erfordern jeweils ein explizites Bestätigungskontrollkästchen oder einen „Suchen → Öffnen → Bestätigen"-Ablauf, bevor die zerstörerische Aktion ausgeführt wird.
SAP-Schreibzugriffe sind standardmäßig deaktiviert (
SAP_WRITE_ENABLED=false) und die Tools, die sie ausführen würden, sind auf dem MCP-Server nicht einmal registriert, es sei denn, Sie aktivieren sie.
Fehlerbehebung
„Verbindung zum MCP-Server fehlgeschlagen" – stellen Sie sicher, dass
server.pyläuft undMCP_SERVER_URLin Ihrer.envmit dessen Host/Port übereinstimmt.Gmail-OAuth-Fehler mit veraltetem/ungültigem Token – löschen Sie die Datei unter
GMAIL_TOKEN_FILEund versuchen Sie es erneut; die App führt den OAuth-Flow erneut aus.SAP-Anfragen schlagen mit HTTP-Fehlern fehl – einige SAP-Sandbox- Mandanten haben nicht jeden OData-Dienst (z. B.
API_SALES_ORDER_SRV,API_BILLING_DOCUMENT_SRV) standardmäßig aktiviert; prüfen Sie den Fehlertext gegen Ihren API-Katalog.„KI-Assistent nicht verfügbar" –
MISTRAL_API_KEYfehlt oder ist leer in.env.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
MCP server exposing the Backtest360 engine API as tools for AI agents.
MCP server for Gainium — manage trading bots, deals, and balances via AI assistants
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/suryanandan1/Gmail-SAP-Connection-With-MCP-Agent'
If you have feedback or need assistance with the MCP directory API, please join our Discord server