Gmail-SAP-MCP-Assistant
Gmail + SAP MCP Assistant
Streamlit-приложение, которое позволяет читать и управлять Gmail, просматривать данные SAP Business Partner / Sales / Billing / Product и задавать ИИ-ассистенту вопросы на естественном языке о вашем почтовом ящике (и записях SAP) — всё через единый Model Context Protocol (MCP) сервер.
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)Интерфейс никогда не обращается к Gmail или SAP напрямую — каждое действие, будь то нажатие кнопки или решение ИИ-ассистента, проходит через один и тот же путь MCPClient → FastMCP server → service layer. Это обеспечивает единую, проверяемую границу между приложением и двумя внешними системами.
Поток запросов
Есть два способа, которыми запрос попадает в систему, и они сходятся в MCPClient.
1. Прямое действие в интерфейсе (вкладки Gmail / SAP / Admin)
Вы нажимаете кнопку (например, «Search» на вкладке Gmail).
app.pyвызывает метод напрямую на общем экземпляреMCPClient, напримерmcp_client.gmail_search_messages(query, max_results).MCPClientпланирует эту корутину в своём выделенном фоновом цикле событий и блокируется до её завершения (_loop.run(...)вmcp_client.py) — это обеспечивает безопасность MCP-сессии в модели Streamlit с повторным выполнением при каждом взаимодействии.FastMCP-сервер (
server.py) получает вызов инструмента через Streamable HTTP и передаёт его соответствующей функции, напримерgmail_search_messages().Эта функция вызывает
GmailService(gmail_service.py) илиSAPService(sap_service.py), которые выполняют реальный сетевой вызов — Gmail API (OAuth) или SAP OData API (API key) — и возвращают разобранные результаты в виде простых словарей.Результат возвращается обратно: MCP server →
MCPClient._unwrap()→app.py, который сохраняет его вst.session_stateи отображает.
Ошибки на любом уровне (MCPToolError, MCPConnectionError или что-то непредвиденное) перехватываются централизованно функцией run_action() в app.py и отображаются как st.error, так что неудачный вызов никогда не приводит к сбою интерфейса.
2. Вопрос ИИ-ассистенту (вкладка Ai)
Это тот же конвейер с циклом принятия решений перед ним:
Ваш вопрос (плюс история чата) отправляется в
EmailAssistant.ask()вai_agent.py, который формирует системный промпт черезprompts.py(с подстановкой сегодняшней/завтрашней дат) и отправляет его в Mistral вместе со схемойTOOLS.Mistral решает, нужен ли ему инструмент. Если да,
ai_agent.pyвыполняет вызов через тот же экземплярMCPClient, который используется в ручных вкладках —EmailAssistantникогда не обращается к Gmail/SAP напрямую — и передаёт JSON-результат обратно в диалог.Шаги 1–2 повторяются (поиск, затем, возможно, чтение конкретного сообщения, затем, возможно, ещё один поиск) до
MISTRAL_MAX_STEPSраз (по умолчанию 12).Когда у Mistral достаточно информации, он перестаёт вызывать инструменты и возвращает финальный ответ на естественном языке, который
app.pyотображает в чате — с полным журналом вызовов инструментов в сворачиваемом блоке «Tool calls used» для отладки.
Список инструментов агента намеренно узкий (только чтение Gmail/SAP), поэтому что бы вы ни спросили, он не может отправлять, удалять или изменять что-либо. Только ручные сценарии на вкладке Gmail могут это делать, и каждый из них требует явного шага подтверждения перед выполнением разрушительного действия.
3. Запуск приложения (один раз на процесс)
get_mcp_client() в app.py обёрнут в @st.cache_resource, поэтому он выполняется ровно один раз: создаёт MCPClient, вызывает .connect(), который запускает фоновый поток + цикл событий и открывает сессию Streamable HTTP к FastMCP-серверу. Эта сессия остаётся активной на всё время жизни процесса Streamlit — она не пересоздаётся при каждом повторном выполнении.
Возможности
Gmail (через вкладку «Gmail»)
Список / поиск сообщений с использованием нативного синтаксиса поиска Gmail
Чтение полного сообщения (тело, заголовки, вложения)
Отправка писем, создание черновиков, перемещение сообщений в корзину (каждое действие защищено явным шагом подтверждения в интерфейсе)
Отметка сообщений прочитанными/непрочитанными, список меток, получение байтов вложений
SAP (через вкладку «SAP»)
Проверка конфигурации / подключения к SAP OData sandbox
Список и поиск Business Partners, просмотр одного партнёра
Список email-адресов в системе
(Только чтение по умолчанию — см. SAP writes ниже)
ИИ-ассистент (через вкладку «Ai»)
Агент на базе Mistral (ai_agent.py / EmailAssistant), который отвечает на вопросы на естественном языке, например:
«Резюмируй сегодняшние важные письма»
«Найди письма с вложениями»
«Есть ли у меня собеседования завтра?»
«Резюмируй письма за последние 7 дней»
Агент намеренно только для чтения: он может вызывать только gmail_search_messages, gmail_read_message и gmail_list_messages (плюс операции чтения SAP, описанные в prompts.py). У него нет инструментов для отправки, ответа или удаления чего-либо, и системный промпт явно предписывает ему сообщать об этом, если его спросят — каждый факт в его ответах должен опираться на реальный результат инструмента, а не на выдумку.
Вкладка Administration
Статус живого MCP-подключения, список инструментов, которые сервер в настоящее время предоставляет, и последняя полученная конфигурация Gmail/SAP — полезно для проверки доступности и правильной настройки сервера.
Структура проекта
Файл | Ответственность |
| Streamlit UI — вкладки для AI, Gmail, SAP и Admin |
| MCP-клиент, безопасный для Streamlit (единый постоянный фоновый цикл событий; см. docstring модуля, почему) |
| Цикл агента: отправляет вопрос пользователя + результаты инструментов в Mistral, пока не получит финальный ответ |
| Системный промпт: разрешения инструментов, контекст дат, справочник по синтаксису поиска Gmail, рекомендации по стилю ответов |
| FastMCP-сервер, предоставляющий операции Gmail и SAP как MCP-инструменты |
| Обёртка Gmail API: OAuth-поток, разбор сообщений, операции отправки/черновика/удаления/меток |
| Обёртка SAP OData: чтение Business Partner, Sales Order, Billing Document, Product (записи реализованы, но отключены по умолчанию) |
| Python-зависимости |
Предварительные требования
Python 3.10+
Проект Google Cloud с включённым Gmail API и OAuth-клиентом Desktop app (
credentials.json)Доступ к SAP OData sandbox (например, SAP Business Accelerator Hub) с API-ключом, если вы хотите, чтобы вкладка/инструменты SAP работали
Mistral API-ключ, если вы хотите, чтобы вкладка AI Assistant работала
Настройка
Установите зависимости
python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txtУчётные данные Gmail OAuth
Скачайте
credentials.jsonвашего OAuth-клиента из Google Cloud Console и поместите его вcredentials/credentials.json(или укажите другой путь черезGMAIL_CREDENTIALS_FILE). При первом вызове инструмента Gmail сервер откроет окно браузера для авторизации; полученный токен будет записан вcredentials/token.json.Переменные окружения
Создайте файл
.envв корне проекта:# --- 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=12У каждой переменной есть разумное значение по умолчанию, кроме самих учётных данных/API-ключей — см. начало каждого файла
*_service.py/*_client.pyдля точных значений по умолчанию.Запустите MCP-сервер
python server.pyЭто запустит FastMCP-сервер на
MCP_SERVER_HOST:MCP_SERVER_PORTс использованием транспорта Streamable HTTP.Запустите Streamlit-приложение (во втором терминале)
streamlit run app.pyОткройте URL, который выведет Streamlit (обычно
http://localhost:8501).
SAP writes
SAPService уже реализует create_business_partner и update_business_partner для конечных точек записи SAP OData, но соответствующие MCP-инструменты закомментированы в server.py, а вызовы жёстко ограничены флагом SAP_WRITE_ENABLED=true в sap_service.py. Чтобы включить их:
Установите
SAP_WRITE_ENABLED=trueв.env.Раскомментируйте определения инструментов
sap_create_business_partner/sap_update_business_partnerвserver.py.Перезапустите MCP-сервер.
До этого момента весь доступ к SAP доступен только для чтения, независимо от флага.
Замечания по безопасности
ИИ-ассистент может только читать Gmail — у него нет инструментов отправки/удаления/изменения, что обеспечивается как списком
TOOLSвai_agent.py, так и системным промптом вprompts.py.Отправка писем, создание черновиков и удаление/перемещение в корзину на вкладке Gmail требуют явного подтверждения (чекбокс или сценарий «поиск → открыть → подтвердить») перед выполнением разрушительного действия.
Запись в SAP отключена по умолчанию (
SAP_WRITE_ENABLED=false), и инструменты, которые могли бы её выполнять, даже не регистрируются на MCP-сервере, если вы не включите их явно.
Устранение неполадок
«Could not connect to the MCP server» — убедитесь, что
server.pyзапущен, иMCP_SERVER_URLв вашем.envсоответствует его хосту/порту.Ошибки Gmail OAuth, связанные с устаревшим/недействительным токеном — удалите файл по пути
GMAIL_TOKEN_FILEи повторите попытку; приложение повторно запустит OAuth-поток.Запросы SAP завершаются с HTTP-ошибками — некоторые SAP sandbox-тенанты не активируют все OData-сервисы (например,
API_SALES_ORDER_SRV,API_BILLING_DOCUMENT_SRV) по умолчанию; проверьте тело ошибки в соответствии с вашим каталогом API.«AI assistant is not available» —
MISTRAL_API_KEYотсутствует или пуст в.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