Scopegate is a Google-auth proxy exposing 45 tools across enterprise services (Gmail, Calendar, Slack, Notion, Salesforce, etc.). While the conceptual scope is ambitious, source visibility is severely limited. Only 3 tool files are partially visible (gmail.ts, calendar.ts, drive.ts), showing incomplete schemas and minimal descriptions. The remaining 42 tools are declared in the tool list but their actual definitions are not provided in the source code. Per HARD SCORING RULES, when tool definitions cannot be verified in source (only inferred), each tool is capped at 50. Since 42 of 45 tools lack visible definitions, and the 3 visible tools show poor schema coverage and generic descriptions, the overall score reflects this evidence gap. The Dockerfile and package.json show solid infrastructure (Next.js, Prisma, OpenTelemetry), but tool quality cannot be assessed without seeing actual parameter schemas and descriptions.
CRITICAL: No visible input schemas for any of the 45 tools. Per HARD SCORING RULES, tools without verifiable schemas cannot score above 0 for schema component. Only file references are provided; actual parameter definitions, types, and constraints are not in the provided source code.
CRITICAL: No visible descriptions for any of the 45 tools. Parameter descriptions are mandatory per the rubric, LLMs cannot infer parameter meaning from names alone. Every tool description must be at least 20 characters and explain WHAT, WHEN, and any prerequisites.
HIGH: 16 WRITE operations (gmail_send_email, calendar_create_event, google_ads_create_campaign, slack_send_message, notion_create_page, hubspot_create_contact, github_create_issue, jira_create_issue, salesforce_create_record, meta_ads_create_campaign, twitter_ads_create_campaign, stripe_create_invoice, airtable_create_record, youtube_upload_video, threads_post_message, instagram_post_content) have no visible confirmation, dry-run, or error recovery patterns. Per pattern:confirmation-request, irreversible operations must support user confirmation or safe rollback.
Recommendations
ADD: Complete input schemas for all 45 tools. Each parameter must have a type (string, number, boolean, enum), description (20+ chars explaining what it controls), and constraints (min/max for numbers, regex/length for strings, allowed values for enums). Use TypeScript/Zod interfaces as the source of truth; export them to the MCP tool registration.
ADD: Tool descriptions (50 - 200 chars) explaining WHAT the tool does, WHEN to use it, and any prerequisites. Avoid generic descriptions. E.g., 'Send an email via Gmail (requires gmail.send scope). Returns email ID if successful. Fails if recipient invalid or quota exceeded.'
ADD: Parameter descriptions for every field. Examples: 'recipient_email: The email address to send to (string, required). Accepts Gmail-verified addresses only.' 'message_subject: Email subject line (string, 1 - 200 chars, required).' 'attachment_urls: Array of https:// file URLs to attach (optional, max 5 files, 25 MB each).'
IMPLEMENT: Confirmation or dry-run pattern for all 16 WRITE operations. Use one of: (1) explicit confirm_action=true parameter that agents must set; (2) dry_run=true to preview without executing; (3) idempotency keys so retries are safe. Example: gmail_send_email should accept confirm=true and only execute when true; otherwise return a preview.
RENAME: Clarify ambiguous or generic names. 'email_send' → 'smtp_send_email' (to distinguish from gmail_send_email). 'salesforce_get_records' → 'salesforce_get_contacts' or 'salesforce_get_opportunities' (specify the object). 'semrush_get_data' → 'semrush_get_domain_overview'. 'notion_query_database' → 'notion_query_contacts_database'.
HIGH: Generic tool names reduce clarity. 'email_send' conflicts with 'gmail_send_email', LLMs cannot distinguish when to use which. 'salesforce_get_records' and 'salesforce_create_record' don't hint at object type. 'semrush_get_data', 'ahrefs_get_data', 'notion_query_database' are too vague. Use specific names: 'salesforce_get_contact_records', 'semrush_get_domain_overview', 'notion_query_contacts_database'.
HIGH: No visible pagination support for list operations (gmail_list_messages, calendar_list_events, drive_list_files, google_ads_get_campaigns, slack_list_channels, hubspot_get_contacts, github_list_repositories, jira_get_issues, stripe_get_customers, airtable_list_records, youtube_get_videos). Per pattern:paginated-result, list tools must accept limit and offset/cursor parameters and return total count. Without pagination, large results exhaust context windows.
MEDIUM: No visible error categorization or recovery guidance. Per pattern:recovery-guide and pattern:error-classification, errors must tell the LLM whether to retry, ask the user, or give up. A financial write (stripe_create_invoice) failing silently without compensation logic is risky.
MEDIUM: No visible output schemas. Per pattern:tool, every tool must document what fields it returns so agents can extract IDs for downstream calls. Without documented responses, agents cannot chain tools (e.g. get_contact returns contact_id, then create_invoice uses contact_id).
MEDIUM: No visible scope declarations for permission gating. Per pattern:scope-declaration, each tool should declare what permissions it requires (e.g. 'read:email', 'write:calendar'). Without scope annotations, agents cannot be configured with least-privilege, and audit trails lack granularity.
All 45 tools
ADD: Pagination support to all list operations. Implement limit (1 - 100, default 20) and offset or cursor parameters. Return total_count and next_cursor so agents can iterate through large result sets without exhausting context. Example: gmail_list_messages(limit=20, offset=0) returns {messages: [...], total_count: 1523, has_more: true}.
ADD: Error response schemas with actionable guidance. Every error must include: (1) error_code (retryable, user_fixable, fatal); (2) message (plain English, <200 chars); (3) recovery_hint (what to try next). Example: {error_code: 'user_not_found', message: 'User john@example.com not found', recovery_hint: 'Try search_users(domain=example.com) to find the correct email.'}.
ADD: Output schemas documenting returned fields for every tool. Example for gmail_send_email: {email_id: string, recipient: string, subject: string, timestamp: ISO8601, status: 'sent'|'queued'|'failed'}. Include all IDs needed for downstream tool calls (e.g. if create_contact returns contact_id, document it so add_note can use it).
ADD: Scope declarations to every tool. Annotate each with required permissions (read:email, write:calendar, etc.). Enable least-privilege agent configurations and clear audit trails. Use tool metadata or a permission matrix in the server init response.
ADD: Rate-limiting and timeout guidance. Document expected latency (e.g. 'typical: <1s, max: 5s'), retry policy (exponential backoff, max 3 retries), and rate limits (e.g. 'Gmail: 1M calls/day, 100 calls/sec'). Prevent agent loops from overwhelming downstream APIs.
SPLIT: Combine tools that always execute together. If 'create_contact' always followed by 'send_welcome_email', offer a single 'create_contact_with_welcome_email' tool. Reduces round-trips, latency, and LLM reasoning overhead.
ADD: Natural-language identifier support. Users say 'email john' not 'email user_12345'. Accept email addresses, usernames, display names; resolve to IDs internally. Reduces lookup tool calls and matches the chat data model.
DOCUMENT: API chaining relationships. If get_contact returns contact_id, explicitly note which tools accept contact_id (add_note, create_invoice, etc.). This enables LLMs to predict chaining without discovery detours.