From 3c552c713b79cd09025a46c8c94a9ba03258a4a1 Mon Sep 17 00:00:00 2001 From: Amolith Date: Sun, 18 May 2025 11:13:26 -0600 Subject: [PATCH] refactor: Move general tools code from handlers.go to tools.go --- tools/handlers.go | 99 ----------------------------------------------- tools/tools.go | 43 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 99 deletions(-) diff --git a/tools/handlers.go b/tools/handlers.go index 75fc8d58e788446572cd1f688e2a12b76969c32d..e295db3b62416b52509273ff964033ebde7767d8 100644 --- a/tools/handlers.go +++ b/tools/handlers.go @@ -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) { diff --git a/tools/tools.go b/tools/tools.go index 00dc914af6f8ce2e7df8a0c08dcebada985ac68b..0d3159a4bcece2862b5af7ac445afdeeb03a67b0 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -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 +}