handler.go

 1// SPDX-FileCopyrightText: Amolith <amolith@secluded.site>
 2//
 3// SPDX-License-Identifier: AGPL-3.0-or-later
 4
 5// Package timestamp provides the get_timestamp MCP tool for parsing natural
 6// language dates into formatted timestamps.
 7package timestamp
 8
 9import (
10	"context"
11	"fmt"
12	"time"
13
14	"github.com/ijt/go-anytime"
15	"github.com/mark3labs/mcp-go/mcp"
16
17	"git.sr.ht/~amolith/lunatask-mcp-server/tools/shared"
18)
19
20// Handler handles timestamp-related MCP tool calls.
21type Handler struct {
22	timezone string
23}
24
25// NewHandler creates a new timestamp Handler.
26func NewHandler(timezone string) *Handler {
27	return &Handler{timezone: timezone}
28}
29
30// Handle handles the get_timestamp tool call.
31//
32//nolint:wrapcheck // ReportError returns nil for error
33func (h *Handler) Handle(
34	_ context.Context,
35	request mcp.CallToolRequest,
36) (*mcp.CallToolResult, error) {
37	natLangDate, ok := request.Params.Arguments["natural_language_date"].(string)
38	if !ok || natLangDate == "" {
39		return shared.ReportError(
40			"Missing or invalid required argument: natural_language_date",
41		)
42	}
43
44	loc, err := shared.LoadLocation(h.timezone)
45	if err != nil {
46		return shared.ReportError(err.Error())
47	}
48
49	parsedTime, err := anytime.Parse(natLangDate, time.Now().In(loc))
50	if err != nil {
51		return shared.ReportError(
52			fmt.Sprintf("Could not parse natural language date: %v", err),
53		)
54	}
55
56	return &mcp.CallToolResult{
57		Content: []mcp.Content{
58			mcp.TextContent{
59				Type: "text",
60				Text: parsedTime.Format(time.RFC3339),
61			},
62		},
63	}, nil
64}