1<!--
 2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 3
 4SPDX-License-Identifier: CC0-1.0
 5-->
 6
 7# Architecture & Design
 8
 9This document provides a comprehensive guide to the codebase architecture and core design decisions. The project uses a clean three-layer architecture that separates concerns between MCP server handling, business logic, and API client operations.
10
11## Architecture Overview
12
13This is an MCP (Model Context Protocol) server that exposes Lunatask API functionality to LLMs. The codebase uses a clean three-layer architecture:
14
15### Layer 1: Main Entry Point (`cmd/lunatask-mcp-server.go`)
16
17- Loads TOML configuration from `config.toml` (or custom path via `-c/--config`)
18- Creates and configures the MCP SSE server (Server-Sent Events transport)
19- Implements Provider interfaces (`AreaProvider`, `GoalProvider`, `HabitProvider`) that wrap config structs
20- Registers all MCP tools with their handlers
21- Validates configuration on startup (areas/goals must have names and IDs, timezone must be valid)
22
23### Layer 2: Tools Package (`tools/`)
24
25- Bridges MCP tool calls to Lunatask API client
26- Handles MCP request/response formatting
27- Performs pre-validation and argument transformation (e.g., string priorities → integers)
28- Consumes Provider interfaces to access configuration without tight coupling
29- Contains handlers for: timestamp parsing, area/goal listing, task CRUD, habit tracking
30
31### Layer 3: Lunatask Package (`lunatask/`)
32
33- Low-level HTTP client for Lunatask REST API (`https://api.lunatask.app/v1`)
34- Defines request/response types with JSON tags
35- Uses `go-playground/validator` for request validation
36- Contains API methods for tasks (`CreateTask`, `UpdateTask`, `DeleteTask`) and habits (`TrackHabitActivity`)
37
38## Key Design Patterns
39
40**Provider Interfaces**: The tools package defines `AreaProvider`, `GoalProvider`, and `HabitProvider` interfaces. The main package's config structs implement these, allowing tools to access config data without importing main or knowing config structure details.
41
42**String-to-Integer Mapping**: MCP tools accept human-readable strings that get translated to API integers:
43- Priority: `"lowest"`=-2, `"low"`=-1, `"neutral"`=0, `"high"`=1, `"highest"`=2
44- Eisenhower matrix: `"uncategorised"`=0, `"both urgent and important"`=1, `"urgent, but not important"`=2, `"important, but not urgent"`=3, `"neither urgent nor important"`=4
45
46**Natural Language Date Parsing**: Uses `github.com/ijt/go-anytime` with timezone support. The `get_timestamp` tool parses expressions like "tomorrow at 3pm" into RFC3339 timestamps. Timezone is configured in `config.toml` using IANA/Olson format (e.g., `America/New_York`).
47
48## Validation Happens at Two Levels
49
501. **Tools layer**: Type checking, area/goal relationship validation, string-to-int translation
512. **Lunatask layer**: go-playground/validator tags enforce API constraints (UUID format, string lengths, numeric ranges, enum values)
52
53This prevents invalid requests from reaching the API and provides better error messages.