PR #37 Review Guide
Documents a pull request that adds graceful degradation, fixes a sandbox argument mutation bug, and upgrades FastMCP to 3.2.4.
What this file does
Documents a pull request that adds graceful degradation, fixes a sandbox argument mutation bug, and upgrades FastMCP to 3.2.4.
When to use it
- Reviewing PR #37 in dipseth/google_workspace_fastmcp2
- Understanding how to implement degraded mode for MCP servers
- Checking for stale argument leakage in sandbox sessions
- Aligning tool documentation with optional parameter defaults
Assumes this stack
PR #37 Review Guide
Overview
This PR brings the reaserch_trm_mw branch into main via pr/migrate-to-public. It spans TRM research, module wrapper improvements, and server hardening work across multiple sessions.
Key Changes to Review
1. Graceful Degradation (High Impact)
Files: adapters/module_wrapper/__init__.py, qdrant_mixin.py, embedding_mixin.py, search_mixin/_base.py, lifespans/server_lifespans.py
Server now starts with all 96 tools even when Qdrant/embeddings are down. ModuleWrapper enters degraded mode — in-memory introspection works, vector search returns empty results, lazy reconnection recovers when services come back.
Validated: Server starts with Qdrant unreachable, card/email tools register and work with in-memory fallbacks, normal mode unchanged.
2. Stale Sandbox Argument Fix (Bug Fix)
File: middleware/sampling_middleware.py
The argument recovery middleware was mutating context.message.arguments in-place (.clear()/.update()), causing args from prior tool calls to leak into subsequent calls within the same sandbox session. Changed to dict reassignment.
Validated: Sequential search_gmail_messages → send_dynamic_card → compose_dynamic_email calls in sandbox — no arg leakage.
3. Tool Docs Alignment (Developer Experience)
Files: gchat/card_tools.py, skills/server_skill_generator.py, gchat/wrapper_setup.py, gmail/email_wrapper_setup.py
send_dynamic_cardnow usesUserGoogleEmail = None(middleware auto-injects, LLMs don't need to pass it)- All hardcoded Unicode symbols in skill templates/examples converted to dynamic functions pulling from
wrapper.symbol_mapping - Parameter tables updated with
user_google_email, email content separation guidance
4. FastMCP 3.2.4 Upgrade
File: uv.lock
Security fixes (FileUpload validation, header forwarding), task auth scoping, Gemini compatibility.
5. Supporting Fixes
middleware/tag_based_resource_middleware.py— Forms resourcelist_toolset toNone(requiresform_id)- Lint: all E741/E731 errors fixed across research and diagnostic-ui code
- Format: entire codebase formatted with
ruff format
What's NOT Changed
- Google API tool behavior (Gmail, Drive, Docs, Sheets, Calendar, etc.) — unchanged
- Authentication flows — unchanged
- Payment middleware — unchanged
- DSL parser — unchanged
Test Results
| Suite | Result |
|---|---|
| Module unit tests | 480 passed, 28 skipped, 0 failed |
| Client tests | 21 passed, 1 pre-existing failure (test_list_tools count assertion in code mode) |
| Live server validation | send_dynamic_card and compose_dynamic_email both succeed |
| Degraded mode | Server starts and tools register with Qdrant down |
| Lint | ruff check passes clean |
| Format | ruff format --check passes clean |
Merge Checklist
- CI passes (lint + format + tests)
- No breaking changes to tool signatures (UserGoogleEmail is Optional with default=None)
- Graceful degradation tested in both degraded and normal modes
- Stale arg fix validated with sequential sandbox calls
- All 96 tools register on server startup
- Live tool calls succeed (card sent to Testing space, email drafted)
What's inside
Overview, 5 key change sections, test results table, and a 6-item merge checklist.
Change this for your project
- Replace
dipseth/google_workspace_fastmcp2with your repository name - Replace
pr/migrate-to-publicwith your target branch name - Replace
reaserch_trm_mwwith your source branch name
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Degraded mode pattern: server starts with all tools even when dependencies are down
- Argument recovery fix: reassign dict instead of mutating in-place to prevent cross-call leaks
Related Documents
Setup & Deployment Checklist
Guides you through 10 phases to set up, test, deploy, and customize a content agent system using OpenRouter and Streamlit.
RealDiag Demo Video Script
Provides a complete 5-7 minute demo video script for a clinical decision support tool, including timing, visual cues, and production notes.
📱 Mobile Phone Preview - Quick Start
Walks you through four ways to preview a React Native Expo app on real devices and emulators, plus a testing checklist and troubleshooting guide.
🚀 Product Hunt Launch Prep
Provides a Product Hunt launch checklist, listing copy, and newsletter template for an open-source AI vulnerability database.