|
1 | 1 | package activity
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "bytes" |
| 5 | + "context" |
| 6 | + "github.com/eat-pray-ai/yutu/cmd" |
4 | 7 | "github.com/eat-pray-ai/yutu/pkg/activity"
|
| 8 | + "github.com/eat-pray-ai/yutu/pkg/utils" |
| 9 | + "github.com/mark3labs/mcp-go/mcp" |
5 | 10 | "github.com/spf13/cobra"
|
| 11 | + "io" |
6 | 12 | )
|
7 | 13 |
|
| 14 | +const ( |
| 15 | + shortDesc = "List YouTube activities" |
| 16 | + longDesc = "List YouTube activities, such as likes, favorites, uploads, etc." |
| 17 | + channelIdDesc = "ID of the channel" |
| 18 | + homeDesc = "true or false" |
| 19 | + maxResultsDesc = "The maximum number of items that should be returned" |
| 20 | + mineDesc = "true or false" |
| 21 | + publishedAfterDesc = "Filter on activities published after this date" |
| 22 | + publishedBeforeDesc = "Filter on activities published before this date" |
| 23 | + regionCodeDesc = "" |
| 24 | + partsDesc = "Comma separated parts" |
| 25 | + outputDesc = "json or yaml" |
| 26 | +) |
| 27 | + |
| 28 | +var listTool = mcp.NewTool( |
| 29 | + "activity.list", |
| 30 | + mcp.WithDescription(longDesc), |
| 31 | + mcp.WithString( |
| 32 | + "channelId", mcp.DefaultString(""), mcp.Description(channelIdDesc), |
| 33 | + ), |
| 34 | + mcp.WithString( |
| 35 | + "home", mcp.Enum("true", "false", ""), |
| 36 | + mcp.DefaultString(""), mcp.Description(homeDesc), |
| 37 | + ), |
| 38 | + mcp.WithNumber( |
| 39 | + "maxResults", mcp.DefaultNumber(5), mcp.Description(maxResultsDesc), |
| 40 | + ), |
| 41 | + mcp.WithString( |
| 42 | + "mine", mcp.Enum("true", "false", ""), |
| 43 | + mcp.DefaultString("true"), mcp.Description(mineDesc), |
| 44 | + ), |
| 45 | + mcp.WithString( |
| 46 | + "publishedAfter", mcp.DefaultString(""), mcp.Description(publishedAfterDesc), |
| 47 | + ), |
| 48 | + mcp.WithString( |
| 49 | + "publishedBefore", mcp.DefaultString(""), |
| 50 | + mcp.Description(publishedBeforeDesc), |
| 51 | + ), |
| 52 | + mcp.WithString( |
| 53 | + "regionCode", mcp.DefaultString(""), mcp.Description(regionCodeDesc), |
| 54 | + ), |
| 55 | + mcp.WithArray( |
| 56 | + "parts", mcp.DefaultArray([]string{"id", "snippet", "contentDetails"}), |
| 57 | + mcp.Description(partsDesc), |
| 58 | + ), |
| 59 | + mcp.WithString("output", mcp.DefaultString(""), mcp.Description(outputDesc)), |
| 60 | +) |
| 61 | + |
| 62 | +func run(writer io.Writer) error { |
| 63 | + a := activity.NewActivity( |
| 64 | + activity.WithChannelId(channelId), |
| 65 | + activity.WithHome(home), |
| 66 | + activity.WithMaxResults(maxResults), |
| 67 | + activity.WithMine(mine), |
| 68 | + activity.WithPublishedAfter(publishedAfter), |
| 69 | + activity.WithPublishedBefore(publishedBefore), |
| 70 | + activity.WithRegionCode(regionCode), |
| 71 | + activity.WithService(nil), |
| 72 | + ) |
| 73 | + |
| 74 | + return a.List(parts, output, writer) |
| 75 | +} |
| 76 | + |
8 | 77 | var listCmd = &cobra.Command{
|
9 | 78 | Use: "list",
|
10 |
| - Short: "List YouTube activities", |
11 |
| - Long: "List YouTube activities, such as likes, favorites, uploads, etc.", |
| 79 | + Short: shortDesc, |
| 80 | + Long: longDesc, |
| 81 | + PreRun: func(cmd *cobra.Command, args []string) { |
| 82 | + if !cmd.Flags().Lookup("home").Changed { |
| 83 | + home = nil |
| 84 | + } |
| 85 | + if !cmd.Flags().Lookup("mine").Changed { |
| 86 | + mine = nil |
| 87 | + } |
| 88 | + }, |
12 | 89 | Run: func(cmd *cobra.Command, args []string) {
|
13 |
| - a := activity.NewActivity( |
14 |
| - activity.WithChannelId(channelId), |
15 |
| - activity.WithHome(home, true), |
16 |
| - activity.WithMaxResults(maxResults), |
17 |
| - activity.WithMine(mine, true), |
18 |
| - activity.WithPublishedAfter(publishedAfter), |
19 |
| - activity.WithPublishedBefore(publishedBefore), |
20 |
| - activity.WithRegionCode(regionCode), |
21 |
| - activity.WithService(nil), |
22 |
| - ) |
23 |
| - a.List(parts, output) |
| 90 | + err := run(cmd.OutOrStdout()) |
| 91 | + if err != nil { |
| 92 | + _ = cmd.Help() |
| 93 | + cmd.PrintErrf("Error: %v\n", err) |
| 94 | + } |
24 | 95 | },
|
25 | 96 | }
|
26 | 97 |
|
27 | 98 | func init() {
|
| 99 | + cmd.MCP.AddTool(listTool, listHandler) |
28 | 100 | activityCmd.AddCommand(listCmd)
|
29 | 101 | listCmd.Flags().StringVarP(
|
30 |
| - &channelId, "channelId", "c", "", "ID of the channel", |
| 102 | + &channelId, "channelId", "c", "", channelIdDesc, |
31 | 103 | )
|
32 |
| - listCmd.Flags().BoolVarP(&home, "home", "H", true, "true or false") |
| 104 | + listCmd.Flags().BoolVarP(home, "home", "H", true, homeDesc) |
33 | 105 | listCmd.Flags().Int64VarP(
|
34 |
| - &maxResults, "maxResults", "n", 5, "The maximum number of items that should be returned", |
| 106 | + &maxResults, "maxResults", "n", 5, maxResultsDesc, |
35 | 107 | )
|
36 |
| - listCmd.Flags().BoolVarP(&mine, "mine", "M", true, "true or false") |
| 108 | + listCmd.Flags().BoolVarP(mine, "mine", "M", true, mineDesc) |
37 | 109 | listCmd.Flags().StringVarP(
|
38 |
| - &publishedAfter, "publishedAfter", "a", "", |
39 |
| - "Filter on activities published after this date", |
| 110 | + &publishedAfter, "publishedAfter", "a", "", publishedAfterDesc, |
40 | 111 | )
|
41 | 112 | listCmd.Flags().StringVarP(
|
42 |
| - &publishedBefore, "publishedBefore", "b", "", |
43 |
| - "Filter on activities published before this date", |
| 113 | + &publishedBefore, "publishedBefore", "b", "", publishedBeforeDesc, |
44 | 114 | )
|
45 |
| - listCmd.Flags().StringVarP(®ionCode, "regionCode", "r", "", "") |
| 115 | + listCmd.Flags().StringVarP(®ionCode, "regionCode", "r", "", regionCodeDesc) |
46 | 116 |
|
47 | 117 | listCmd.Flags().StringArrayVarP(
|
48 |
| - &parts, "parts", "p", []string{"id", "snippet", "contentDetails"}, |
49 |
| - "Comma separated parts", |
50 |
| - ) |
51 |
| - listCmd.Flags().StringVarP( |
52 |
| - &output, "output", "o", "", "json or yaml", |
| 118 | + &parts, "parts", "p", []string{"id", "snippet", "contentDetails"}, partsDesc, |
53 | 119 | )
|
| 120 | + listCmd.Flags().StringVarP(&output, "output", "o", "", outputDesc) |
| 121 | +} |
| 122 | + |
| 123 | +func listHandler(ctx context.Context, request mcp.CallToolRequest) ( |
| 124 | + *mcp.CallToolResult, error, |
| 125 | +) { |
| 126 | + args := request.GetArguments() |
| 127 | + channelId = args["channelId"].(string) |
| 128 | + home = utils.BoolPtr(args["home"].(string)) |
| 129 | + maxResults = int64(args["maxResults"].(float64)) |
| 130 | + mine = utils.BoolPtr(args["mine"].(string)) |
| 131 | + publishedAfter = args["publishedAfter"].(string) |
| 132 | + publishedBefore = args["publishedBefore"].(string) |
| 133 | + regionCode = args["regionCode"].(string) |
| 134 | + parts = make([]string, len(args["parts"].([]interface{}))) |
| 135 | + for i, part := range args["parts"].([]interface{}) { |
| 136 | + parts[i] = part.(string) |
| 137 | + } |
| 138 | + output = args["output"].(string) |
| 139 | + |
| 140 | + var writer bytes.Buffer |
| 141 | + err := run(&writer) |
| 142 | + if err != nil { |
| 143 | + return mcp.NewToolResultError(err.Error()), err |
| 144 | + } |
| 145 | + return mcp.NewToolResultText(writer.String()), nil |
54 | 146 | }
|
0 commit comments