@@ -665,12 +665,10 @@ func AddPullRequestReviewComment(getClient GetClientFn, t translations.Translati
665
665
mcp .Description ("The text of the review comment" ),
666
666
),
667
667
mcp .WithString ("commit_id" ,
668
- mcp .Required (),
669
- mcp .Description ("The SHA of the commit to comment on" ),
668
+ mcp .Description ("The SHA of the commit to comment on. Required unless in_reply_to is specified." ),
670
669
),
671
670
mcp .WithString ("path" ,
672
- mcp .Required (),
673
- mcp .Description ("The relative path to the file that necessitates a comment" ),
671
+ mcp .Description ("The relative path to the file that necessitates a comment. Required unless in_reply_to is specified." ),
674
672
),
675
673
mcp .WithString ("subject_type" ,
676
674
mcp .Description ("The level at which the comment is targeted, 'line' or 'file'" ),
@@ -691,7 +689,7 @@ func AddPullRequestReviewComment(getClient GetClientFn, t translations.Translati
691
689
mcp .Enum ("LEFT" , "RIGHT" ),
692
690
),
693
691
mcp .WithNumber ("in_reply_to" ,
694
- mcp .Description ("The ID of the review comment to reply to. When specified, all parameters other than body are ignored" ),
692
+ mcp .Description ("The ID of the review comment to reply to. When specified, only body is required and all other parameters are ignored" ),
695
693
),
696
694
),
697
695
func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
@@ -711,161 +709,103 @@ func AddPullRequestReviewComment(getClient GetClientFn, t translations.Translati
711
709
if err != nil {
712
710
return mcp .NewToolResultError (err .Error ()), nil
713
711
}
714
- commitID , err := requiredParam [string ](request , "commit_id" )
715
- if err != nil {
716
- return mcp .NewToolResultError (err .Error ()), nil
717
- }
718
- path , err := requiredParam [string ](request , "path" )
719
- if err != nil {
720
- return mcp .NewToolResultError (err .Error ()), nil
721
- }
722
712
723
- comment := & github.PullRequestComment {
724
- Body : github .Ptr (body ),
725
- CommitID : github .Ptr (commitID ),
726
- Path : github .Ptr (path ),
713
+ client , err := getClient (ctx )
714
+ if err != nil {
715
+ return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
727
716
}
728
717
729
- // Check for in_reply_to parameter which takes precedence
718
+ // Check if this is a reply to an existing comment
730
719
if replyToFloat , ok := request .Params .Arguments ["in_reply_to" ].(float64 ); ok {
731
- comment .InReplyTo = github .Ptr (int64 (replyToFloat ))
732
- } else {
733
- // Handle subject_type parameter
734
- subjectType , err := OptionalParam [string ](request , "subject_type" )
720
+ // Use the specialized method for reply comments due to inconsistency in underlying go-github library: https://github.com/google/go-github/pull/950
721
+ commentID := int64 (replyToFloat )
722
+ createdReply , resp , err := client .PullRequests .CreateCommentInReplyTo (ctx , owner , repo , pullNumber , body , commentID )
735
723
if err != nil {
736
- return mcp . NewToolResultError ( err . Error ()), nil
724
+ return nil , fmt . Errorf ( "failed to reply to pull request comment: %w" , err )
737
725
}
738
- if subjectType != "file" {
739
- // Handle line or position-based comments
740
- // No action needed if subjectType is "file"
741
- line , lineExists := request .Params .Arguments ["line" ].(float64 )
742
- startLine , startLineExists := request .Params .Arguments ["start_line" ].(float64 )
743
- side , sideExists := request .Params .Arguments ["side" ].(string )
744
- startSide , startSideExists := request .Params .Arguments ["start_side" ].(string )
745
-
746
- if subjectType != "file" && ! lineExists {
747
- return mcp .NewToolResultError ("line parameter is required unless using subject_type:file or in_reply_to" ), nil
748
- }
726
+ defer func () { _ = resp .Body .Close () }()
749
727
750
- if lineExists {
751
- comment .Line = github .Ptr (int (line ))
752
- }
753
- if sideExists {
754
- comment .Side = github .Ptr (side )
755
- }
756
- if startLineExists {
757
- comment .StartLine = github .Ptr (int (startLine ))
758
- }
759
- if startSideExists {
760
- comment .StartSide = github .Ptr (startSide )
761
- }
762
-
763
- // Validate multi-line comment parameters
764
- if startLineExists && ! lineExists {
765
- return mcp .NewToolResultError ("if start_line is provided, line must also be provided" ), nil
766
- }
767
- if startSideExists && ! sideExists {
768
- return mcp .NewToolResultError ("if start_side is provided, side must also be provided" ), nil
728
+ if resp .StatusCode != http .StatusCreated {
729
+ respBody , err := io .ReadAll (resp .Body )
730
+ if err != nil {
731
+ return nil , fmt .Errorf ("failed to read response body: %w" , err )
769
732
}
733
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to reply to pull request comment: %s" , string (respBody ))), nil
770
734
}
771
- }
772
-
773
- client , err := getClient (ctx )
774
- if err != nil {
775
- return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
776
- }
777
-
778
- createdComment , resp , err := client .PullRequests .CreateComment (ctx , owner , repo , pullNumber , comment )
779
- if err != nil {
780
- return nil , fmt .Errorf ("failed to create pull request comment: %w" , err )
781
- }
782
- defer func () { _ = resp .Body .Close () }()
783
735
784
- if resp .StatusCode != http .StatusCreated {
785
- body , err := io .ReadAll (resp .Body )
736
+ r , err := json .Marshal (createdReply )
786
737
if err != nil {
787
- return nil , fmt .Errorf ("failed to read response body : %w" , err )
738
+ return nil , fmt .Errorf ("failed to marshal response: %w" , err )
788
739
}
789
- return mcp .NewToolResultError (fmt .Sprintf ("failed to create pull request comment: %s" , string (body ))), nil
790
- }
791
740
792
- r , err := json .Marshal (createdComment )
793
- if err != nil {
794
- return nil , fmt .Errorf ("failed to marshal response: %w" , err )
741
+ return mcp .NewToolResultText (string (r )), nil
795
742
}
796
743
797
- return mcp .NewToolResultText (string (r )), nil
798
- }
799
- }
800
-
801
- // ReplyToPullRequestReviewComment creates a tool to reply to an existing review comment on a pull request.
802
- func ReplyToPullRequestReviewComment (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool ,
803
- handler server.ToolHandlerFunc ) {
804
- return mcp .NewTool ("reply_to_pull_request_review_comment" ,
805
- mcp .WithDescription (t ("TOOL_REPLY_TO_PULL_REQUEST_REVIEW_COMMENT_DESCRIPTION" , "Reply to an existing review comment on a pull request" )),
806
- mcp .WithString ("owner" ,
807
- mcp .Required (),
808
- mcp .Description ("Repository owner" ),
809
- ),
810
- mcp .WithString ("repo" ,
811
- mcp .Required (),
812
- mcp .Description ("Repository name" ),
813
- ),
814
- mcp .WithNumber ("pull_number" ,
815
- mcp .Required (),
816
- mcp .Description ("Pull request number" ),
817
- ),
818
- mcp .WithNumber ("comment_id" ,
819
- mcp .Required (),
820
- mcp .Description ("The unique identifier of the comment to reply to" ),
821
- ),
822
- mcp .WithString ("body" ,
823
- mcp .Required (),
824
- mcp .Description ("The text of the reply comment" ),
825
- ),
826
- ),
827
- func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
828
- owner , err := requiredParam [string ](request , "owner" )
829
- if err != nil {
830
- return mcp .NewToolResultError (err .Error ()), nil
831
- }
832
- repo , err := requiredParam [string ](request , "repo" )
744
+ // This is a new comment, not a reply
745
+ // Verify required parameters for a new comment
746
+ commitID , err := requiredParam [string ](request , "commit_id" )
833
747
if err != nil {
834
748
return mcp .NewToolResultError (err .Error ()), nil
835
749
}
836
- pullNumber , err := RequiredInt (request , "pull_number " )
750
+ path , err := requiredParam [ string ] (request , "path " )
837
751
if err != nil {
838
752
return mcp .NewToolResultError (err .Error ()), nil
839
753
}
840
- commentID , err := RequiredInt (request , "comment_id" )
841
- if err != nil {
842
- return mcp .NewToolResultError (err .Error ()), nil
754
+
755
+ comment := & github.PullRequestComment {
756
+ Body : github .Ptr (body ),
757
+ CommitID : github .Ptr (commitID ),
758
+ Path : github .Ptr (path ),
843
759
}
844
- body , err := requiredParam [string ](request , "body" )
760
+
761
+ subjectType , err := OptionalParam [string ](request , "subject_type" )
845
762
if err != nil {
846
763
return mcp .NewToolResultError (err .Error ()), nil
847
764
}
765
+ if subjectType != "file" {
766
+ line , lineExists := request .Params .Arguments ["line" ].(float64 )
767
+ startLine , startLineExists := request .Params .Arguments ["start_line" ].(float64 )
768
+ side , sideExists := request .Params .Arguments ["side" ].(string )
769
+ startSide , startSideExists := request .Params .Arguments ["start_side" ].(string )
848
770
849
- client , err := getClient (ctx )
850
- if err != nil {
851
- return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
771
+ if ! lineExists {
772
+ return mcp .NewToolResultError ("line parameter is required unless using subject_type:file" ), nil
773
+ }
774
+
775
+ comment .Line = github .Ptr (int (line ))
776
+ if sideExists {
777
+ comment .Side = github .Ptr (side )
778
+ }
779
+ if startLineExists {
780
+ comment .StartLine = github .Ptr (int (startLine ))
781
+ }
782
+ if startSideExists {
783
+ comment .StartSide = github .Ptr (startSide )
784
+ }
785
+
786
+ if startLineExists && ! lineExists {
787
+ return mcp .NewToolResultError ("if start_line is provided, line must also be provided" ), nil
788
+ }
789
+ if startSideExists && ! sideExists {
790
+ return mcp .NewToolResultError ("if start_side is provided, side must also be provided" ), nil
791
+ }
852
792
}
853
793
854
- createdReply , resp , err := client .PullRequests .CreateCommentInReplyTo (ctx , owner , repo , pullNumber , body , int64 ( commentID ) )
794
+ createdComment , resp , err := client .PullRequests .CreateComment (ctx , owner , repo , pullNumber , comment )
855
795
if err != nil {
856
- return nil , fmt .Errorf ("failed to reply to pull request comment: %w" , err )
796
+ return nil , fmt .Errorf ("failed to create pull request comment: %w" , err )
857
797
}
858
798
defer func () { _ = resp .Body .Close () }()
859
799
860
800
if resp .StatusCode != http .StatusCreated {
861
- body , err := io .ReadAll (resp .Body )
801
+ respBody , err := io .ReadAll (resp .Body )
862
802
if err != nil {
863
803
return nil , fmt .Errorf ("failed to read response body: %w" , err )
864
804
}
865
- return mcp .NewToolResultError (fmt .Sprintf ("failed to reply to pull request comment: %s" , string (body ))), nil
805
+ return mcp .NewToolResultError (fmt .Sprintf ("failed to create pull request comment: %s" , string (respBody ))), nil
866
806
}
867
807
868
- r , err := json .Marshal (createdReply )
808
+ r , err := json .Marshal (createdComment )
869
809
if err != nil {
870
810
return nil , fmt .Errorf ("failed to marshal response: %w" , err )
871
811
}
0 commit comments