@@ -17,105 +17,6 @@ import (
"git.sr.ht/~amolith/lunatask-mcp-server/lunatask"
)
-// AreaProvider defines the interface for accessing area data.
-type AreaProvider interface {
- GetName() string
- GetID() string
- GetGoals() []GoalProvider
-}
-
-// GoalProvider defines the interface for accessing goal data.
-type GoalProvider interface {
- GetName() string
- GetID() string
-}
-
-// HabitProvider defines the interface for accessing habit data.
-type HabitProvider interface {
- GetName() string
- GetID() string
-}
-
-// HandlerConfig holds the necessary configuration for tool handlers.
-type HandlerConfig struct {
- AccessToken string
- Timezone string
- Areas []AreaProvider
- Habits []HabitProvider
-}
-
-// Handlers provides methods for handling MCP tool calls.
-type Handlers struct {
- config HandlerConfig
-}
-
-// NewHandlers creates a new Handlers instance.
-func NewHandlers(config HandlerConfig) *Handlers {
- return &Handlers{config: config}
-}
-
-// reportMCPError creates an MCP error result.
-func reportMCPError(msg string) (*mcp.CallToolResult, error) {
- return &mcp.CallToolResult{
- IsError: true,
- Content: []mcp.Content{mcp.TextContent{Type: "text", Text: msg}},
- }, nil
-}
-
-// LoadLocation loads a timezone location string, returning a *time.Location or error
-func LoadLocation(timezone string) (*time.Location, error) {
- if timezone == "" {
- return nil, fmt.Errorf("timezone is not configured; please set the 'timezone' value in your config file (e.g. 'UTC' or 'America/New_York')")
- }
- loc, err := time.LoadLocation(timezone)
- if err != nil {
- return nil, fmt.Errorf("could not load timezone '%s': %v", timezone, err)
- }
- return loc, nil
-}
-
-// HandleGetTimestamp handles the get_timestamp tool call.
-func (h *Handlers) HandleGetTimestamp(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
- natLangDate, ok := request.Params.Arguments["natural_language_date"].(string)
- if !ok || natLangDate == "" {
- return reportMCPError("Missing or invalid required argument: natural_language_date")
- }
- loc, err := LoadLocation(h.config.Timezone)
- if err != nil {
- return reportMCPError(err.Error())
- }
- parsedTime, err := anytime.Parse(natLangDate, time.Now().In(loc))
- if err != nil {
- return reportMCPError(fmt.Sprintf("Could not parse natural language date: %v", err))
- }
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: parsedTime.Format(time.RFC3339),
- },
- },
- }, nil
-}
-
-// HandleListAreasAndGoals handles the list_areas_and_goals tool call.
-func (h *Handlers) HandleListAreasAndGoals(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
- var b strings.Builder
- for _, area := range h.config.Areas {
- fmt.Fprintf(&b, "- %s: %s\n", area.GetName(), area.GetID())
- for _, goal := range area.GetGoals() {
- fmt.Fprintf(&b, " - %s: %s\n", goal.GetName(), goal.GetID())
- }
- }
- return &mcp.CallToolResult{
- Content: []mcp.Content{
- mcp.TextContent{
- Type: "text",
- Text: b.String(),
- },
- },
- }, nil
-}
// HandleCreateTask handles the create_task tool call.
func (h *Handlers) HandleCreateTask(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -14,6 +14,7 @@ import (
"github.com/mark3labs/mcp-go/mcp"
)
+
// AreaProvider defines the interface for accessing area data.
type AreaProvider interface {
GetName() string
@@ -113,3 +114,45 @@ func (h *Handlers) HandleListAreasAndGoals(ctx context.Context, request mcp.Call
},
}, nil
}
+// HandleGetTimestamp handles the get_timestamp tool call.
+func (h *Handlers) HandleGetTimestamp(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
+ natLangDate, ok := request.Params.Arguments["natural_language_date"].(string)
+ if !ok || natLangDate == "" {
+ return reportMCPError("Missing or invalid required argument: natural_language_date")
+ }
+ loc, err := LoadLocation(h.config.Timezone)
+ if err != nil {
+ return reportMCPError(err.Error())
+ }
+ parsedTime, err := anytime.Parse(natLangDate, time.Now().In(loc))
+ if err != nil {
+ return reportMCPError(fmt.Sprintf("Could not parse natural language date: %v", err))
+ }
+ return &mcp.CallToolResult{
+ Content: []mcp.Content{
+ mcp.TextContent{
+ Type: "text",
+ Text: parsedTime.Format(time.RFC3339),
+ },
+ },
+ }, nil
+}
+
+// HandleListAreasAndGoals handles the list_areas_and_goals tool call.
+func (h *Handlers) HandleListAreasAndGoals(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
+ var b strings.Builder
+ for _, area := range h.config.Areas {
+ fmt.Fprintf(&b, "- %s: %s\n", area.GetName(), area.GetID())
+ for _, goal := range area.GetGoals() {
+ fmt.Fprintf(&b, " - %s: %s\n", goal.GetName(), goal.GetID())
+ }
+ }
+ return &mcp.CallToolResult{
+ Content: []mcp.Content{
+ mcp.TextContent{
+ Type: "text",
+ Text: b.String(),
+ },
+ },
+ }, nil
+}