@@ -796,3 +796,147 @@ func PushFiles(getClient GetClientFn, t translations.TranslationHelperFunc) (too
796796return 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 git 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 git 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+ }