Skip to main content
Glama

Things MCP Server

by wbopan
architecture.md9.45 kB
# Architecture Overview Technical architecture and design patterns of the Things MCP Server. ## High-Level Architecture ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ AI Assistant │ │ MCP Server │ │ Things.app │ │ (Claude, etc.) │◄──►│ (This Project) │◄──►│ (macOS) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ │ Things Database │ │ (SQLite) │ └─────────────────┘ ``` ## Core Components ### MCP Server Layer **Purpose**: Model Context Protocol server that bridges AI assistants with Things.app **Technologies**: - TypeScript with ES modules - `@modelcontextprotocol/sdk` for MCP compliance - Zod for runtime schema validation - Node.js child processes for system integration **Key Files**: - `src/index.ts` - Server initialization and tool registration - `src/tools/` - Individual MCP tool implementations ### Things.app Integration Layer **Purpose**: Interfaces with Things.app using multiple interaction methods **Methods**: 1. **URL Scheme** (Primary) - For create and update operations 2. **Direct Database Access** - For read operations and verification 3. **JSON Operations** - For reliable completion/cancellation **Key Files**: - `src/utils/url-builder.ts` - URL scheme construction - `src/utils/applescript.ts` - AppleScript execution - `src/utils/json-operations.ts` - JSON-based operations ### Data Layer **Purpose**: Type-safe data structures and validation **Components**: - TypeScript type definitions (`src/types/things.ts`) - Zod schemas for runtime validation - Data transformation utilities ## Design Patterns ### Tool Registration Pattern Each MCP tool follows a standardized registration pattern: ```typescript export function registerXxxTool(server: McpServer): void { server.tool( 'tool_name', 'Description for AI assistants', zodSchema.shape, // Schema with .shape property async (params) => { // Tool implementation return { content: [{ type: "text", text: "Result" }] }; } ); } ``` **Benefits**: - Consistent API surface - Automatic parameter validation - Standardized error handling - MCP compliance guarantee ### Hybrid Operation Strategy Different operations use the most appropriate method: ```typescript // Creation: URL Scheme (fast, reliable) const url = buildThingsUrl('add', params); await openThingsUrl(url); // Reading: Direct Database (comprehensive, fast) const data = executeSqlQuery(dbPath, query); // Completion: JSON Operation (reliable state changes) await executeJsonOperation('complete', { id }); ``` **Rationale**: - URL scheme for immediate operations - Database access for complex queries - JSON operations for state changes requiring verification ### ES Module Architecture ```typescript // All imports use .js extensions for TypeScript files import { buildThingsUrl } from '../utils/url-builder.js'; import type { ThingsTask } from '../types/things.js'; // Package.json: "type": "module" // Jest: --experimental-vm-modules flag ``` **Benefits**: - Modern JavaScript standards - Better tree-shaking - Native Node.js ESM support - Future-proof architecture ## Data Flow ### Creation Flow ``` AI Request → Zod Validation → URL Building → Things.app → Response ``` 1. **AI Assistant** sends structured request 2. **MCP Server** validates with Zod schema 3. **URL Builder** constructs Things URL scheme 4. **macOS** opens URL in Things.app 5. **Things.app** creates item 6. **Response** confirms creation ### Query Flow ``` AI Request → Database Access → Data Processing → Formatted Response ``` 1. **AI Assistant** requests data summary 2. **MCP Server** locates Things database 3. **SQLite Query** extracts relevant data 4. **Data Processor** formats and filters results 5. **Response** returns Markdown or JSON ### Update Flow ``` AI Request → Auth Check → Operation Routing → Verification → Response ``` 1. **AI Assistant** requests update 2. **Auth Module** validates token 3. **Router** chooses JSON or URL operation 4. **Verification** confirms database state 5. **Response** confirms update ## Security Architecture ### Authentication Model ```typescript // Update operations require auth token export function requireAuthToken(): string { const token = process.env.THINGS_AUTH_TOKEN; if (!token) { throw new Error('THINGS_AUTH_TOKEN required for updates'); } return token; } ``` **Security Layers**: 1. **Environment Variable** storage for tokens 2. **Operation-level** authorization checks 3. **Things.app** built-in URL scheme validation 4. **No persistent** credential storage ### Data Access Security - **Read-only** database access for queries - **No credential** exposure in responses - **Local-only** operations (no network calls) - **macOS sandbox** compatibility ## Performance Architecture ### Database Access Optimization ```typescript // Efficient SQLite queries with proper indexing const query = ` SELECT uuid, title, notes, type, area, project FROM TMTask WHERE status = 0 AND trashed = 0 ORDER BY creationDate DESC `; ``` **Optimizations**: - Direct SQLite access bypasses AppleScript overhead - Filtered queries reduce data transfer - Bit-packed date handling for Things format - Minimal object creation in hot paths ### URL Scheme Efficiency ```typescript // Batch operations where possible const url = buildThingsUrl('add', { title: 'Task', 'checklist-items': items.join(','), // Single URL call tags: tags.join(',') }); ``` **Benefits**: - Single URL call per operation - Proper percent encoding for reliability - Minimal subprocess overhead - Asynchronous execution ### Memory Management - **Streaming** SQLite results for large datasets - **Compressed objects** removing empty properties - **Lazy loading** of database connections - **Garbage collection** friendly patterns ## Error Handling Architecture ### Layered Error Strategy ```typescript // Tool level: User-friendly messages catch (error) { logger.error('Failed to add task', { error: error.message }); throw new Error(`Could not create task: ${error.message}`); } // Utility level: Technical details catch (error) { logger.debug('SQLite query failed', { query, error }); return []; } ``` **Error Layers**: 1. **Tool Level** - User-facing error messages 2. **Utility Level** - Technical error details 3. **System Level** - Platform compatibility checks 4. **Validation Level** - Schema validation errors ### Platform Compatibility ```typescript // Graceful handling of non-macOS platforms if (process.platform !== 'darwin') { throw new Error('Things.app integration requires macOS'); } ``` ## Extensibility Architecture ### Plugin Pattern for New Tools ```typescript // New tool follows same pattern export function registerNewTool(server: McpServer): void { server.tool(name, description, schema.shape, handler); } // Registration in index.ts registerNewTool(server); ``` ### Schema Evolution ```typescript // Zod schemas allow safe evolution const schema = z.object({ // Existing fields title: z.string(), // New optional fields for backward compatibility priority: z.enum(['high', 'medium', 'low']).optional(), }); ``` ### Configuration Architecture ```typescript // Environment-based configuration const config = { logLevel: process.env.LOG_LEVEL || 'info', authToken: process.env.THINGS_AUTH_TOKEN, dbPath: findThingsDatabase() }; ``` ## Testing Architecture ### Test Strategy Layers 1. **Unit Tests** - Core logic and utilities 2. **Integration Tests** - Full MCP tool workflows 3. **Platform Tests** - macOS-specific functionality 4. **Verification Tests** - Database state validation ### Test Infrastructure ```typescript // Platform detection for test skipping beforeEach(() => { if (process.platform !== 'darwin') { test.skip('macOS-only functionality'); } }); // Database verification pattern await addTask(params); const verified = await verifyItemExists(taskId); expect(verified).toBe(true); ``` ## Deployment Architecture ### Distribution Model - **npm Package** for easy installation - **npx Execution** for zero-install usage - **Global Installation** for permanent setup - **Local Development** with source code ### Runtime Requirements - **Node.js** 18+ for ES modules - **macOS** for Things.app integration - **Things.app** 3.0+ for URL scheme support - **MCP Client** for AI assistant integration ## Future Architecture Considerations ### Scalability - **Connection pooling** for multiple MCP clients - **Caching layer** for frequently accessed data - **Background sync** for offline operations - **Event-driven** updates for real-time data ### Cross-Platform - **Abstract interfaces** for future platform support - **Plugin architecture** for different task managers - **Protocol abstraction** beyond Things.app URL scheme - **Universal data** formats for portability

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wbopan/things-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server