@@ -796,3 +796,147 @@ func PushFiles(getClient GetClientFn, t translations.TranslationHelperFunc) (too
796
796
return mcp .NewToolResultText (string (r )), nil
797
797
}
798
798
}
799
+
800
+ // ListTags creates a tool to list tags in a GitHub repository.
801
+ func ListTags (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
802
+ return mcp .NewTool ("list_tags" ,
803
+ mcp .WithDescription (t ("TOOL_LIST_TAGS_DESCRIPTION" , "List tags in a GitHub repository" )),
804
+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
805
+ Title : t ("TOOL_LIST_TAGS_USER_TITLE" , "List tags" ),
806
+ ReadOnlyHint : true ,
807
+ }),
808
+ mcp .WithString ("owner" ,
809
+ mcp .Required (),
810
+ mcp .Description ("Repository owner" ),
811
+ ),
812
+ mcp .WithString ("repo" ,
813
+ mcp .Required (),
814
+ mcp .Description ("Repository name" ),
815
+ ),
816
+ WithPagination (),
817
+ ),
818
+ func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
819
+ owner , err := requiredParam [string ](request , "owner" )
820
+ if err != nil {
821
+ return mcp .NewToolResultError (err .Error ()), nil
822
+ }
823
+ repo , err := requiredParam [string ](request , "repo" )
824
+ if err != nil {
825
+ return mcp .NewToolResultError (err .Error ()), nil
826
+ }
827
+ pagination , err := OptionalPaginationParams (request )
828
+ if err != nil {
829
+ return mcp .NewToolResultError (err .Error ()), nil
830
+ }
831
+
832
+ opts := & github.ListOptions {
833
+ Page : pagination .page ,
834
+ PerPage : pagination .perPage ,
835
+ }
836
+
837
+ client , err := getClient (ctx )
838
+ if err != nil {
839
+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
840
+ }
841
+
842
+ tags , resp , err := client .Repositories .ListTags (ctx , owner , repo , opts )
843
+ if err != nil {
844
+ return nil , fmt .Errorf ("failed to list tags: %w" , err )
845
+ }
846
+ defer func () { _ = resp .Body .Close () }()
847
+
848
+ if resp .StatusCode != http .StatusOK {
849
+ body , err := io .ReadAll (resp .Body )
850
+ if err != nil {
851
+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
852
+ }
853
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to list tags: %s" , string (body ))), nil
854
+ }
855
+
856
+ r , err := json .Marshal (tags )
857
+ if err != nil {
858
+ return nil , fmt .Errorf ("failed to marshal response: %w" , err )
859
+ }
860
+
861
+ return mcp .NewToolResultText (string (r )), nil
862
+ }
863
+ }
864
+
865
+ // GetTag creates a tool to get details about a specific tag in a GitHub repository.
866
+ func GetTag (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
867
+ return mcp .NewTool ("get_tag" ,
868
+ mcp .WithDescription (t ("TOOL_GET_TAG_DESCRIPTION" , "Get details about a specific tag in a GitHub repository" )),
869
+ mcp .WithToolAnnotation (mcp.ToolAnnotation {
870
+ Title : t ("TOOL_GET_TAG_USER_TITLE" , "Get tag details" ),
871
+ ReadOnlyHint : true ,
872
+ }),
873
+ mcp .WithString ("owner" ,
874
+ mcp .Required (),
875
+ mcp .Description ("Repository owner" ),
876
+ ),
877
+ mcp .WithString ("repo" ,
878
+ mcp .Required (),
879
+ mcp .Description ("Repository name" ),
880
+ ),
881
+ mcp .WithString ("tag" ,
882
+ mcp .Required (),
883
+ mcp .Description ("Tag name" ),
884
+ ),
885
+ ),
886
+ func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
887
+ owner , err := requiredParam [string ](request , "owner" )
888
+ if err != nil {
889
+ return mcp .NewToolResultError (err .Error ()), nil
890
+ }
891
+ repo , err := requiredParam [string ](request , "repo" )
892
+ if err != nil {
893
+ return mcp .NewToolResultError (err .Error ()), nil
894
+ }
895
+ tag , err := requiredParam [string ](request , "tag" )
896
+ if err != nil {
897
+ return mcp .NewToolResultError (err .Error ()), nil
898
+ }
899
+
900
+ client , err := getClient (ctx )
901
+ if err != nil {
902
+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
903
+ }
904
+
905
+ // First get the tag reference
906
+ ref , resp , err := client .Git .GetRef (ctx , owner , repo , "refs/tags/" + tag )
907
+ if err != nil {
908
+ return nil , fmt .Errorf ("failed to get tag reference: %w" , err )
909
+ }
910
+ defer func () { _ = resp .Body .Close () }()
911
+
912
+ if resp .StatusCode != http .StatusOK {
913
+ body , err := io .ReadAll (resp .Body )
914
+ if err != nil {
915
+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
916
+ }
917
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to get tag reference: %s" , string (body ))), nil
918
+ }
919
+
920
+ // Then get the tag object
921
+ tagObj , resp , err := client .Git .GetTag (ctx , owner , repo , * ref .Object .SHA )
922
+ if err != nil {
923
+ return nil , fmt .Errorf ("failed to get tag object: %w" , err )
924
+ }
925
+ defer func () { _ = resp .Body .Close () }()
926
+
927
+ if resp .StatusCode != http .StatusOK {
928
+ body , err := io .ReadAll (resp .Body )
929
+ if err != nil {
930
+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
931
+ }
932
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to get tag object: %s" , string (body ))), nil
933
+ }
934
+
935
+ r , err := json .Marshal (tagObj )
936
+ if err != nil {
937
+ return nil , fmt .Errorf ("failed to marshal response: %w" , err )
938
+ }
939
+
940
+ return mcp .NewToolResultText (string (r )), nil
941
+ }
942
+ }
0 commit comments