FastMCP server exposing data connectors (Gmail, Google Sheets, Notion, Stripe, etc.) as standardized MCP tools for a LangGraph-based Business Intelligence agent
All 12 tools follow a repetitive pattern (list_resources, read, search) across 4 connectors. Naming is verb-first and consistent, but descriptions are minimal (15-20 chars) and lack context for LLM selection. Input schemas are present with basic types and descriptions, but output schemas are completely undocumented. No error handling guidance, no pagination info, no chaining IDs returned. Parameter descriptions are generic ('The user ID', 'The resource ID') without format constraints or examples of valid values. Tools appear to be dynamically registered via a factory pattern, making it difficult to verify actual schema compliance in the source.
List resources the user can access in gmail.
Read the contents of one gmail resource by id.
Search gmail for resources matching a query.
List resources the user can access in google_sheets.
Read the contents of one google_sheets resource by id.
Search google_sheets for resources matching a query.
List resources the user can access in notion.
Output schemas completely undocumented. Tools return list[dict[str, Any]] or dict[str, Any] with no field definitions, forcing LLMs to guess structure and breaking downstream tool chaining.
Descriptions are 15 - 20 characters, below the 50-char minimum for LLM selection. 'List resources the user can access in gmail.' lacks context on when to call this vs search, what structure is returned, or prerequisites.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 47 | <=2025-11-25 | v2 |
Read the contents of one notion resource by id.
Search notion for resources matching a query.
List resources the user can access in stripe.
Read the contents of one stripe resource by id.
Search stripe for resources matching a query.
Parameter descriptions are generic and lack format constraints. 'The user ID' does not specify format (email, UUID, numeric), valid range, or how to obtain it. 'The resource ID' is equally vague.
No pagination support documented. list_resources and search return list[dict] with no limit, offset, or total_count fields. Large result sets will blow context windows.
No error handling guidance. Tools return dict[str, Any] on success but no documented error responses, recovery steps, or retry logic for LLMs.