package comment import ( "bytes" "context" "io" "log/slog" "github.com/eat-pray-ai/yutu/cmd" "github.com/eat-pray-ai/yutu/pkg/comment" "github.com/eat-pray-ai/yutu/pkg/utils" "github.com/mark3labs/mcp-go/mcp" "github.com/spf13/cobra" ) const ( insertShort = "Insert a comment" insertLong = "Insert a comment to a video" insertPidUsage = "ID of the parent comment" ) func init() { cmd.MCP.AddTool(insertTool, insertHandler) commentCmd.AddCommand(insertCmd) insertCmd.Flags().StringVarP( &authorChannelId, "authorChannelId", "a", "", acidUsage, ) insertCmd.Flags().StringVarP( &channelId, "channelId", "c", "", cidUsage, ) insertCmd.Flags().BoolVarP(canRate, "canRate", "R", false, crUsage) insertCmd.Flags().StringVarP( &parentId, "parentId", "P", "", insertPidUsage, ) insertCmd.Flags().StringVarP( &textOriginal, "textOriginal", "t", "", toUsage, ) insertCmd.Flags().StringVarP(&videoId, "videoId", "v", "", vidUsage) insertCmd.Flags().StringVarP(&output, "output", "o", "", cmd.SilentUsage) insertCmd.Flags().StringVarP(&jpath, "jsonPath", "j", "", cmd.JPUsage) _ = insertCmd.MarkFlagRequired("authorChannelId") _ = insertCmd.MarkFlagRequired("channelId") _ = insertCmd.MarkFlagRequired("parentId") _ = insertCmd.MarkFlagRequired("textOriginal") _ = insertCmd.MarkFlagRequired("videoId") } var insertCmd = &cobra.Command{ Use: "insert", Short: insertShort, Long: insertLong, Run: func(cmd *cobra.Command, args []string) { err := insert(cmd.OutOrStdout()) if err != nil { _ = cmd.Help() cmd.PrintErrf("Error: %v\n", err) } }, } var insertTool = mcp.NewTool( "comment-insert", mcp.WithTitleAnnotation(insertShort), mcp.WithDescription(insertLong), mcp.WithDestructiveHintAnnotation(false), mcp.WithOpenWorldHintAnnotation(true), mcp.WithReadOnlyHintAnnotation(false), mcp.WithString( "authorChannelId", mcp.DefaultString(""), mcp.Description(acidUsage), mcp.Required(), ), mcp.WithString( "channelId", mcp.DefaultString(""), mcp.Description(cidUsage), mcp.Required(), ), mcp.WithString( "canRate", mcp.Enum("true", "false", ""), mcp.DefaultString(""), mcp.Description(crUsage), mcp.Required(), ), mcp.WithString( "parentId", mcp.DefaultString(""), mcp.Description(insertPidUsage), mcp.Required(), ), mcp.WithString( "textOriginal", mcp.DefaultString(""), mcp.Description(toUsage), mcp.Required(), ), mcp.WithString( "videoId", mcp.DefaultString(""), mcp.Description(vidUsage), mcp.Required(), ), mcp.WithString( "output", mcp.Enum("json", "yaml", "silent", ""), mcp.DefaultString("yaml"), mcp.Description(cmd.SilentUsage), mcp.Required(), ), mcp.WithString( "jsonpath", mcp.DefaultString(""), mcp.Description(cmd.JPUsage), mcp.Required(), ), ) func insertHandler( ctx context.Context, request mcp.CallToolRequest, ) (*mcp.CallToolResult, error) { args := request.GetArguments() authorChannelId, _ = args["authorChannelId"].(string) channelId, _ = args["channelId"].(string) canRateRaw, _ := args["canRate"].(string) canRate = utils.BoolPtr(canRateRaw) parentId, _ = args["parentId"].(string) textOriginal, _ = args["textOriginal"].(string) videoId, _ = args["videoId"].(string) output, _ = args["output"].(string) jpath, _ = args["jsonpath"].(string) slog.InfoContext(ctx, "comment insert started") var writer bytes.Buffer err := insert(&writer) if err != nil { slog.ErrorContext( ctx, "comment insert failed", "error", err, "args", args, ) return mcp.NewToolResultError(err.Error()), err } slog.InfoContext( ctx, "comment insert completed successfully", "resultSize", writer.Len(), ) return mcp.NewToolResultText(writer.String()), nil } func insert(writer io.Writer) error { c := comment.NewComment( comment.WithAuthorChannelId(authorChannelId), comment.WithChannelId(channelId), comment.WithCanRate(canRate), comment.WithParentId(parentId), comment.WithTextOriginal(textOriginal), comment.WithVideoId(videoId), comment.WithService(nil), ) return c.Insert(output, jpath, writer) }