Skip to content

Latest commit

 

History

History
117 lines (85 loc) · 5.48 KB

File metadata and controls

117 lines (85 loc) · 5.48 KB

CLAUDE.md

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

Motion MCP Server

MCP server bridging Motion's task management API with LLMs via the Model Context Protocol. Supports both local (stdio) and remote (Cloudflare Workers) deployment.

Common Commands

# Build & Run
npm run build              # Compile TypeScript to dist/
npm run mcp                # Start MCP server (compiled)
npm run mcp:dev            # Start MCP server (ts-node, no build needed)
npm run type-check         # Type checking without emitting files

# Testing (vitest)
npm test                   # Run all unit tests
npm test -- handlers.task  # Run a single test file by name fragment
npm test -- --reporter=verbose  # Run with verbose output
npm run test:integration   # Integration tests (requires MOTION_API_KEY in .env)

# Worker (Cloudflare)
npm run worker:dev             # Local Worker at http://localhost:8787
npm run worker:deploy          # Deploy to Cloudflare
npm run worker:type-check      # Type-check Worker code (separate tsconfig)

# Verify both entry points compile
npm run build && npm run worker:type-check

# Quick startup smoke test
timeout 3s npm run mcp

Testing

Uses vitest. Unit tests in tests/**/*.spec.ts, integration tests in tests/integration/**/*.integration.test.ts.

  • Unit tests: 10s timeout, mocked services, tests/setup.ts silences console.error
  • Integration tests: 60s timeout, sequential execution (rate limits), requires MOTION_API_KEY env var
  • Handler tests mock MotionApiService and WorkspaceResolver; service returns use ListResult<T> shape ({ items, truncation })

Architecture

Entry Points

Both share all handlers, services, tools, and utilities — they differ only in transport and API key source.

  • Stdio Server (src/mcp-server.ts): Uses Server from MCP SDK. API key from MOTION_API_KEY env var.
  • Cloudflare Worker (src/worker.ts): Uses McpAgent from Cloudflare Agents SDK with Durable Objects. API key from Worker secret. Auth via secret token in URL path (/mcp/SECRET).

Handler Architecture (src/handlers/)

Command pattern: each resource type has a handler extending BaseHandler. HandlerFactory routes tool calls to handlers by tool name.

Handlers access this.motionService (API client) and this.workspaceResolver (name-to-ID resolution). Operations are dispatched via switch(operation) in handle().

Tool Management (src/tools/)

  • ToolRegistry: Manages definitions and tier mappings
  • ToolConfigurator: Validates config string, returns enabled tool set
  • ToolDefinitions: JSON Schema definitions for all tools

Configured via MOTION_MCP_TOOLS env var:

  • minimal (3): motion_tasks, motion_projects, motion_workspaces
  • essential (7): + motion_users, motion_search, motion_comments, motion_schedules
  • complete (10, default): + motion_custom_fields, motion_recurring_tasks, motion_statuses
  • custom:tool1,tool2: Exact tool selection

Core Service (src/services/motionApi.ts)

Centralized Motion API client (https://api.usemotion.com/v1). Features:

  • Workspace name-to-ID and project name resolution
  • Caching with per-resource TTLs (defined in src/utils/constants.ts as CACHE_TTL)
  • Retry with exponential backoff (GET requests only, config in RETRY_CONFIG)
  • Pagination with configurable limits (LIMITS.MAX_PAGES, LIMITS.MAX_PAGE_SIZE)
  • All logging to stderr in JSON format (MCP compliance)

Utilities (src/utils/)

  • sanitize.ts: sanitizeTextContent, sanitizeName, sanitizeDescription, sanitizeCommentContent — strip HTML/script tags, normalize whitespace. Length limits are caller's responsibility.
  • responseFormatters.ts: Consistent MCP response formatting for all resource types (tasks, projects, workspaces, comments, etc.)
  • constants.ts: LIMITS, RETRY_CONFIG, CACHE_TTL, createMinimalPayload() (strips undefined/empty strings, preserves null and []), VALID_PRIORITIES, parseFilterDate()
  • workspaceResolver.ts: Workspace name resolution with fuzzy matching
  • parameterUtils.ts: Parameter parsing (auto-scheduling, duration, labels)
  • validator.ts: Runtime input validation via AJV against tool JSON schemas
  • jsonSchemaToZod.ts: Converts JSON Schema to Zod for Worker entry point (excluded from main build)

Consolidated Tools

Tool Operations
motion_tasks create, list, get, update, delete, move, unassign
motion_projects create, list, get
motion_workspaces list, get
motion_users list, current
motion_search content
motion_comments list, create
motion_custom_fields list, create, delete, add_to_project, remove_from_project, add_to_task, remove_from_task
motion_recurring_tasks list, create, delete
motion_schedules list
motion_statuses list

Build System

  • Two tsconfigs: tsconfig.json (CommonJS, excludes worker.ts and jsonSchemaToZod.ts) and tsconfig.worker.json (ES2022, bundler resolution, Workers types)
  • Stdio server compiles to dist/; Wrangler bundles Worker separately
  • Changes to shared code (handlers, services, tools, utils) affect both entry points — always verify both builds pass

Adding a New Handler

  1. Create handler class extending BaseHandler in src/handlers/
  2. Implement handle() method with operation switch
  3. Register in HandlerFactory
  4. Add tool schema in ToolDefinitions.ts (auto-registered via allToolDefinitions)
  5. Add to appropriate tier in ToolRegistry.ts