Skip to content

Latest commit

 

History

History
236 lines (173 loc) · 9.17 KB

File metadata and controls

236 lines (173 loc) · 9.17 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Overview

Google Calendar MCP Server - A Model Context Protocol (MCP) server providing Google Calendar integration for AI assistants. Built with TypeScript, supports both stdio and HTTP transports, with OAuth 2.0 authentication.

Development Commands

npm install              # Install dependencies
npm run build            # Build with esbuild (outputs to build/)
npm run dev              # Show interactive development menu with all commands
npm run lint             # TypeScript type checking (no emit)

# Testing - Quick Start
npm test                             # Unit tests only (no auth required)
npm run test:watch                   # Unit tests in watch mode
npm run dev test:integration:direct  # Direct integration tests (recommended for dev)
npm run dev coverage                 # Generate test coverage report

# Testing - Full Suite (rarely needed, incurs LLM usage costs)
npm run dev test:integration:claude  # Claude + MCP integration (requires CLAUDE_API_KEY)
npm run dev test:integration:openai  # OpenAI + MCP integration (requires OPENAI_API_KEY)
npm run dev test:integration:all     # All integration tests (requires all API keys)

# Authentication
npm run auth                # Authenticate main account
npm run dev auth:test       # Authenticate test account (for integration tests)
npm run dev account:status  # Check authentication status

# Running the server
npm start                        # Start with stdio transport
npm run dev http                 # Start HTTP server on localhost:3000
npm run dev http:public          # HTTP server accessible from any host

Architecture

Handler Architecture

All MCP tools follow a consistent handler pattern:

  1. Handler Registration: Handlers are auto-registered via src/tools/registry.ts
  2. Base Class: All handlers extend BaseToolHandler from src/handlers/core/BaseToolHandler.ts
  3. Schema Definition: Input schemas defined in src/tools/registry.ts using Zod
  4. Handler Implementation: Core logic in src/handlers/core/ directory

Request Flow:

Client → Transport Layer → Schema Validation (Zod) → Handler → Google Calendar API → Response

Adding New Tools

  1. Create handler class in src/handlers/core/YourToolHandler.ts:

    • Extend BaseToolHandler
    • Implement runTool(args, accounts) method where accounts is Map<string, OAuth2Client>
    • Use this.getCalendar(accounts) to get Calendar API client
    • Use this.handleGoogleApiError(error) for error handling
  2. Define schema in src/tools/registry.ts:

    • Add to ToolSchemas object with Zod schema
    • Add to ToolRegistry.tools array with name, description, handler class
  3. Add tests:

    • Unit tests in src/tests/unit/handlers/YourToolHandler.test.ts
    • Integration tests in src/tests/integration/ if needed

No manual registration needed - handlers are auto-discovered by the registry system.

Authentication System

  • OAuth 2.0 with refresh token support
  • Multi-account: Supports multiple accounts with friendly nicknames (e.g., work, personal). Use the manage-accounts tool in chat, or npm run account auth <nickname> from CLI to add additional accounts.
  • Token Storage: ~/.config/google-calendar-mcp/tokens.json (platform-specific paths)
  • Token Validation: Automatic refresh on expiry
  • Components:
    • src/auth/client.ts - OAuth2Client initialization
    • src/auth/server.ts - Auth server for OAuth flow
    • src/auth/tokenManager.ts - Token management and validation

Transport Layer

  • stdio (default): Process communication for Claude Desktop
  • HTTP: RESTful API with SSE for remote deployment
  • Configuration: src/config/TransportConfig.ts
  • Handlers: src/transports/stdio.ts and src/transports/http.ts

Testing Strategy

Unit Tests (src/tests/unit/):

  • No external dependencies (mocked)
  • Schema validation, error handling, datetime logic
  • Run with npm test (no setup required)

Integration Tests (src/tests/integration/):

Three types of integration tests, each with different requirements:

  1. Direct Integration (most commonly used):

    • File: direct-integration.test.ts
    • Tests real Google Calendar API calls
    • Setup Required:
      # 1. Set credentials path
      export GOOGLE_OAUTH_CREDENTIALS=./gcp-oauth.keys.json
      
      # 2. Set test calendar (use "primary" or a specific calendar ID)
      export TEST_CALENDAR_ID=primary
      
      # 3. Authenticate test account
      npm run dev auth:test
      
      # 4. Run tests
      npm run dev test:integration:direct
  2. LLM Integration (rarely needed):

    • Files: claude-mcp-integration.test.ts, openai-mcp-integration.test.ts
    • Tests end-to-end MCP protocol with AI models
    • Additional Setup (beyond direct integration setup):
      # For Claude tests
      export CLAUDE_API_KEY=sk-ant-...
      npm run dev test:integration:claude
      
      # For OpenAI tests
      export OPENAI_API_KEY=sk-...
      npm run dev test:integration:openai
      
      # For both
      npm run dev test:integration:all
    • ⚠️ Consumes API credits and takes 2-5 minutes

