Gmail-SAP-MCP-Assistant
Gmail + SAP MCP Assistant
一个 Streamlit 应用程序,可让您读取和管理 Gmail、浏览 SAP 业务伙伴 / 销售 / 计费 / 产品数据,并通过一个 Model Context Protocol(MCP)服务器向 AI 助手提出关于收件箱(以及 SAP 记录)的自然语言问题。
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)UI 从不直接与 Gmail 或 SAP 通信——每个操作,无论是按钮点击还是 AI 助手决定执行的操作,都经过相同的 MCPClient → FastMCP 服务器 → 服务层路径。这就在应用与两个外部系统之间保持了单一、可审计的边界。
请求流程
请求进入系统有两种方式,它们在 MCPClient 处汇合。
1. 直接 UI 操作(Gmail / SAP / 管理标签页)
您点击一个按钮(例如 Gmail 标签页中的“搜索”)。
app.py直接调用共享的MCPClient实例上的方法,例如mcp_client.gmail_search_messages(query, max_results)。MCPClient将该协程调度到其专用的后台事件循环上,并阻塞直到完成(mcp_client.py中的_loop.run(...))——这保证了 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 密钥)——并返回解析后的纯字典结果。结果沿原路返回:MCP 服务器 →
MCPClient._unwrap()→app.py,后者将其存储在st.session_state中并渲染。
任何层的错误(MCPToolError、MCPConnectionError 或任何意外错误)都由 app.py 中的 run_action() 集中捕获,并显示为 st.error,因此失败的调用绝不会导致 UI 崩溃。
2. AI 助手问题(Ai 标签页)
这是相同的管道,只是前面多了一个决策循环:
您的问题(连同聊天历史)发送到
ai_agent.py中的EmailAssistant.ask(),后者通过prompts.py构建系统提示(注入今天/明天的日期),并将其与TOOLS模式一起发送给 Mistral。Mistral 决定是否需要工具。如果需要,
ai_agent.py通过与手动标签页相同的MCPClient实例执行调用——EmailAssistant从不直接与 Gmail/SAP 通信——并将 JSON 结果反馈到对话中。步骤 1–2 重复(搜索,然后可能读取特定消息,然后可能再次搜索),最多
MISTRAL_MAX_STEPS次(默认 12)。一旦 Mistral 获得足够信息,它停止调用工具并返回最终的自然语言答案,
app.py在聊天中渲染该答案——完整的工具调用轨迹可在可折叠的“使用的工具调用”展开器中查看,便于调试。
代理的工具列表刻意保持狭窄(只读的 Gmail/SAP 查询),因此无论您问什么,它都无法发送、删除或修改任何内容。只有 Gmail 标签页中的手动流程才能执行这些操作,并且每个破坏性操作在触发前都需要明确的确认步骤。
3. 应用启动(每个进程一次)
app.py 中的 get_mcp_client() 被 @st.cache_resource 包装,因此它只运行一次:它创建 MCPClient,调用 .connect(),后者启动后台线程 + 事件循环,并打开到 FastMCP 服务器的 Streamable HTTP 会话。该会话在 Streamlit 进程的整个生命周期内保持活动——它不会在每次重跑时重新创建。
功能
Gmail(通过“Gmail”标签页)
使用 Gmail 原生搜索语法列出 / 搜索消息
读取完整消息(正文、标头、附件)
发送电子邮件、创建草稿、将消息移至回收站(每个操作都在 UI 中通过明确的确认步骤把关)
将消息标记为已读/未读、列出标签、获取附件字节
SAP(通过“SAP”标签页)
检查与 SAP OData 沙箱的配置 / 连接性
列出和搜索业务伙伴、查看单个伙伴
列出存档的电子邮件地址
(默认只读——请参阅下面的 SAP 写入)
AI 助手(通过“Ai”标签页)
一个由 Mistral 驱动的代理(ai_agent.py / EmailAssistant),可回答自然语言问题,例如:
“总结今天的重要电子邮件”
“查找包含附件的电子邮件”
“我明天有面试安排吗?”
“总结过去 7 天的电子邮件”
该代理刻意只读:它只能调用 gmail_search_messages、gmail_read_message 和 gmail_list_messages(以及 prompts.py 中描述的只读 SAP 查询)。它没有发送、回复或删除任何内容的工具,系统提示明确指示它在被问到时说明这一点——其答案中的每个事实都必须追溯到实际的工具结果,绝不能是编造的。
管理标签页
实时的 MCP 连接状态、服务器当前公开的工具列表,以及最近获取的 Gmail/SAP 配置——用于验证服务器是否可访问且配置正确。
项目布局
文件 | 职责 |
| Streamlit UI——AI、Gmail、SAP 和管理标签页 |
| Streamlit 安全的 MCP 客户端(单个持久后台事件循环;有关原因,请参阅模块文档字符串) |
| 代理循环:将用户的问题 + 工具结果发送给 Mistral,直到它产生最终答案 |
| 系统提示:工具权限、日期上下文、Gmail 搜索语法参考、答案风格指南 |
| FastMCP 服务器,将 Gmail 和 SAP 操作公开为 MCP 工具 |
| Gmail API 包装器:OAuth 流程、消息解析、发送/草稿/删除/标签操作 |
| SAP OData 包装器:业务伙伴、销售订单、计费文档、产品读取(写入已实现但默认禁用) |
| Python 依赖项 |
先决条件
Python 3.10+
一个启用了 Gmail API 并具有 OAuth 桌面应用客户端(
credentials.json)的 Google Cloud 项目如果希望 SAP 标签页/工具正常工作,需要访问 SAP OData 沙箱(例如 SAP Business Accelerator Hub)并具有 API 密钥
如果希望 AI 助手标签页正常工作,需要 Mistral API 密钥
设置
安装依赖项
python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txtGmail OAuth 凭据
从 Google Cloud Console 下载您的 OAuth 客户端的
credentials.json,并将其放在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这将使用 Streamable HTTP 传输在
MCP_SERVER_HOST:MCP_SERVER_PORT上启动 FastMCP 服务器。运行 Streamlit 应用(在第二个终端中)
streamlit run app.py打开 Streamlit 打印的 URL(通常为
http://localhost:8501)。
SAP 写入
SAPService 已经实现了针对 SAP OData 写入端点的 create_business_partner 和 update_business_partner,但相应的 MCP 工具在 server.py 中被注释掉了,并且调用在 sap_service.py 中被 SAP_WRITE_ENABLED=true 硬性把关。要启用它们:
在
.env中设置SAP_WRITE_ENABLED=true。取消注释
server.py中的sap_create_business_partner/sap_update_business_partner工具定义。重启 MCP 服务器。
在此之前,无论标志如何,所有 SAP 访问都是只读的。
安全说明
AI 助手只能读取 Gmail——它没有发送/删除/修改工具,这在
ai_agent.py的TOOLS列表和prompts.py的系统提示中都得到了强制。在 Gmail 标签页中发送电子邮件、创建草稿以及删除/移至回收站消息,每个操作都需要明确的确认复选框或“搜索 → 打开 → 确认”流程,然后破坏性操作才会触发。
SAP 写入默认关闭(
SAP_WRITE_ENABLED=false),并且执行这些操作的工具甚至不会在 MCP 服务器上注册,除非您选择启用。
故障排除
“无法连接到 MCP 服务器”——确保
server.py正在运行,并且.env中的MCP_SERVER_URL与其主机/端口匹配。Gmail OAuth 错误提到令牌过期/无效——删除
GMAIL_TOKEN_FILE处的文件并重试;应用将重新运行 OAuth 流程。SAP 请求因 HTTP 错误失败——某些 SAP 沙箱租户默认未激活每个 OData 服务(例如
API_SALES_ORDER_SRV、API_BILLING_DOCUMENT_SRV);请对照您的 API 目录检查错误正文。“AI 助手不可用”——
.env中缺少MISTRAL_API_KEY或为空。
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