AGENTS.md
MCP server exposing Lunatask to LLMs. Primary use case is letting the user say "remind me to call mom tomorrow" to their preferred MCP-supporting LLM, that LLM calls create_task, and the user sees the task in their desktop/mobile apps.
If you know what doc-agent is, use it to check go module APIs often. You can check context7 for details on various libraries directly if the MCP tools are available:
- lunatask.app/api (
/websites/lunatask_app_api) - Official Lunatask REST API documentation - git.secluded.site/go-lunatask (
/websites/pkg_go_dev_git_secluded_site_go-lunatask) - Go client for the Lunatask API - github.com/charmbracelet/fang (
/charmbracelet/fang) - CLI starter kit with styled help, error handling, and version management for Cobra - github.com/BurntSushi/toml (
/burntsushi/toml) - TOML parser and encoder for Go - github.com/spf13/cobra (
/websites/pkg_go_dev_github_com_spf13_cobra) - CLI framework for Go - github.com/markusmobius/go-dateparser (
/markusmobius/go-dateparser) - Natural language date parsing supporting 200+ locales - github.com/modelcontextprotocol/go-sdk (
/modelcontextprotocol/go-sdk) - Official Go SDK for the Model Context Protocol, providing APIs for constructing and using MCP clients and servers
Commands
Run in order of most to least often
task fmt lint:fix test # frequently
task # before committing
Architecture
cmd/lunatask-mcp-server.go → Config, tool registration, SSE server
tools/
├── areas/ → list_areas_and_goals tool
├── habits/ → list_habits, track_habit tools
├── tasks/ → create/update/delete_task tools
├── timestamp/ → get_timestamp tool
└── shared/ → Provider interfaces, error helpers
Data flow: SSE/STDIO request → MCP server → tool handler → lunatask client → Lunatask API
Domain model: Areas contain Goals. Habits are separate. Tasks always belong to an Area and might belong to a Goal within that area.
Adding New Functionality
New MCP tool:
- Create package in
tools/withHandlertype andNewHandler()constructor - Add handler methods (
Handle,HandleCreate, etc.) returning(*mcp.CallToolResult, error) - Put description constants in
prose.gowithin the package - Register tool with
mcpServer.AddTool()incmd/lunatask-mcp-server.go
Key Patterns
- 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 - Error returns: Handlers return
(result, nil)withIsError: true—application errors go in the result, not the Go error - Enum translation: Human strings (
"high") → API integers (1) in handlers before calling client - Provider interfaces:
tools/defines interfaces (AreaProvider, etc.) thatcmd/types implement, keeping packages decoupled
Gotchas
- Area/goal/habit IDs are static in config, not fetched—Lunatask API has no list endpoint
CreateTaskreturns(nil, nil)on HTTP 204 (task already exists)—not an error- No tests exist yet
- All files need appropriate SPDX headers based on content (
task reusechecks this)