Quick Setup Summary:

# Minimal setup for development (direct integration tests only):
export GOOGLE_OAUTH_CREDENTIALS=./gcp-oauth.keys.json
export TEST_CALENDAR_ID=primary
npm run dev auth:test
npm run dev test:integration:direct

Key Services

Conflict Detection (src/services/conflict-detection/):

  • EventSimilarityChecker.ts - Detects scheduling conflicts, identifies duplicate events, and analyzes event overlap
  • ConflictDetectionService.ts - Main service coordinating conflict and duplicate checks
  • Used by create-event and update-event handlers

Calendar Registry (src/services/CalendarRegistry.ts):

  • Calendar deduplication across multiple accounts
  • Permission-based account auto-selection (read vs write)
  • Calendar name-to-ID resolution with caching

Structured Responses (src/types/structured-responses.ts):

  • TypeScript interfaces for consistent response formats
  • All handlers return structured JSON via createStructuredResponse()

Utilities:

  • src/utils/field-mask-builder.ts - Builds Google API field masks
  • src/utils/event-id-validator.ts - Validates Google Calendar event IDs
  • src/utils/response-builder.ts - Formats MCP responses
  • src/utils/datetime.ts - Timezone and datetime utilities

Important Patterns

Timezone Handling

  • Preferred Format: ISO 8601 without timezone (e.g., 2024-01-01T10:00:00)
    • Uses timeZone parameter or calendar's default timezone
  • Also Supported: ISO 8601 with timezone (e.g., 2024-01-01T10:00:00-08:00)
  • All-day Events: Date only format (e.g., 2024-01-01)
  • Helper: getCalendarTimezone() method in BaseToolHandler

Multi-Calendar Support

  • list-events accepts single calendar ID or JSON array: '["cal1", "cal2"]'
  • Batch requests handled by BatchRequestHandler.ts
  • Maximum 50 calendars per request

Recurring Events

  • Modification scopes: thisEventOnly, thisAndFollowing, all
  • Handled by RecurringEventHelpers.ts
  • Special validation in update-event schema

Error Handling

  • Use McpError from @modelcontextprotocol/sdk/types.js
  • BaseToolHandler.handleGoogleApiError() for consistent Google API error handling
  • Maps HTTP status codes to appropriate MCP error codes

Structured Responses

All tool outputs use a structured JSON response format. Types are defined in src/types/structured-responses.ts and responses are created via createStructuredResponse() from src/utils/response-builder.ts. When adding new handlers, ensure responses conform to these structured formats.

MCP Structure

MCP tools return errors as successful responses with error content, not as thrown exceptions. Integration tests must validate result.content[0].text for error messages, while unit tests of handlers directly can still catch thrown McpError exceptions before the MCP transport layer wraps them.

Code Quality

  • TypeScript: Strict mode, avoid any types
  • Formatting: Use existing patterns in handlers
  • Testing: Add unit tests for all new handlers
  • Error Messages: Clear, actionable error messages referencing Google Calendar concepts

Google Calendar API

  • Version: v3 (googleapis package)
  • Timeout: 3 seconds per API call (configured in BaseToolHandler)
  • Rate Limiting: Google Calendar API has quotas - integration tests may hit limits
  • Scope Required: https://www.googleapis.com/auth/calendar (full calendar access, superset of calendar.events)

Deployment

  • npx: npx @cocal/google-calendar-mcp (requires GOOGLE_OAUTH_CREDENTIALS env var)
  • Docker: See docs/docker.md for Docker deployment with stdio and HTTP modes
  • Claude Desktop Config: See README.md for local stdio configuration

Deployment Modes

Local Development (Claude Desktop):

  • Use stdio mode (default)
  • No server or domain required
  • Direct process communication
  • See README.md for setup

Key Differences:

  • stdio: For Claude Desktop only, local machine
  • HTTP: For testing, development, debugging (local only)