@@ -796,3 +796,147 @@ func PushFiles(getClient GetClientFn, t translations.TranslationHelperFunc) (too
796796 return mcp .NewToolResultText (string (r )), nil
797797 }
798798}
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