The server defines 10 tools across Gmail, Calendar, and Contacts APIs with complete input schemas and descriptions. However, critical security issues (credentials in parameters), missing output schemas, and vague descriptions for some tools significantly limit production readiness. Naming is generally verb-noun compliant. Parameter descriptions exist but lack format constraints and validation guidance. No evidence of error handling strategies, recovery guides, or destructive operation safeguards. The codebase shows basic MCP structure but lacks polish expected of production-grade agent toolkits.
Tools (10)
create_eventwriteauthsource verified75/100
Create a new calendar event
delete_eventdestructiveauthsource verified70/100
Delete a calendar event
get_user_inforead onlyauthsource verified55/100
Get user information
list_contactsread onlyauthsource verified58/100
List contacts from Google Contacts
list_emailsread onlyauthsource verified73/100
List recent emails from Gmail inbox
list_eventsread onlyauthsource verified73/100
List upcoming calendar events
modify_emailwriteauthsource verified67/100
Modify email labels (archive, trash, mark read/unread)
All tools require 'accessToken' as a string parameter passed by the agent. This is a critical security vulnerability, credentials should never be exposed in tool parameters where they appear in logs, traces, and LLM context. Google API tokens MUST use server-side secret injection via environment variables or a secure vault.
Output schemas are not documented anywhere in the tool definitions or source code. Agents have no way to know what fields to expect from list_emails, create_event, or modify_email responses. This breaks composition, the agent cannot reliably chain results from one tool into the next.
Move accessToken handling server-side: inject Google API credentials via environment variables (GOOGLE_ACCESS_TOKEN or equivalent) at server startup. Remove accessToken as a tool parameter. Use the authenticated client inside handler functions. This eliminates credential exposure in logs.
Document output schemas for all tools. Add a 'returns' or 'outputSchema' field to each tool definition. Example for list_emails: { type: 'object', properties: { emails: { type: 'array', items: { type: 'object', properties: { id: { type: 'string' }, from: { type: 'string' }, subject: { type: 'string' }, snippet: { type: 'string' }, ... } } }, total: { type: 'number' } } }. This enables agents to understand response structure and chain results reliably.
Add tool annotations to all definitions: readOnlyHint: true for list_* and search_* and get_* tools; destructiveHint: true for delete_event; idempotentHint: true only for idempotent operations (e.g., create_event with same parameters multiple times). Update the server.ts tool registration to include these hints in the capability declaration.
Rename 'modify_email' to 'update_email_labels' (or 'modify_email_labels') to clarify that only labels are modified, not content. Keep all parameter names the same.
Add pagination support to list_contacts and list_events: introduce limit (default 20, max 100) and nextToken (or pageToken) parameters. Return total count and nextToken if more results exist. Cap default results at 20 items to prevent context bloat.
Add format constraints to parameter descriptions. Examples: 'maxResults: Must be an integer between 1 and 100 (default: 10).', 'daysBack: Non-negative integer, max 365 days.', 'start/end: ISO 8601 datetime string (e.g., 2024-12-25T14:30:00Z). Timezone assumed UTC if omitted.'
Destructive operations (send_email, delete_event) lack confirmation/dry-run support and have no guidance on irreversibility in their descriptions. An agent can accidentally send emails or delete calendars without safeguards. delete_event description is vague ('Delete a calendar event') and does not emphasize permanence.
'modify_email' name is ambiguous, the description clarifies it modifies labels, but the name alone does not signal this clearly. LLMs may confuse it with a tool that edits email content. Consider rename to 'update_email_labels' for clarity.
list_contacts and get_user_info lack input schema detail. 'list_contacts' has only accessToken as required parameter but provides no pagination (limit, offset, nextToken). Returning all contacts could exceed context windows. 'get_user_info' schema is minimal and undescribed in the visible code.
Parameter descriptions lack format constraints and validation guidance. 'maxResults' has no range (1 - 100?, 1 - 1000?). Date parameters like 'daysBack' and 'daysForward' have no bounds specified. 'start' and 'end' accept 'ISO format' but do not mention timezone behavior or validation rules.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) present in tool definitions. The schema declarations do not signal which tools are read-only vs write vs destructive. Agents cannot distinguish safe discovery calls from risky operations.
No error handling guidance in the source code. The CallToolRequestSchema handler throws McpError for unknown tools but does not guide agents on recovery (e.g., 'Email not found. Try search_emails() with a partial query'). API failures (auth, rate limit, network) have no recovery strategy.
Tool 'send_email' with parameters 'cc' and 'bcc' as comma-separated strings is fragile, agents might add extra spaces or format incorrectly. Consider accepting arrays of email addresses instead (e.g., cc: [string] in schema) to reduce parsing ambiguity.
send_email
Change send_email 'cc' and 'bcc' parameters from strings to arrays: cc: { type: 'array', items: { type: 'string' }, description: 'Email addresses to CC (array of valid email addresses)' }. This removes comma-parsing ambiguity and prevents formatting errors by agents.
Add irreversibility warnings to destructive operations. Update send_email description: 'Send a new email. WARNING: This action is irreversible, once sent, the email cannot be unsent. Consider reviewing the recipient and subject before confirming.' Update delete_event description similarly.
Implement error recovery guidance in handler code. When an API call fails (e.g., email not found), return a structured error with actionable steps. Example: { isError: true, error: 'Email with ID abc123 not found.', suggestion: 'Call search_emails(query="...") to find the email you need.' }. This guides agents to self-correct instead of retrying blindly.
Add permission scopes to tool descriptions. Document what Gmail/Calendar scopes each tool requires (e.g., 'Requires scope: gmail.readonly for reading, gmail.send for sending'). This enables audit trails and least-privilege agent configurations.