Multi-server MCP implementation for Google Calendar, Gmail, and restaurant ordering automation
The server defines 13 tools across Google Calendar, Gmail, and a food ordering domain. While schemas are partially present for most tools, critical gaps exist: (1) Many tool descriptions are under 20 chars or missing substance, e.g., list_calendars is 'List calendars for the authorized user' (40 chars, bare minimum), list_events lacks context about when to use it vs other discovery tools; (2) Parameters lack descriptions in several tools, e.g., order_food_item has 'customizations' with only 'Item customizations' and no format guidance; (3) Error handling is completely absent, tools return raw errors without recovery guidance; (4) Output schemas are not documented, forcing LLMs to infer structure; (5) No tool annotations (readOnlyHint, destructiveHint) despite obvious distinctions between read (list_events) and write (send_email, create_event) operations; (6) Tool composition is weak, no idempotency guarantees, no clear chaining IDs in responses. The code shows basic registration with z.object() schemas but lacks the LLM-optimized descriptions required for A-tier quality.
Browse the restaurant menu to see available items
Complete your order and proceed to payment
Remove all items from your cart
Create a Google Calendar event with ISO datetimes and automatic color coding
Create a recurring Google Calendar event with RRULE pattern and automatic color coding
View current items in your cart
Retrieve a specific email by ID with full content
Tool descriptions are minimal and lack LLM-optimized context. Examples: 'List calendars for the authorized user' (40 chars), 'View current items in your cart' (30 chars), 'Complete your order and proceed to payment' (42 chars). These descriptions fail to explain WHEN to call the tool, WHAT it returns, or how it differs from similar tools. LLM selection accuracy will be poor.
Output schemas are completely undocumented. The code shows tools returning JSON via McpServer responses (e.g., list_calendars returns {calendars: [{id, summary}]}), but no formal output schema is declared. LLMs cannot plan downstream calls or extract the right fields without documented return types.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 45 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 44 | - | v1 |
List calendars for the authorized user
List emails from Gmail with optional filtering
List events from a calendar with optional filtering
Add a food item to your order from the restaurant menu
Search emails using Gmail search syntax
Compose and send an email
No tool annotations present (readOnlyHint, destructiveHint, idempotentHint). The server has clear read-only tools (list_*, get_*, search_*, browse_menu, get_cart) and destructive tools (send_email, create_event, delete operations), but does not annotate them. This prevents agents from reasoning about side effects and retry safety.
Error handling provides no recovery guidance. The code shows generic try-catch blocks returning raw errors ('Error: ' + message) without categorizing them as retryable, user-fixable, or fatal. Example from list_calendars: 'Error: ' + err.message tells the agent nothing about what to try next.
Parameter 'customizations' in order_food_item lacks format guidance. Described only as 'Item customizations (e.g., {'size': 'large', 'milk': 'oat'})', example values in descriptions are an anti-pattern (LLMs latch onto them literally). Should specify object schema with known keys or define customization format formally.
No pagination or result limits documented. list_events accepts maxResults (default 10) but list_emails has no explicit limit guidance in the description. search_emails lacks a default. Without documented limits and pagination guidance, agents risk requesting thousands of items, blowing context windows.
Enum constraints missing from parameters. 'format' in get_email declares enum [full, metadata, minimal, raw], good. But 'orderBy' in list_events is correct. However, many parameters that should be enums are not: 'category' in browse_menu could be a closed set of menu categories; 'q' in list_emails should clarify Gmail query syntax; 'timeZone' in create_event is a free string, not constrained to IANA TZ identifiers.
Tool composition breaks across domains. The server mixes Google Calendar/Gmail (authentication via Google OAuth) with food ordering (presumably a local/mock API with different auth). No documentation explains how credentials are managed, whether ordering tools use the same auth, or what happens if one domain's connection fails. This risks silent partial failures.
Idempotency not addressed. create_event and create_recurring_event have no idempotency key or deduplication logic. If an agent retries a failed create_event call, a duplicate event is created. Destructive operations (send_email, checkout) are similarly at risk.
No confirmation/dry-run for irreversible operations. send_email and checkout are high-stakes operations (send email, process payment) with no opportunity for agent self-correction before execution. No dry_run or confirm_before_execute pattern is implemented.