refactor: Move general tools code from handlers.go to tools.go

Amolith created

Change summary

tools/handlers.go | 99 -------------------------------------------------
tools/tools.go    | 43 +++++++++++++++++++++
2 files changed, 43 insertions(+), 99 deletions(-)

Detailed changes

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) {

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
+}