聊天MCP谷歌

一个面向生产的Gradio聊天应用程序,将LLM工具调用与八个专注于谷歌的MCP服务器集成在一起:
- Gmail(IMAP/SMTP)
- 谷歌日历(CalDAV)
- 谷歌联系人(CardDAV)
- Google Drive(Drive REST API)
- Google文档(文档REST API+驱动器元数据)
- Google Sheets(Sheets REST API+驱动器文件发现)
- Google幻灯片(幻灯片REST API+驱动器文件发现)
- 谷歌地图(地图/地点/地理编码/方向API)
该应用程序支持两个模型后端:
- 直接Gemini模型通过
google-genai - OpenAI兼容模型通过
BASE_URL和API_KEY
当前的OpenAI兼容(非Gemini)模型:
deepseek-v3-2-251201deepseek-r1-250528glm-4-7-251222kimi-k2-250905kimi-k2-thinking-251104seed-1-8-251228seed-2-0-mini-260215
当前Gemini型号:
gemini-3-flash-previewgemini-3-pro-previewgemini-2.5-progemini-2.5-flashgemini-2.5-flash-lite
主要特点
- Gradio聊天界面,可选择型号。
- 自动MCP工具发现和工具调用。
- 基于意图的MCP工具门控(每次请求只向模型发送相关的服务器工具)。
- 运行时MCP策略注入来自
docs/mcp-servers/*.md进入系统指令。 - OpenAI兼容模型的多轮工具调用编排(工具->工具->最终答案)。
- 集成Gmail、日历、联系人、驱动器、文档、表格、幻灯片和地图操作。
- 自动邀请流程:当提示包括
invite+创建电子邮件和活动后,应用程序通过Gmail MCP发送邀请。 - 日历邀请传递支持
.ics(text/calendar)接受/拒绝流程。 - 驱动器阶段1.1包括文件夹创建、文本上传、移动、用户共享和公共链接创建。
- Docs现在支持Word互操作性:发现
.docx/.doc,阅读.docx直接将Word文件转换为原生Google文档。 - 表阶段2包括电子表格发现、元数据、选项卡管理、范围读/写操作、直接
.xlsx/.xls阅读,.xlsx/.xls转换为原生Google表格、导出、批处理范围操作、电子表格共享、模板复制、CSV导入、图表插入、保护、数据透视表创建和权限审核。 - 模板发现工具可用于文档/表格/幻灯片(
list_document_templates,list_spreadsheet_templates,list_presentation_templates). - 幻灯片阶段1包括演示文稿发现、元数据、幻灯片文本提取、演示文稿创建、文本幻灯片插入、演示文稿共享、导出和PowerPoint
.pptx/.ppt互操作性(发现/读取/转换)。 - 联系人搜索弹性:在以下情况下自动回退到HTTP/1.1
h2不可用。 - 在模型反馈之前截断工具输出,以减少大型工具结果的上下文膨胀。
- 结构化工具结果合同(
success,error,data)在MCP工具执行和模型上下文之间。 - 当所需服务器停机时,在最终响应中请求范围MCP可用性通知。
- OpenAI兼容模型调用的显式超时处理。
- 请求级别指标
metrics.jsonl. - 运行时登录
chat_app.log. - 基于Pydantic的应用程序设置、有效载荷规范化和工具输入验证。
快速开始
Copy-Item .env.template .env
uv sync
uv run python app.py建筑
这 chat_service 流程为:
- 通过stdio启动MCP服务器(
uv run python .py). - 从每个服务器收集工具模式。
- 从用户输入推断意图域,并过滤到相关的服务器工具。
- 注入MCP策略摘要(来自
docs/mcp-servers/*.md)进入系统指令。 - 将用户输入发送到所选模型后端。
- 该模型要么直接响应,要么请求工具调用。
- 执行所请求的MCP工具,将结果标准化为结构化合约,然后将其返回给模型。
flowchart TD
U[User] --> UI[Gradio UI
src/chat_google/ui.py]
UI --> CS[Chat Service
src/chat_google/chat_service.py]
CS --> MCPREG[Initialize MCP sessions
and collect tool schemas]
CS --> ROUTE[Infer intent and filter
relevant MCP tools]
CS --> POLICY[Load MCP policy summary
from docs/mcp-servers]
CS --> LLM[Selected LLM backend
Gemini or OpenAI-compatible]
LLM --> DEC{Tool call needed?}
DEC -- No --> RESP[Direct model response]
DEC -- Yes --> TOOL[Execute requested MCP tool
normalize result contract]
TOOL --> MG[gmail_server.py]
TOOL --> MC[calendar_server.py]
TOOL --> MT[contacts_server.py]
TOOL --> MD[drive_server.py]
TOOL --> MDO[docs_server.py]
TOOL --> MSH[sheets_server.py]
TOOL --> MSL[slides_server.py]
TOOL --> MM[maps_server.py]
MG --> GI[Gmail IMAP/SMTP]
MC --> GC[Google Calendar CalDAV]
MT --> GCT[Google Contacts CardDAV]
MD --> GD[Google Drive REST API]
MDO --> GDO[Google Docs API]
MSH --> GSH[Google Sheets API]
MSL --> GSL[Google Slides API]
MM --> GM[Google Maps APIs]
ROUTE --> LLM
POLICY --> LLM
TOOL --> LLM
RESP --> UI
CS --> L[chat_app.log]
CS --> M[metrics.jsonl]仓库的规划
app.py:UI入口点(向后兼容的包装器)。gmail_server.py:Gmail MCP包装入口点。calendar_server.py:日历MCP包装器入口点。contacts_server.py:联系MCP包装入口点。drive_server.py:驱动MCP包装器入口点。docs_server.py:文档MCP包装器入口点。sheets_server.py:MCP包装纸入口点。slides_server.py:滑动MCP包装器入口点。maps_server.py:映射MCP包装器入口点。src/chat_google/chat_service.py:主编排逻辑。src/chat_google/ui.py:Gradio UI组成和事件连接。src/chat_google/constants.py:模型列表和默认模型解析器。src/chat_google/models.py:共享Pydantic模型。src/chat_google/mcp_servers/*.py:MCP服务器实现。docs/mcp-servers/*.md:作为运行时MCP策略摘要使用的面向代理的MCP使用指南。tests/:全面的异步/单元测试套件。requirements.txt:运行时依赖关系。requirements-dev.txt:运行时+测试依赖关系。pyproject.toml:pytest配置。readme-id.md:指向初级英语的简短指针注释README.md.
先决条件
- Python 3.10+
uv已安装并可用PATH- 谷歌账号:
- 已启用两步验证 - 已启用并生成应用程序密码
- 启用驱动API的谷歌云项目(用于
GOOGLE_DRIVE_ACCESS_TOKEN) - 启用Google Docs API的Google Cloud项目(适用于Docs MCP工具)
- 启用Google Sheets API的Google Cloud项目(适用于Sheets MCP工具)
- 启用Google Slides API的Google Cloud项目(用于Slides MCP工具)
- OAuth客户端凭据(
Desktop app)用于驱动自动刷新流程
- GOOGLE_OAUTH_CLIENT_ID - GOOGLE_OAUTH_CLIENT_SECRET
- 启用地图API的Google Cloud项目(适用于
GOOGLE_MAPS_API_KEY)
配置
使用模板初始化环境变量:
Copy-Item .env.template .env然后编辑 .env:
GOOGLE_ACCOUNT=you@example.com
GOOGLE_APP_KEY=xxxxxxxxxxxxxxxx
GOOGLE_DRIVE_ACCESS_TOKEN=your-drive-access-token
GOOGLE_DRIVE_REFRESH_TOKEN=your-drive-refresh-token
GOOGLE_OAUTH_CLIENT_ID=your-oauth-client-id.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=your-oauth-client-secret
GOOGLE_MAPS_API_KEY=your-google-maps-api-key
GOOGLE_GEMINI_API_KEY=your_gemini_key
BASE_URL=https://ai.sumopod.com
API_KEY=your_api_key
MODEL=seed-2-0-mini-260215变量参考:
GOOGLE_ACCOUNT:Gmail/日历/联系人MCP服务器使用的谷歌帐户。GOOGLE_APP_KEY:谷歌应用程序密码(16个字符,无空格)。GOOGLE_DRIVE_ACCESS_TOKEN:驱动器/文档/表格/幻灯片MCP的OAuth 2.0承载令牌(不是应用程序密码)。GOOGLE_DRIVE_REFRESH_TOKEN:用于自动更新驱动器/文档/表格/幻灯片令牌的可选刷新令牌。GOOGLE_OAUTH_CLIENT_ID:OAuth客户端ID与配对GOOGLE_DRIVE_REFRESH_TOKEN.GOOGLE_OAUTH_CLIENT_SECRET:OAuth客户端密钥与配对GOOGLE_DRIVE_REFRESH_TOKEN.GOOGLE_MAPS_API_KEY:地图MCP工具的谷歌地图API密钥。GOOGLE_GEMINI_API_KEY:对于以开头的模型是必需的gemini.BASE_URL:适用于非Gemini模型的与OpenAI兼容的API基本URL。API_KEY:不记名代币BASE_URL.MODEL:UI下拉列表的初始默认模型(必须存在于可用模型列表中)。
- 如果缺失/无效,应用回退默认值为 seed-2-0-mini-260215.
如何获取Google应用程序密码(个人帐户)
- 打开
https://myaccount.google.com/. - 首选
Security. - 启用
2-Step Verification. - 打开应用程序密码:
https://myaccount.google.com/apppasswords. - 为Mail生成应用程序密码(或自定义应用程序名称)。
- 将生成的16个字符的密码放入
GOOGLE_APP_KEY.
重要提示:
- 应用程序密码仅在启用两步验证时可用。
- 应用程序密码可能会被组织策略(工作区管理)、高级保护或严格的2SV配置阻止。
- 更改Google主帐户密码可能会撤销现有的应用程序密码。
如何获取 GOOGLE_DRIVE_ACCESS_TOKEN (个人账户)
- 打开谷歌云控制台:
https://console.cloud.google.com/. - 创建/选择一个项目,然后启用Google Drive API:
APIs & Services->Library->Google Drive API->Enable. - 配置OAuth同意屏幕(
External适合个人使用),并在需要时将您的帐户添加为测试用户。 - 创建OAuth客户端ID凭据(
Desktop app)inAPIs & Services->Credentials. - 打开OAuth 2.0游乐场:
https://developers.google.com/oauthplayground/. - 单击OAuth Playground中的设置图标并启用
Use your own OAuth credentials,然后输入您的客户端ID/密码。 - 选择范围
https://www.googleapis.com/auth/drive、授权和交换令牌代码。 - 复制
access_token价值进入.env作为GOOGLE_DRIVE_ACCESS_TOKEN.
重要提示:
- 此令牌是OAuth承载令牌,而不是应用程序密码。
- 访问令牌是短暂的(通常在1小时左右)。如果不使用刷新流,请在过期时重新生成。
- 为了长期使用,请设置刷新流变量:
- GOOGLE_DRIVE_REFRESH_TOKEN - GOOGLE_OAUTH_CLIENT_ID - GOOGLE_OAUTH_CLIENT_SECRET
程序化辅助脚本(根):
uv run --with google-auth-oauthlib python get_google_drive_access_token.py --client-secret client_secret.json默认情况下,此脚本现在写入 .env:
GOOGLE_DRIVE_ACCESS_TOKENGOOGLE_DRIVE_REFRESH_TOKEN(如果谷歌返回)GOOGLE_OAUTH_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRET
可选标志:
# only write access token
uv run --with google-auth-oauthlib python get_google_drive_access_token.py --client-secret client_secret.json --no-write-refresh-token --no-write-oauth-client
# print token only (do not modify .env)
uv run --with google-auth-oauthlib python get_google_drive_access_token.py --client-secret client_secret.json --no-write-env此脚本中的默认作用域是完全驱动器访问权限:
https://www.googleapis.com/auth/drive
Google文档、工作表和幻灯片API设置说明
- 启用
Google Docs API在与OAuth凭据相同的GCP项目中。 - 启用
Google Sheets API在同一个GCP项目中。 - 启用
Google Slides API在同一个GCP项目中。 - 中的现有令牌流
get_google_drive_access_token.py(范围https://www.googleapis.com/auth/drive)与此存储库中的文档/表格/幻灯片MCP兼容。 - 文档/表格/幻灯片MCP和驱动器MCP共享相同的令牌环境变量。
如何获取 GOOGLE_OAUTH_CLIENT_ID 和 GOOGLE_OAUTH_CLIENT_SECRET
- 打开谷歌云控制台:
https://console.cloud.google.com/. - 选择您的项目。
- 首选
APIs & Services->Credentials. - 创建OAuth客户端凭据(
Desktop app)如果尚未创建。 - 下载客户端机密JSON文件。
- 从JSON中读取:
- installed.client_id -> GOOGLE_OAUTH_CLIENT_ID - installed.client_secret -> GOOGLE_OAUTH_CLIENT_SECRET
您可以通过运行以下命令来避免手动复制:
uv run --with google-auth-oauthlib python get_google_drive_access_token.py --client-secret client_secret.json它会自动提取和写入这两个值(除非被标志禁用)。
如何获取 GOOGLE_MAPS_API_KEY 以及所需的API
- 打开谷歌云控制台:
https://console.cloud.google.com/. - 为此应用程序创建/选择一个项目。
- 为项目启用计费(谷歌地图平台需要一个活动的计费帐户)。
- 首选
APIs & Services->Library,然后启用这些API:
- Geocoding API - Directions API - Places API (用于文本搜索和位置详细信息)
- 首选
APIs & Services->Credentials->Create Credentials->API key. - 将密钥复制到
.env如:
- GOOGLE_MAPS_API_KEY=your-google-maps-api-key
建议的关键限制:
- 应用限制:
- 对于本地/服务器使用,首选 IP addresses 只允许您的服务器IP。
- API限制:
- 将密钥限制为: - Geocoding API - Directions API - Places API
验证检查表:
GOOGLE_MAPS_API_KEY存在于.env.- 上述3个API与密钥在同一个项目中启用。
- 该项目的计费处于活动状态。
程序化辅助脚本(根):
# One-time auth for script token discovery
gcloud auth login
gcloud auth application-default login
# Create restricted key, enable required APIs, and write GOOGLE_MAPS_API_KEY to .env
uv run python get_google_maps_api_key.py --project YOUR_PROJECT_ID如果 gcloud 如果未安装,请使用OAuth客户端密钥回退:
uv run --with google-auth-oauthlib python get_google_maps_api_key.py --project YOUR_PROJECT_ID --client-secret client_secret.json可选示例:
# Create key without automatic API restrictions
uv run python get_google_maps_api_key.py --project YOUR_PROJECT_ID --no-api-restrictions
# Restrict key to server IP(s)
uv run python get_google_maps_api_key.py --project YOUR_PROJECT_ID --allowed-ip 203.0.113.10
# Do not modify .env (print key only)
uv run python get_google_maps_api_key.py --project YOUR_PROJECT_ID --no-write-env壳牌注意事项:
- 在一个令牌中使用完整标志:
--no-api-restrictions(不要像这样分开--no-api-然后restrictions).
推荐的uv工作流程
为了实现稳定和可重复的设置:
uv sync
uv run python app.py笔记:
uv sync安装/同步项目依赖关系。uv run在解析的环境中执行命令。
运行应用程序
uv run python app.py默认本地URL: http://127.0.0.1:7860
手动运行MCP服务器
uv run python gmail_server.py
uv run python calendar_server.py
uv run python contacts_server.py
uv run python drive_server.py
uv run python docs_server.py
uv run python sheets_server.py
uv run python slides_server.py
uv run python maps_server.pyMCP工具
Gmail
list_recent_emails(count=5)read_email(email_id)summarize_emails(timeframe='24h', label='inbox', count=10)list_unread_emails(count=5)mark_as_read(email_id)list_labels()search_emails_by_label(label, count=5)search_emails(query)send_email(to_email, subject, body)send_calendar_invite_email(to_email, subject, body, summary, start_time, duration_minutes=60, description='', location='')
日历
summarize_agenda(timeframe='24h', days=None)list_events(days=7)add_event(summary, start_time, duration_minutes=60, description='')search_events(query)
注:
add_event仍然没有结构化的与会者/位置字段。- 邀请由Gmail MCP处理(
send_calendar_invite_email)使用ICS数据,以便收件人可以接受/拒绝。
联系人
list_contacts(limit=10)search_contacts(query)
驱动(第1+1.1阶段)
list_drive_files(limit=10, folder_id=None, mime_type=None)search_drive_files(query, limit=10, folder_id=None)get_drive_file_metadata(file_id)read_drive_text_file(file_id, max_chars=8000)(仅限非谷歌工作区文件)list_shared_with_me(limit=10)create_drive_folder(name, parent_id=None)upload_text_file(name, content, parent_id=None)move_drive_file(file_id, new_parent_id)(适用于文件/文件夹)create_drive_shared_link_to_user(item_id, user_email, role='reader', send_notification=True, message='', expires_in_days=7)create_drive_public_link(item_id, role='reader', allow_discovery=False)(文件/文件夹)
文档(阶段1+1.1+Word互操作)
list_docs_documents(limit=10)search_docs_documents(query, limit=10)get_docs_document_metadata(document_id)read_docs_document(document_id, max_chars=8000)create_docs_document(title, initial_content='')append_docs_text(document_id, text)replace_docs_text(document_id, find_text, replace_text='', match_case=False)share_docs_to_user(document_id, user_email, role='reader', send_notification=True, message='')export_docs_document(document_id, export_format='pdf', max_chars=8000)(txt,html,pdf,docx)append_docs_structured_content(document_id, heading='', paragraph='', bullet_items=[], numbered_items=[])replace_docs_text_if_revision(document_id, expected_revision_id, find_text, replace_text='', match_case=False)list_documents(limit=10, include_word=True)(原生文档+可选.docx/.doc)list_document_templates(limit=10, folder_name='Documents', name_contains='template', include_word=True)search_documents(query, limit=10, include_word=True)(原生文档+可选.docx/.doc)get_document_metadata(file_id)(原生文档和Word文件)read_word_document(file_id, max_chars=8000)(直接.docx阅读)convert_word_to_google_doc(file_id, new_title='', move_to_parent=True)(.docx/.doc->本机文档)
图纸(第1+2阶段)
list_sheets_spreadsheets(limit=10)search_sheets_spreadsheets(query, limit=10)get_sheets_metadata(spreadsheet_id)read_sheet_values(spreadsheet_id, range_a1='A1:Z50', max_rows=50, max_cols=20)append_sheet_row(spreadsheet_id, range_a1, values)update_sheet_values(spreadsheet_id, range_a1, values, value_input_option='USER_ENTERED')create_sheets_spreadsheet(title, sheet_title='Sheet1')add_sheet_tab(spreadsheet_id, title, row_count=1000, column_count=26)list_spreadsheets(limit=10, include_excel=True)(本机图纸+可选.xlsx/.xls)list_spreadsheet_templates(limit=10, folder_name='Documents', name_contains='template', include_excel=True)search_spreadsheets(query, limit=10, include_excel=True)(本机图纸+可选.xlsx/.xls)get_spreadsheet_metadata(file_id)(适用于本地表格和.xlsx/.xls)read_excel_values(file_id, sheet_name='', range_a1='A1:Z50', max_rows=50, max_cols=20)(读.xlsx/.xls直接)convert_excel_to_google_sheet(file_id, new_title='', move_to_parent=True)export_google_sheet(file_id, export_format='xlsx', gid=None, range_a1='', max_preview_chars=2000)(xlsx,ods,pdf,zip,csv,tsv)batch_get_sheet_values(spreadsheet_id, ranges, value_render_option='FORMATTED_VALUE', date_time_render_option='SERIAL_NUMBER', max_rows_per_range=20, max_cols_per_row=20)batch_update_sheet_values(spreadsheet_id, updates, value_input_option='USER_ENTERED')share_spreadsheet(file_id, user_email, role='writer', send_notification=True, message='')create_spreadsheet_from_template(template_file_id, new_title, destination_folder_id='')import_csv_to_sheet(spreadsheet_id, sheet_name, csv_text, overwrite=False)insert_sheet_chart(spreadsheet_id, sheet_id, chart_spec)protect_sheet_or_range(spreadsheet_id, sheet_id=None, range_a1='', editors=[], warning_only=False)create_pivot_table(spreadsheet_id, source_range, target_sheet, target_cell='A1', summarize_function='COUNTA')get_spreadsheet_permissions(file_id)
幻灯片(第一阶段)
list_slides_presentations(limit=10)search_slides_presentations(query, limit=10)get_slides_presentation_metadata(presentation_id)read_slides_presentation(presentation_id, max_chars=8000)create_slides_presentation(title, initial_slide_title='')add_text_slide(presentation_id, title, body='')list_presentations(limit=10, include_powerpoint=True)(本机幻灯片+可选.pptx/.ppt)list_presentation_templates(limit=10, folder_name='Documents', name_contains='template', include_powerpoint=True)search_presentations(query, limit=10, include_powerpoint=True)(本机幻灯片+可选.pptx/.ppt)get_presentation_metadata(file_id)(本机幻灯片和.pptx/.ppt)read_powerpoint_document(file_id, max_chars=8000)(直接.pptx阅读)convert_powerpoint_to_google_slides(file_id, new_title='', move_to_parent=True)(.pptx/.ppt->原生幻灯片)share_presentation_to_user(presentation_id, user_email, role='reader', send_notification=True, message='')export_slides_presentation(presentation_id, export_format='pdf', max_chars=8000)(pdf,pptx,txt)
地图
search_places_text(query, limit=5, language='en', region=None)geocode_address(address, limit=3, language='en', region=None)reverse_geocode(latitude, longitude, limit=3, language='en')get_place_details(place_id, language='en')get_directions(origin, destination, mode='driving', alternatives=False, language='en', units='metric', departure_time=None)
测试
使用以下命令运行完整的测试套件 uv:
uv run --with pytest --with pytest-asyncio --with-requirements requirements.txt pytest -q保险范围包括:
- 所有Gmail工具
- 所有日历工具
- 所有联系人工具
- 所有驱动阶段1和阶段1.1工具
- 所有文档工具(包括Word
.docx/.doc互操作流) - 所有图纸工具(包括
.xlsx/.xls读取/转换流) - 所有幻灯片工具(包括PowerPoint
.pptx/.ppt读取/转换流) - 所有地图工具
- 核心聊天编排路径(Gemini、OpenAI兼容、流媒体、工具调用、有效载荷规范化)
- 默认模型解析行为
实时烟雾测试(无用户界面)
使用此功能直接通过以下方式验证真实查询 chat_service (不带Gradio UI):
$env:RUN_LIVE_SMOKE="1"
$env:SMOKE_MODEL="seed-2-0-mini-260215"
$env:SMOKE_PROMPT="find recent emails from social school, summarize"
uv run --with pytest --with pytest-asyncio --with-requirements requirements.txt pytest -q tests/test_live_smoke_no_ui.py -m live_smoke笔记:
- 此测试调用真正的外部API,并可以使用配额。
- 如果
SMOKE_MODEL以...开始gemini,setGOOGLE_GEMINI_API_KEY. - 对于非Gemini型号,设置
BASE_URL和API_KEY. - 一些供应商可能会间歇性返回
429/400在现场吸烟期间;如果需要,请使用其他型号重试。
模板驱动的图纸工作流的示例提示:
$env:RUN_LIVE_SMOKE="1"
$env:SMOKE_MODEL="seed-2-0-mini-260215"
$env:SMOKE_PROMPT="create a new xlsx from template, add column A with date from today until end of year"
uv run --with pytest --with pytest-asyncio --with-requirements requirements.txt pytest -q tests/test_live_smoke_no_ui.py -m live_smoke该提示的预期工具顺序:
sheets.list_spreadsheet_templates(或sheets.search_spreadsheets回退)sheets.create_spreadsheet_from_templatesheets.convert_excel_to_google_sheetsheets.update_sheet_values- 可选验证:
sheets.read_sheet_values
可观测性
chat_app.log:运行时日志、工具调用跟踪、工具持续时间、回退行为和异常堆栈跟踪。metrics.jsonl:按请求遥测:
- 核心领域: timestamp, request_id, model, user_question, duration_seconds, invoked_tools, invoked_servers, status - 错误字段: error_message, tool_errors - status 包括 success_with_tool_errors 当响应完成但一个或多个工具返回错误内容时。 - request_id 格式: - (并发请求的碰撞安全)。
故障排除
- MCP工具不可用
- 确认
uv已安装并处于PATH. - 确认相关性已同步(
uv sync). - 手动启动MCP服务器并检查错误。
- Google身份验证失败
- 验证
GOOGLE_ACCOUNT和GOOGLE_APP_KEY. - 确认启用了两步验证。
- 如果需要,重新生成应用程序密码。
- Gemini请求失败
- 检查
GOOGLE_GEMINI_API_KEY. - 确认型号名称以开头
gemini.
- 非Gemini请求失败
- 验证
BASE_URL和API_KEY. - 确认您的端点支持聊天完成和工具调用。
- 该应用程序现在支持非双子座模型的多轮工具调用;如果查询非常宽泛并且超时,请使用较窄的提示重试。
- 邀请流量期望
- 如果提示包括
invite应用程序在事件创建后尝试发送ICS邀请电子邮件。 - 若无法使用日历邀请传递,应用程序将退回到纯文本电子邮件。
- 检查
metrics.jsonlinvoked_tools为了send_calendar_invite_email或send_email.
- 联系人搜索显示“技术问题”
- 联系人服务器现在会在以下情况下自动禁用HTTP/2
h2缺少,因此它仍然可以通过HTTP/1.1运行。 - 如果 Google CardDAV
REPORT搜索返回5xx,服务器自动回退到PROPFIND+本地过滤。 - 检查
chat_app.log对于包含以下内容的行search_contacts REPORT failed和fallback PROPFIND completed.
- 401/403驱动工具故障
- 检查
GOOGLE_DRIVE_ACCESS_TOKEN已设置且未过期。 - 建议配置刷新流以避免手动续订令牌:
- GOOGLE_DRIVE_REFRESH_TOKEN - GOOGLE_OAUTH_CLIENT_ID - GOOGLE_OAUTH_CLIENT_SECRET
- 确保在您的Google Cloud项目中启用了Drive API。
- 确保OAuth范围包括
https://www.googleapis.com/auth/drive(默认脚本作用域)。 - 记得:
GOOGLE_APP_KEY无法用于驱动器API。 - 如果写/共享/公共链接工具在403时失败,请使用完整的驱动器范围重新生成令牌。
- 谷歌文档工具401/403失败
- 确保Google Docs API已在您的Google Cloud项目中启用。
- 确保令牌包括文档/驱动器访问权限(现有驱动器全范围兼容)。
- 确保经过身份验证的帐户可以访问目标文档。
.docx/.doc无法使用读取文件read_docs_document
read_docs_document仅适用于原生Google文档(application/vnd.google-apps.document).- 使用
read_word_document为了.docx文件夹。 - 对于遗产
.doc,跑convert_word_to_google_doc首先,然后使用read_docs_document.
- 谷歌表格工具失败401/403
- 确保Google Sheets API已在您的Google Cloud项目中启用。
- 确保令牌包括工作表/驱动器访问权限(现有驱动器全范围兼容)。
- 确保经过身份验证的帐户可以访问目标电子表格。
.xlsx/.xls文件不可读read_sheet_values
read_sheet_values仅适用于本机Google表格(application/vnd.google-apps.spreadsheet).- 使用
read_excel_values为了.xlsx/.xls文件,或运行convert_excel_to_google_sheet第一。
export_google_sheet返回错误或空预览
export_google_sheet仅导出本地Google表格文件;转换.xlsx/.xls第一。csv/tsv预览是文本。二进制格式(xlsx,ods,pdf,zip)返回元数据和字节大小,不进行二进制预览。
protect_sheet_or_range/create_pivot_table/insert_sheet_chart因权限错误而失败
- 确保令牌范围包括完全驱动器访问权限(
https://www.googleapis.com/auth/drive)并且启用了Sheets API。 - 确保您的帐户具有对电子表格的编辑权限(查看者/评论者无法编写结构更新)。
- 谷歌幻灯片工具失败401/403
- 确保Google Slides API已在您的Google Cloud项目中启用。
- 确保令牌包括幻灯片/驱动器访问权限(现有驱动器全范围兼容)。
- 确保经过身份验证的帐户可以访问目标演示文稿。
.pptx/.ppt文件不可读read_slides_presentation
read_slides_presentation仅适用于原生Google幻灯片(application/vnd.google-apps.presentation).- 使用
read_powerpoint_document为了.pptx文件夹。 - 对于遗产
.ppt,跑convert_powerpoint_to_google_slides第一。
export_slides_presentation返回错误或空预览
export_slides_presentation仅导出本机Google幻灯片文件;转换.pptx/.ppt第一。- 二进制格式(
pdf,pptx)返回元数据和字节大小,不进行二进制预览。
- 响应包括关于MCP服务器不可用的警告
- 当您的请求域需要一个初始化失败的服务器时,就会出现这种情况。
- 检查
chat_app.log行包含Failed to start MCP server. - 手动启动受影响的服务器(
uv run python _server.py)然后重试。
- 实时烟雾查询失败
Error: 429或Gemini API error (400)
- 这通常是提供商端的配额/速率限制/验证,而不是MCP工具逻辑。
- 用另一个模型重试相同的提示。
- 当提供者不稳定阻止聊天级别烟雾时,直接使用服务器工具验证MCP行为。
- 模板查询在中未返回任何结果
Documents
list_*_templates默认为name_contains='template'.- 如果您的文件中不包含单词
template,重新运行name_contains=''. - 回退查询模式:
- 首次运行
list_*_templates(..., name_contains='template') - 然后运行
search_*或list_*_templates(..., name_contains='')以扩大发现。
- 创建
.xlsx来自模板,但无法使用表格API编写
.xlsx不是原生的谷歌表格。- 使用
convert_excel_to_google_sheet首先,然后写update_sheet_values/append_sheet_row.
安全说明
- 永不承诺
.env. - 将日志和指标视为潜在的敏感数据。
- 仅在受信任的环境中运行此应用程序。
