AGENTS.md

 1<!--
 2SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 3
 4SPDX-License-Identifier: CC0-1.0
 5-->
 6
 7# AGENTS.md
 8
 9MCP server exposing Lunatask (task/habit tracker) to LLMs via SSE. Primary use case: Home Assistant voice assistant says "remind me to call mom tomorrow" → HA's LLM calls this server's `create_task` tool → task appears in Lunatask.
10
11All of Lunatask's API docs are local (uncommitted), so feel free to read them _liberally_ while working on the client. The index, telling you which files to read for which topics, is in lunatask/docs/index.md
12
13## Commands
14
15```sh
16just          # Run all checks (fmt, lint, staticcheck, test, vuln, reuse)
17just build    # Build with version info
18just run      # Build and run
19```
20
21## Architecture
22
23```
24cmd/lunatask-mcp-server.go  → Config, tool registration, SSE server
25tools/                      → MCP tool handlers
26```
27
28**Data flow**: SSE request → MCP server → tool handler → lunatask client → Lunatask API
29
30**Domain model**: Areas contain Goals. Habits are separate. Tasks belong to an Area and optionally a Goal.
31
32## Adding New Functionality
33
34**New MCP tool**: 
351. Add handler method to `tools/` (on `Handlers` struct)
362. Register tool with `mcpServer.AddTool()` in `cmd/lunatask-mcp-server.go`
37
38**New API endpoint**: Add method to `lunatask/Client` with request/response types
39
40## Key Patterns
41
42- **Tool descriptions are prompts**: The verbose `mcp.WithDescription()` strings guide the *calling* LLM's behavior—they explain workflows, valid values, and when to use each tool
43- **Error returns**: Handlers return `(result, nil)` with `IsError: true`—application errors go in the result, not the Go error
44- **Enum translation**: Human strings (`"high"`) → API integers (`1`) in handlers before calling client
45- **Provider interfaces**: `tools/` defines interfaces (`AreaProvider`, etc.) that `cmd/` types implement, keeping packages decoupled
46
47## Gotchas
48
49- Area/goal/habit IDs are static in config, not fetched—Lunatask API has no list endpoint
50- `CreateTask` returns `(nil, nil)` on HTTP 204 (task already exists)—not an error
51- `update_task` MCP tool requires `name` even for partial updates
52- No tests exist yet
53- All files need SPDX headers (`just reuse` checks this)